We went through an event sourcing phase. Between 2021 and 2023, we tried to apply event sourcing to four different client projects. Two were successful. Two were disasters that we eventually rewrote as traditional CRUD applications. The pattern that emerged is clear: event sourcing is powerful for a narrow set of problems and actively harmful everywhere else.
The two successful projects shared a specific characteristic: complete history of state changes was a business requirement, not a nice-to-have. One was a financial reconciliation platform where auditors needed to trace every balance change back to its originating event. The other was a logistics tracking system where the sequence of status updates was the core data model, not a side effect of it.
The two failures were a project management tool and an e-commerce platform. In both cases, we chose event sourcing because it felt architecturally elegant, not because the business required it. The project management tool needed to track task state changes, but users only cared about the current state. Nobody was querying historical transitions. We built an event store, projections, and replay logic for data that could have been three columns in a tasks table.
The e-commerce platform was worse. We event-sourced the order lifecycle. Every feature required thinking about event streams. "Show orders over $100" required a projection. "Update shipping address" required a compensating event and a projection rebuild. Tasks that would take 30 minutes with SQL took half a day with event sourcing.
Our decision framework: you need event sourcing when the sequence and history of state changes is a first-class business concept. When your domain experts talk about events naturally. When regulations require a complete immutable history. When you need multiple views derived from the same sequence of facts. You do not need it when current state is what matters and history is informational. Most CRUD applications are current-state domains.
The implementation complexity is where teams underestimate. You need an event store, projections, a rebuild mechanism, idempotency handling, and event schema versioning. Five infrastructure concerns a CRUD app does not have, each with its own failure modes.
Our recommendation: start with CRUD and an audit log. If you find yourself building complex historical queries or multiple read models from the same data, consider migrating specific bounded contexts. The conference talk version of event sourcing is seductive. The production version is a serious commitment that pays off only when the domain demands it.
About the Author
Fordel Studios
AI-native app development for startups and growing teams. 14+ years of experience shipping production software.
We diagnosed a client application running at 40% of expected throughput. The fix was not more servers or better queries. It was proper connection pooling configuration.

We ran identical API implementations in Go and Node.js on the same hardware with real-world payloads. The results are more nuanced than "Go is faster." Here is the complete data.

PostgreSQL can handle full-text search, JSON documents, time-series data, vector embeddings, and pub/sub messaging. Here is when to use Postgres for everything and when to reach for a specialized database.
We love talking shop. If this article resonated, let's connect.
Start a ConversationTell us about your project. We'll give you honest feedback on scope, timeline, and whether we're the right fit.
Start a Conversation