🛑⚡ WHEN NOT TO USE EVENT-DRIVEN ARCHITECTURE (EDA) inspired by Java Champion Victor Rentea
🛑⚡ WHEN NOT TO USE EVENT-DRIVEN ARCHITECTURE (EDA) inspired by Java Champion Victor Rentea
TL;DR ☕
Event-Driven Architecture (EDA) is one of the most powerful architectural styles for scalable distributed systems... but it is NOT a universal solution.
Many teams adopt Kafka, RabbitMQ, Pulsar or cloud messaging because they are trendy, only to discover months later that they have added complexity without solving any real problem.
The best architects know when to use EDA.
The great architects also know when NOT to use it.

🔸 WHY THIS ARTICLE?
Modern software architecture often swings between extremes.
Yesterday everything was a monolith.
Today everything becomes asynchronous.
Tomorrow... we'll probably rediscover moderation. 😄
EDA is amazing for reacting to events.
It is often terrible for coordinating workflows.
A useful rule of thumb is:
Coordination → Think twice.
Let's see the most common situations where EDA may actually be the wrong architectural choice.

🔸 1. SIMPLE CRUD APPLICATIONS
If your application is:
▪️ one small team
▪️ one deployable
▪️ one database
▪️ a few hundred users
...adding Kafka or another event broker usually creates more problems than value.
Instead of:
REST
↓
Database
you suddenly have:
REST
↓
Producer
↓
Broker
↓
Consumer
↓
Database
Congratulations 🎉
You just added:
✅ brokers
✅ retries
✅ dead-letter queues
✅ replay
✅ monitoring
✅ serialization
✅ versioning
...to update one row.
Example: Direct CRUD is enough
@PostMapping("/customers")
public Customer create(@RequestBody Customer c) {
return repository.save(c);
}
One request, one transaction, one database update. For small CRUD applications this is easier to maintain than introducing asynchronous messaging and distributed infrastructure.
The complexity budget of EDA should be paid only when it brings clear business value.
🔸 2. WHEN STRONG CONSISTENCY IS REQUIRED
Some domains cannot tolerate eventual consistency.
Examples:
🏦 Banking
💳 Payments
📦 Inventory reservation
✈️ Airline booking
Imagine:
Debit account
↓
Publish event
↓
Credit account
If something crashes in the middle...
Money disappears.
Not ideal.
Some business rules require:
either everything succeeds
or
everything fails.
Those are classic ACID transaction scenarios.
Example: One transaction
@Transactional
public void transfer(Account from, Account to, BigDecimal amount) {
from.withdraw(amount);
to.deposit(amount);
}
Some business operations require atomicity. Distributed events introduce temporary inconsistency that may violate business invariants.
Notice that this does NOT mean EDA is incompatible with finance.
Many banks use EDA extensively...
...but usually after the transactional boundary.
🔸 3. WHEN USERS EXPECT AN IMMEDIATE RESPONSE
Imagine clicking:
Pay Now
Would you like the UI to answer:
"We'll eventually process your payment."
Probably not.
Sometimes users expect:
Click
↓
Immediate validation
↓
Immediate confirmation
Synchronous APIs are often the right tool.
EDA works wonderfully for background processing:
📧 sending emails
📊 analytics
📱 notifications
🧾 invoice generation
Those actions don't block the user experience.
Example: Immediate response
@PostMapping("/login")
public Token login(LoginRequest request) {
return authenticationService.authenticate(request);
}
Authentication is conversational. The client waits for the answer before continuing. An asynchronous workflow would only increase latency and complexity.
🔸 4. WHEN THERE IS NO FAN-OUT
One of the biggest strengths of EDA is:
One producer
↓
Many consumers
Example:
OrderCreated
↓
Inventory
↓
Shipping
↓
Analytics
↓
Recommendation Engine
↓
Fraud Detection
↓
Beautiful.
Now imagine:
Producer
↓
One consumer
That's basically an asynchronous method call.
You added a broker...
to replace:
service.process(order);
Not a great trade-off.
Example: Direct service call
orderValidator.validate(order);
paymentService.process(order);
If only one service consumes the information, direct calls are usually simpler, easier to debug and cheaper to operate than an event broker.
🔸 5. WHEN YOUR TEAM IS NOT OPERATIONALLY READY
EDA is an operational architecture.
Not just a programming model.
Successful EDA requires:
✅ metrics
✅ tracing
✅ replay
✅ dead-letter queues
✅ dashboards
✅ alerting
✅ idempotency
✅ schema evolution
✅ on-call discipline
Without those...
Events become mysteries.
Imagine hearing:
"The event disappeared."
Where?
Nobody knows.
Without observability, debugging distributed systems becomes painful.
Example: Idempotent consumer
if(processedIds.contains(event.id())) {
return;
}
handle(event);
Consumers should safely process duplicate events. Idempotency is one of the foundations of reliable event-driven systems.
🔸 6. WHEN THE BUSINESS PROCESS IS ACTUALLY A CONVERSATION
EDA excels at notifications.
It struggles when every step depends immediately on the previous answer.
Example:
Client
↓
Validate
↓
Calculate
↓
Reserve
↓
Confirm
↓
Return result
Each step requires immediate feedback.
This is more of a conversation than a reaction.
REST or gRPC are usually better suited.
Example: Orchestrated workflow
Quote quote = pricingService.calculate(order);
reservationService.reserve(quote);
Sequential workflows where each step depends on the previous result are often easier to express using synchronous service calls.
🔸 7. WHEN YOU DON'T HAVE AN EVENT MODEL
Some teams create events like:
CustomerUpdated
OrderUpdated
ProductUpdated
InvoiceUpdated
Those are often just CRUD notifications.
Great events usually represent business facts, not database operations.
Examples:
✅ OrderPlaced
✅ PaymentAuthorized
✅ ShipmentDispatched
✅ SubscriptionCancelled
Those events have meaning beyond the database.
Example: Business event
publisher.publish(
new OrderPlaced(orderId, customerId)
);
Events should describe something meaningful that happened in the business domain, not simply mirror SQL UPDATE statements.
🔸 WHAT EDA IS EXCELLENT AT
EDA shines when you need:
🚀 scalability
📈 multiple consumers
⚡ loose coupling
🌍 distributed systems
📊 analytics
📬 notifications
📱 integrations
🧠 reactive architectures
It becomes even more powerful when combined with patterns such as:
▪️ Outbox Pattern
▪️ Saga Pattern
▪️ CQRS
▪️ Event Sourcing (when appropriate)
▪️ Idempotent Consumers
▪️ Dead Letter Queues
▪️ Schema Registry
🔸 COMMON ANTI-PATTERNS
❌ Kafka replacing every REST call
❌ Events for simple CRUD updates
❌ Event storms with dozens of tiny events
❌ No replay strategy
❌ No observability
❌ No idempotency
❌ Using events to hide slow services
❌ Assuming asynchronous always means scalable
🔸 TAKEAWAYS 🎯
▪️ EDA is a powerful architectural style; not a silver bullet.
▪️ Complexity should be introduced only when it solves a real problem.
▪️ Strong consistency often favors synchronous transactions.
▪️ Immediate user interactions usually benefit from synchronous APIs.
▪️ Fan-out is where EDA creates significant value.
▪️ Operational maturity is a prerequisite for production-grade event-driven systems.
▪️ Design business events around domain facts, not CRUD operations.
▪️ A good architect chooses the simplest solution that satisfies today's requirements while leaving room for tomorrow's growth.
Architecture is about trade-offs, not trends.
Sometimes the best event is...
no event at all. ☕⚡
#EventDrivenArchitecture #EDA #Kafka #ApacheKafka #SoftwareArchitecture #Microservices #Java #SpringBoot #DistributedSystems #CloudNative #CQRS #EventSourcing #SystemDesign #Backend #SoftwareEngineering #Architecture #TechLeadership
Go further with Java certification:
Java👇
Spring👇
SpringBook👇
JavaBook👇