Beyond the Hype: Event Modeling, Event Sourcing, and Real Choices

Understanding the Domain Before Adding Complex Storage Patterns

Beyond the Hype: Event Modeling, Event Sourcing, and Real Choices
Image Credit: Jacob Wackerhausen

Event modeling and event sourcing frequently appear together in blog posts, conference talks, and online discussions. This association might suggest that event modeling requires event sourcing but they're actually distinct concepts that can exist independently. Many software teams incorporate events into their design while using traditional databases, while others prefer recording every change in an append-only event store. This article will explore both concepts and help you determine whether you need event modeling, event sourcing, or neither.

Event Modeling

Event modeling is a design approach that helps teams describe system behavior through a sequence of business events. An "event" is simply something significant that happens in your system (like when someone places a new order or ships an item). If you're familiar with "event storming," you'll find it quite similar. The process involves mapping out events and understanding what happens before and after each one, along with how different parts of the system respond.

The focus is on understanding why each event matters to the business and how it affects data and users. This approach typically leads to a clearer understanding of requirements and encourages domain expert participation since they can describe these events in everyday language.

Event modeling doesn't require any changes to your data storage approach. It's simply a technique for designing software that better reflects business needs. You're free to use a relational database if that suits your needs after modeling.

Event Sourcing

Event sourcing is a data storage approach where you record every state change as a separate event, rather than just maintaining the current state. For example, instead of only storing a user's current account balance, you store each transaction that affected it. To determine the current state, you replay these events in order, as if you were reading a detailed log of everything that happened in the system.

Consider a bank account example: you store events like "Deposited $100" and "Withdrew $30." The current balance is calculated by adding up all these past events. This approach is particularly valuable when you need a complete history or want to reconstruct past states. Many developers appreciate how event sourcing allows them to debug issues by examining the event log.

However, event sourcing comes with added complexity. It requires managing numerous records (in production there are as many as most people have not yet seen) and often demands specialized event storage tools, along with a process to convert stored events into a usable "read model." When business rules evolve, you might need to migrate historical events or handle multiple event versions.

Event sourcing is a storage pattern that provides comprehensive historical tracking, but it may be excessive if you don't need such detailed history or replay capabilities.

Of course, there are frameworks and tools like Marten in .NET out there that magically take care of everything. But this makes the system dependent on an additional framework and simply shifts the complexity.

Why People Conflate the Two

Event modeling and event sourcing are frequently discussed together because many articles and talks cover them simultaneously. Proponents of event sourcing emphasize the importance of designing systems around events, which naturally leads to discussions of event modeling or event storming.

So it might sound like designing with events = storing all events. I think that is not true. Especially when you have to solve real problems with the system you're building. You don't want to philosophize about it on a theoretical level and show how great it all is with a simple to-do list example. You can design a system around events (event modeling) and still decide to store only the final state in a well-designed relational database.

While some materials promote event sourcing as a "future-proof" or "audit-friendly" solution, this can create a misconception that event-driven system design requires event log storage. However, there is a pragmatic middle ground: you can use events to structure your business logic while still storing data conventionally if it better serves your needs.

Complexity vs. Business Need

Some people think the main reason to avoid an event store is the extra complexity. That is partially true: managing a stream of events is more complex. But the bigger question is whether the business needs it. If your domain needs a thorough audit trail or a way to recreate past states, an event store might be worth it. If not, the added complexity might provide no real benefit.

For example, if your business does not need to replay every action or track a detailed event history, a relational database can be a strong choice. Relational databases provide data integrity and transactional consistency. They also offer well-known tools for handling updates, queries, and backups. If you still want some event-like features, you can log specific actions in a queue or external store. Meanwhile, you keep the core entities in tables that enforce constraints and maintain consistency. This way, you meet your primary business needs without adding the complexity of storing every event.

“Do you need Event Sourcing? No, you don’t.” says Oskar Dudycz in his article CQRS facts and myths explained. He points out that Event Sourcing is often misunderstood as being required for CQRS, when it's actually "just one of many storage options available."

Dudycz emphasizes that you can implement CQRS or vertical slicing without Event Sourcing, supporting the fit-for-purpose principle of using the simplest effective solution. He considers the notion that "You need to do Event Sourcing" a common myth, showing that CQRS can work with any storage solution, including relational data models.

Feature Slices Do Not Mean Event Sourcing

I'm a strong advocate for vertical slices and have written extensively about them. While some people suggest implementing event sourcing from the start, I disagree. My philosophy is simple: build software based on actual requirements, avoiding unnecessary complexity or following trends for their own sake.

In vertical slice architecture, you organize all aspects of a feature (logic, data handling, and UI components) in one cohesive unit. This approach naturally leads to cleaner code and improved team collaboration.

