When to use Spring events vs Kafka/RabbitMQ. (In-process… — Cracked Java
// Spring Framework & Spring Boot · Spring Events
SeniorSystem Design

When to use Spring events vs Kafka/RabbitMQ. (In-process vs cross-process.)

The line is process boundary and durability: Spring events live inside one JVM and vanish on crash; Kafka and RabbitMQ cross processes and survive crashes. Picking the wrong one is a common design mistake in interviews, so be precise about what each guarantees.

What Spring events are

In-process, in-memory, synchronous-by-default method dispatch. The event object is a Java reference passed between beans in the same ApplicationContext. That means:

  • Single process only — a listener in another service or another instance never sees it.
  • Not durable — if the JVM crashes between publish and handling, the event is lost. There's no log, no queue, no replay.
  • No delivery guarantee, no retry, no ordering across restarts — it's a method call, so "delivery" is just "the method ran."

The upside is exactly the cost of a broker, removed: no serialization, no network, no extra infrastructure, no operational surface. Latency is nanoseconds. For decoupling collaborators within one deployable, that's perfect.

What a broker adds

Kafka / RabbitMQ are out-of-process systems that persist messages to disk before acknowledging:

  • Cross-process / cross-service — different applications, different instances, different languages consume the same stream.
  • Durable & replayable — Kafka retains a log you can re-read; RabbitMQ persists queues. A consumer that was down catches up.
  • At-least-once delivery, retries, dead-letter queues, backpressure — the reliability machinery that makes asynchronous integration safe.

The cost: serialization, a network hop, a system to operate and monitor, and the distributed-systems concerns (idempotency, ordering, exactly-once semantics) that come with all of it.

How to decide

Spring eventsKafka / RabbitMQ
Boundarywithin one JVMacross processes/services
Durabilitynone (lost on crash)persisted, replayable
Coupling removedbetween beansbetween deployables
Cost~zeroinfra + ops + distributed concerns

Rule of thumb: decoupling code in the same app → Spring events. Decoupling services, or needing durability/replay → a broker. A frequent mistake is using async Spring events as a "queue" for work that must not be lost — a crash drops it silently. If losing the event is unacceptable, you need persistence, which means a broker (or Spring Modulith's persistent event registry as a stepping stone).

Mark your status