Understanding Event-Driven Systems: Simple Patterns, Big Ideas
Event-driven systems are everywhere. Inspired by Martin Fowler’s insights and a thought-provoking LinkedIn post by Dragan Stepanović, let’s break down event-driven systems in plain, practical terms.

Event-driven systems are everywhere. They help apps talk to each other, handle data better, and stay responsive. But if you’re not careful, they can also get messy fast. One big problem? People often confuse event-driven architecture with specific technologies like queues or message brokers.
As Dragan Stepanović briefly put it on LinkedIn:
Here’s the kicker: you don’t need messaging/queuing technologies to do Event-Driven Architecture.
That insight sparked my curiosity and inspired me to learn more, which led to this article.
Martin Fowler’s breakdown of event patterns gives us a clear way to think about them. Here’s what you need to know.
What Is Event Notification?
Think of event notification as a simple heads-up. One system says, “Hey, something just happened!” and leaves it to others to decide what to do about it. For example, an app might send out an “OrderShipped” event to let other systems know an order is on its way.
Real-Life Example: When a user updates their profile picture on a social media platform, an event notification can be sent to notify other systems, like a newsfeed service or a recommendation engine, about the update.
Why It’s Good:
Keeps Things Independent: Systems don’t need to rely on each other too much.
Easy to Set Up: The sender doesn’t need to know who’s listening.
Why It Can Be Tricky:
Hard to Trace: If a lot of systems are listening and responding, it’s tough to see the full picture.
Hidden Commands: Sometimes, events get misused to tell other systems what to do, which defeats the purpose.
Pro Tip: Only use events when systems really don’t need to know much about each other. Be clear about what the event means.
What About Event-Carried State Transfer?
This is when the event carries all the info someone might need. Instead of just saying “OrderShipped,” the event might include details like the order number, shipping address, and delivery date. This way, the other systems don’t have to ask for more info later.
Real-Life Example: In e-commerce, when an order is placed, the order service sends an event with all order details, allowing the inventory, shipping, and notification systems to act independently without querying the order service.
Why It’s Great:
Fast and Reliable: Systems can work even if the main app goes down.
No Waiting Around: No need to call the main system to get details.
Why It Can Be a Pain:
Too Many Copies: Every system has its own version of the data, which can get out of sync.
More Work for Listeners: They have to store and manage all that extra data.
When to Use It: When speed and resilience matter more than keeping things perfectly tidy.
What Is Event Sourcing?
Event sourcing is like keeping a diary. Instead of storing the latest state of something, you write down every change. To find out what’s going on, you read through the changes and piece it together.
Real-Life Example: A banking system records every transaction as an event. To calculate the current account balance, the system replays all transactions from the event log.
Why It’s Cool:
Complete History: You can see everything that ever happened.
Undo or Replay: Go back in time or test out new ideas by replaying events.
Audit-Friendly: Perfect for tracking important changes, like financial transactions.
Why It’s Tough:
Harder to Manage: Replaying events can get complicated, especially if you’re working with other systems.
Changing the Rules: If your event format changes over time, it can break things.
Pro Tip: Use snapshots to save the current state every so often. It makes replaying faster and easier.
What Is CQRS (Command Query Responsibility Segregation)?
CQRS is about splitting the work. One part handles changes (commands), and another handles questions (queries). It’s like having two tools for two different jobs.
Real-Life Example: In a ride-sharing app, the command system manages ride bookings and updates, while the query system handles showing drivers’ locations to users in real-time.
Why It’s Useful:
Optimized Performance: Each part can be built for its specific job.
Better Scaling: You can handle lots of reads or writes without breaking a sweat.
Why It Can Be Overkill:
Extra Complexity: Splitting things up means more moving parts to manage.
Not Always Needed: For simple systems, it just adds work.
When to Use It: When your system has lots of reads and only a few writes, or when the read and write logic is very different.
Event-Driven Isn’t Just Tools
Here’s where many teams get it wrong: they focus too much on the technology. Event-driven doesn’t mean you must use specific tools like Kafka, RabbitMQ, or AWS SQS. Those are just ways to implement the patterns. What really matters is the architecture—the way systems communicate and share responsibilities using events.
Logically, event-driven architecture inverts the control flow to reduce the two-way coupling we see in request-response systems. For example, many HTTP-based technologies allow systems to subscribe to and publish events without needing traditional message queues. Adding a physical queue, like RabbitMQ or Kafka, is about solving specific problems such as load-peaking, not about defining event-driven architecture itself. You can still do Event-Driven Architecture without these tools—it’s about design, not dependency.
How to Choose the Right Pattern
Event-driven systems aren’t one-size-fits-all. Each pattern has its sweet spot:
Event Notification: Great for simple signals. Use it to keep systems loosely connected.
Event-Carried State Transfer: Use when speed and independence matter more than keeping data perfectly synced.
Event Sourcing: Perfect for audit trails and systems that need to rebuild history.
CQRS: Ideal for complex systems with heavy reads or different models for reading and writing.
Keep It Simple
It’s easy to get carried away with fancy patterns. But remember, simpler is better. Don’t use event sourcing or CQRS unless you really need them. Start small, learn as you go, and adjust as your system grows.
Final Thoughts
Event-driven systems are powerful, but they’re not magic. Understanding the patterns and when to use them makes all the difference. Start with clear goals, keep things as simple as possible, and watch out for unnecessary complexity.
Special thanks to Martin Fowler for inspiring this exploration of event-driven systems, and to Dragan Stepanović for his insightful LinkedIn post that reminded me that event-driven architecture is more about design than tools. This article is my way of learning and sharing what I’ve discovered.
Until next time,
Adlet
Loved this post? 💙 Hit that like button—it means the world to me and helps me grow.
Know someone who’d find this helpful? ♻️ Share it with them! Let's spread the knowledge and keep inspiring each other.
Stay awesome!
I can’t think of any other way to implement event driven architecture without some sort of messaging. Could you give examples of how this architecture could be implemented without those tools?