Over the past few months, we have received more feedback than ever before. Hundreds of conversations with developers, architects, and CTOs have painted a remarkably consistent picture. The message was clear, and we owe it to you to be honest about what we heard: Event Sourcing is too complex. Not in theory. In theory, everyone loves it. But in practice, teams struggle. They struggle with modeling, with naming, with the sheer cognitive overhead of thinking in events rather than rows.
In a traditional CRUD system, debugging starts with a familiar question: "What is the current state?" You open the database, look at the row, and see that the order status is "cancelled." But you do not know why. Was it the customer? The payment provider? An automated process? The database shows you the crime scene, but not the crime. All you have is a body and no witnesses.
Event-sourced systems turn this on its head. Instead of inspecting the current state and guessing what went wrong, you follow the trail of events. Every change that ever happened is recorded, timestamped, and preserved. Debugging becomes less about guessing and more about reading. You are not a detective arriving at a cold case. You have a complete surveillance tape.
You have read the books. You have watched the talks. You are convinced that Domain-Driven Design would help your team build better software. The models would be clearer, the communication with stakeholders sharper, the architecture more aligned with the business. There is just one problem: nobody else in your organization knows what DDD is, and nobody asked for it.
Introducing DDD is not a technical challenge. It is a cultural one. You cannot install it like a library or deploy it like a service. It requires changing how people think about software, how they talk about problems, and how they collaborate across disciplines. That takes time, patience, and a strategy that goes beyond "let me show you this cool pattern."
You open the event store and see UserUpdated. What happened? Did the user change their email? Did they accept the terms of service? Did an admin reset their password? The event name tells you nothing. It is CRUD in disguise, a technical label that hides what actually occurred.
Now consider OrderDeleted. Why was it deleted? Did the customer cancel? Did the seller reject it? Was it flagged for fraud? Behind the same technical verb lie completely different business realities, each with its own consequences, its own rules, its own downstream effects. The name you give an event determines whether your system tells a story or keeps a secret.
Almost every Event Sourcing implementation starts with aggregates. You define a class, give it a method for each command, mutate internal state when events are applied, and wire it all up with a framework. This works. Countless systems have been built this way. But if you step back and ask what Event Sourcing actually needs at its core, the answer is surprisingly minimal.
The Decider pattern, introduced by Jérémie Chassaing, strips Event Sourcing down to three functions. No classes. No inheritance. No framework. Just three pure functions that capture everything an event-sourced component does. It is one of the most elegant ideas in the Event Sourcing space, and once you see it, it changes how you think about the entire approach.
AI-powered agents are no longer a future promise. They are here, embedded in development workflows, automating decisions, analyzing data, and helping teams move faster. Tools like Claude, ChatGPT, and Gemini have become part of the daily toolkit for developers and architects alike. But until now, these agents had no way to talk to your event store. They could reason about code, summarize documents, and generate queries, but they could not read your events, explore your subjects, or run an EventQL query against live data. The most valuable data source in an event-sourced system was invisible to AI.
Today, we are changing that. We are releasing the MCP Server 1.0 for EventSourcingDB, an extension that connects large language models directly to a running EventSourcingDB instance. It implements the Model Context Protocol, an open standard that defines how AI models discover and invoke external tools. With this release, your AI agents can read events, write events, browse subjects, inspect event types, register schemas, and run EventQL queries, all through natural language.
"All models are wrong, but some are useful." The statistician George Box wrote this in 1976, and it remains one of the most underappreciated truths in software engineering. We spend weeks, sometimes months, trying to build the perfect domain model before writing a single line of code. We draw diagrams, debate naming, argue about boundaries. The intention is good: get it right upfront so you don't have to fix it later.
But the pursuit of the perfect model is itself a trap. Models are always incomplete, always a simplification of a reality that is too complex to capture fully. The question was never whether your model is right. It was always whether your model is useful enough to start, and whether you know how to evolve it when reality teaches you what you missed.
We build a database. We spend our days thinking about storage engines, query languages, and wire formats. We obsess over write throughput, replay performance, and consistency guarantees. This is what we do, and we care deeply about getting the technical details right.
But when we look back at the most impactful conversations we've had with teams adopting Event Sourcing, they were never about technology. They were about how people work together. About how a team that had been talking past each other for months suddenly found a shared vocabulary. About how a business process that had been invisible for years became something everyone could see, discuss, and improve. That is the story we want to tell today.
When you build a database for Event Sourcing, one of the early design decisions is deceptively simple: how do you send data from the server to the client? JSON is the obvious answer. Every language has a parser, every developer knows the format, and every HTTP client handles it out of the box. But standard JSON has a fundamental limitation that becomes a showstopper the moment you deal with event streams.
We chose NDJSON as EventSourcingDB's wire format for streaming data. It's not a new technology. It's not exciting. It's barely even a specification. But it turned out to be exactly the right choice, and the story of how we got there is worth telling.
When developers discover Event Sourcing, one of the first concerns that arises is replay performance. "What if a subject accumulates thousands of events? Won't rebuilding state become painfully slow?" The answer that usually follows is snapshots. Store the current state periodically, and start replaying from there instead of from the beginning. Problem solved, right?
Not quite. In our experience, snapshots are one of the most overrated concepts in the Event Sourcing toolbox. They solve a problem that rarely exists, and when they seem necessary, they often point to a deeper issue that snapshots merely paper over. That's the paradox: the feature designed to optimize performance frequently masks a modeling mistake that, if fixed, would make the optimization unnecessary.