Skip to content

Is Event-Driven Architecture Overkill for Most Apps?

Sponsor: Do you build complex software systems? See how NServiceBus makes it easier to design, build, and manage software systems that use message queues to achieve loose coupling. Get started for free.

Learn more about Software Architecture & Design.
Join thousands of developers getting weekly updates to increase your understanding of software architecture and design concepts.


I get it. Most apps really are that simple. Typically, just CRUD. A user submits a form, you validate some data, save it in a database somewhere, and return a response. That is it. So is Event-Driven Architecture Overkill then?

YouTube

Check out my YouTube channel, where I post all kinds of content on Software Architecture & Design, including this video showing everything in this post.

Event-Driven Architecture Overkill?

This topic stemmed froma Reddit post that I thought was pretty interesting. Primarily because it’s confusing a lot of concepts and seems to miss the point of Event-Driven architecture. So that’s what this post is trying to clarify.

Pretty much my blog/channel.

I bring up these topics because I think they have a lot of utility and value within a given context. The problem is when there is confusion about what these ideas actually are, and you do not really understand the problem they are trying to solve.

Here’s what confuses me: a friend’s startup processes maybe 10k orders monthly, yet they’re implementing event sourcing. Another friend at a larger company says their monolith handles 100x that traffic just fine.

So what’s the reality? Are we overengineering because it’s trendy? Or am I missing something fundamental about when events actually matter? Real thresholds where event-driven becomes necessary

Neither example has anything to do with the point.

Event sourcing has nothing to do with scaling. A monolith versus services has nothing to do with whether events make sense. So what is the reality? Are we overengineering because it is trendy, or are people missing something fundamental about what events actually are and where they matter?

The reality is, there is just a lot of confusion around event-driven architecture and the different ways you can use events. That is the confusing part.

Scaling is a benefit, not the reason

One of the first things to clear up is scaling.

Yes, scaling can be a benefit of using asynchronous messaging, but that is not the reason to use event-driven architecture.

Imagine a client interacting with an HTTP API. That API publishes messages to a topic on a message broker. Then a separate worker consumes those messages and interacts with the same database. This could even all be happening inside a monolith.

When people think about scaling an HTTP API, they usually think of adding more instances behind a load balancer so more requests can be processed concurrently. That same idea applies to workers consuming messages. You can scale out more workers and process more messages concurrently.

That is the competing consumers pattern.

So yes, there is a scaling benefit there. But again, that is not the primary reason you would apply event driven architecture.

Events as notifications between responsibilities

One of the main reasons to use event-driven architecture is that something happened in your system, and some other independent concern might need to react to it.

That means you have a publisher producing an event because something happened, but it has no idea whether there are any consumers, whether there is one consumer, two consumers, or ten. It does not know if any other part of the system even cares.

What you are doing is decoupling responsibilities in time.

A simple example is shipment delivery.

You order something online. You get tracking information. Maybe you use an app on your phone. Then all of a sudden you get a notification that your package has been delivered.

That notification is one responsibility.

The actual act of somebody dropping off the package, taking the picture, and persisting that to the system is a completely different responsibility.

So when the package gets delivered, that fact can be published to a message broker. From there, different parts of the system can react.

One consumer might send a webhook to some third party system. Another might send an SMS through Twilio. Another might send a push notification through Firebase. These are all different responsibilities, and they are not directly part of the delivery action itself.

That is the point.

Those downstream actions were not part of the decision making process of whether the delivery should happen. The delivery already happened. The decision was already made. Now other parts of the system are reacting to that fact.

That is a good way to think about events. They are facts. Something occurred, and now other responsibilities can respond to it independently.

That is one of the big benefits of event driven architecture in the form of notifications.

Commands and events are not the same thing

This is another place where people get confused.

Just because you are using asynchronous messaging, a message broker, or queues, that does not automatically make your system event driven.

Commands and events are different things.

A command is trying to invoke behavior. It is something like DeliverShipment. It is an instruction. Typically, there is one consumer responsible for handling that command.

There may be multiple parts of the system that can send that command, but the command itself is about telling something to do something.

An event is different.

An event is a statement of fact. Something happened. ShipmentDelivered. PackageDelivered. OrderPlaced.

Typically, an event has one publisher, and there can be zero, one, or many consumers. The publisher does not know who those consumers are, and it does not need to.

That distinction matters.

When someone signs for a package on a device and that triggers a request to your HTTP API, that request is handling a command. It is doing the work of recording the delivery. It should not also be directly responsible for sending every webhook, every SMS, and every push notification as part of the same workflow.

Those are separate concerns. That is where events fit.

Event sourcing is about state, not notifications

There is even more confusion because events can serve different purposes.

Earlier I was talking about events as notifications. But event sourcing is something else entirely.

Event sourcing is about state.

Instead of recording current state, you record the series of events that state can be derived from.

That is a completely different utility than using events for notifications.

Take a shipment as an example. You might have events like:

  • Dispatched
  • ArrivedAtShipper
  • Loaded
  • Departed
  • ArrivedAtConsignee
  • Delivered

Each shipment has its own stream, its own series of events. Another shipment has a different stream.

Those events become your source of truth.

From that stream, you can derive state. You can project it into a relational table. You can put it into a document store. You can shape it however you want. At any point in time, you can rebuild the current state or derive what the state looked like earlier.

That is what event sourcing is.

So yes, you can be using events for collaboration and notifications between parts of your system. And yes, you can be using events as the source of truth with event sourcing. Those things can overlap.

But they are not the same thing.

Do not use events just because everyone else is

Do not use events because you want to use a broker. Do not use them because everybody is using Kafka. Do not use them because you heard it scales better.

That is not a good reason.

Use events for notifications because a business fact occurred and other consumers want to respond to that fact on their own timeline.

Use events when you want to remove temporal coupling.

Use them when you have integration boundaries between parts of your system, whether that is inside a monolith, between services, or with external systems.

Events can act as a contract at those boundaries.

And do not use event sourcing just because you want to be event driven.

That is where people get themselves into trouble.

CRUD sourcing is not event sourcing

One of the worst examples of this confusion is when people use event sourcing even though all they are really doing is recording current state changes.

I often call this CRUD sourcing.

The event stream becomes something like:

  • ShipmentCreated
  • ShipmentUpdated
  • ShipmentUpdated
  • ShipmentUpdated

That is not event sourcing in any meaningful sense.

On the flip side, event sourcing makes sense when history matters.

When the sequence of events matters.
When understanding how something got to its current state matters.
When those events are real domain language.

In the shipment example, Dispatched, ArrivedAtShipper, Departed, ArrivedAtConsignee, Delivered. That is domain language. That history has meaning. That history has value.

That is the exact opposite of CRUD sourcing.

If you care about that history, and you want to use it as your source of truth and derive different views or models from it, then event sourcing can be a really good fit.

So, is event-driven architecture overkill?

It can be.

If your app really is just request-response, and you do not have different workflows, independent responsibilities, or integration boundaries, then yes, it could absolutely be overkill.

Do not invent problems for solutions you do not fully understand.

Scaling is a benefit in some cases, but it is not the reason to use events as notifications, and it is not the reason to use event sourcing.

Use events for notification purposes when you want to decouple responsibilities in time.

Use event sourcing when history matters, when the domain language matters, and when recording that sequence of facts as your source of truth gives you real value.

Do not make it more complicated than that.

Join CodeOpinon!
Developer-level members of my Patreon or YouTube channel get access to a private Discord server to chat with other developers about Software Architecture and Design and access to source code for any working demo application I post on my blog or YouTube. Check out my Patreon or YouTube Membership for more info.