But here's the key point: vertical slicing doesn't demand event sourcing. You're free to build your application in feature slices while using a traditional database. You can even selectively implement event sourcing for specific features where it makes sense. The core principle of vertical slices is keeping related logic together for better maintainability and clarity. The choice of data storage and retrieval methods remains flexible. Some slices may work better with events, while others won't need them at all.

Jimmy Bogard's philosophy aligns perfectly with this incremental, needs-based adoption of patterns. When describing Vertical Slice Architecture, Bogard says he prefers to start simple with straightforward command/query handlers that act like transaction scripts, and only refactor to [more complex] patterns when code smells or requirements demand it.

This approach means: Don't implement event sourcing or CQRS infrastructure up front for every feature. Instead, let each vertical slice determine its own path: most features can work fine with simple synchronous logic and common database inserts and updates, while select critical areas might benefit from an event-sourced model. Bogard's warning is clear: don't complicate things with unnecessary event buses and distributed logs.

I know, it’s easy to get caught up in the excitement around certain patterns. Event sourcing is interesting, and it can solve tricky problems. But it also creates new problems. You need to version your events, you might have to handle replays carefully, and you must manage more data than ever.

My recommendation is, look at the business requirements. If you do not see a clear reason to keep every historical detail, do not jump to event sourcing. If you are worried you might need that history in the future, but you are not sure, there are other ways to store data with some form of logging or archiving without going full event sourcing. For instance, you can store snapshots or keep backup logs that record changes in a more compact form.

Real-World Examples

Below are a few scenarios where some teams modeled events but did not store them all:

E-Commerce Site with Audit on Orders Only

A company wanted to know every change that happened to an order (status changes, payment updates, shipment info). They needed to be able to show an audit log. But they did not care about other data like user profiles or comments. So they modeled events across the whole system to clarify their business flows. Then, they chose to store a full event log only for the Order entity. Everything else remained in a normal CRUD database. That solved their main need without requiring them to event-source the entire platform.

Small Startup with Tight Deadlines

A small team wanted a quick launch. They mapped out their domain events to see how the app would work. They decided to store everything in PostgreSQL because they did not have time to learn or implement an event store. They still used the event models to guide how they structured their code and logic. Later, if they needed to add an event store for analytics or compliance, they could revisit the choice.

Internal App for One Department

This was a simple tool for a finance department to track budget approvals. The team did event modeling to understand what steps or events happened in a typical approval. But they realized they only needed the final state (approved or rejected). They chose to store that in a relational database. The design with events was still helpful for clarity, but the actual storage mechanism did not need to be event-based.

In each of these cases, the team used events to guide design decisions but chose a simpler storage solution. This balanced approach gave them the best of both worlds. They kept the logic clear and tied to the real business events, but they did not add extra overhead by storing every event in an append-only log.

A Note on Black-and-White Thinking

The software world is full of strong opinions. Some people claim “Event sourcing is the only proper way to build enterprise systems.” Others say, “It’s always overkill and never worth it.” The truth is somewhere in between I guess. Sometimes event sourcing is the right answer. Sometimes it is not.

To figure it out, consider these questions:

  • Do we need to see the entire timeline of changes for each record?
  • Will we gain value from being able to replay events for new requirements, debugging, or analytics?
  • Is an audit trail required for legal or compliance reasons?
  • Are we prepared to handle the complexity of versioning events and maintaining read models?

If the answer to most of these is “yes,” then event sourcing might bring real value. If not, you might be better off with another design.

Also note, you can still design your system in an event-focused way and stop short of full event sourcing. You can keep a record of the most important changes if you like. Or you can go all in and store every single event. That decision should come from the business needs, not from a blog post or conference talk pushing the latest trend, or selling the latest technology.

Final Thoughts

Event modeling helps you think about how your system behaves and how it should react to various domain events. It is a design practice that leads to better conversations with stakeholders and clearer logic. I do this since more than 10 years now. You can do it even if you store data in plain old tables.

Event sourcing is a way to store every event that happens in the system. It can be a powerful pattern, but it also introduces overhead. You need a good reason to store everything in an event store, like the need for a full audit history or replay. If you are not sure you need that, it might not be worth the complexity.

The best systems fit their actual business needs. If you only need certain features of event sourcing, consider a hybrid or partial approach. If you truly need a full append-only event store, go for it. Just be sure to weigh the trade-offs.

By understanding the difference between event modeling and event sourcing, you can avoid the hype. Do not let anyone tell you that you must have an append-only store just because you are talking about “events” in your design. And do not feel locked into a single approach. Take a step back, look at what the business needs, and pick the simplest solution that works.

In the end, we should appreciate having so many options for designing systems. It's curious that in software development, we often rush to embrace a single approach as the "ultimate solution" rather than exploring the full range of possibilities.

Cheers!

Subscribe to Rico Fritzsche

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe