Is DDD Overkill for My CRUD Project? - EventSourcingDB
Skip to content
Initializing search
Getting Started
Fundamentals
Deployment and Operations
Reference
Client SDKs
Extensions
MCP Server
Best Practices
Implementation and Development
Data Management and Performance
Operations, Compliance and Infrastructure
Common Issues
Blog
Categories
Privacy Policy
Legal Notice
Is DDD Overkill for My CRUD Project?¶
We hear it almost every week. A developer leans back, half-smiles, and says something like: "Domain-Driven Design? Sure, for a big enterprise system. But mine is just a simple CRUD app. Wouldn't DDD be total overkill?" The tone is friendly, sometimes even a little apologetic, as if they're letting us down gently. And the reasoning sounds airtight. CRUD is simple. Domain-Driven Design is heavy. Why bring a freight train to move a couch?
We get the instinct. Most of us have rolled our eyes at a slide deck full of Bounded Contexts for an app that, frankly, has one table and three buttons. But once you scratch the surface of this question, two different things turn out to be hiding under the same word. One of them really is overkill for your CRUD app. The other one isn't even optional , and you're either doing it well or doing it badly right now, whether you call it DDD or not.
There's No Such Thing as a CRUD App¶
We're going to make a claim that sounds combative, and then we're going to back it up with a Todo list. There is no application that is just data in, data out. Not a single one we've ever seen, including the kinds of apps people use as the canonical example of pure CRUD.
Take a Todo list. It's the cliché. You create a todo, you read it, you update it, you delete it. Four verbs. What could be simpler? Well, look at what those four verbs are actually hiding. When you "delete" a todo, are you doing the same thing every time? Of course not. Sometimes you delete a todo because you finished it, and you want it gone from the list. Sometimes you delete it because the meeting was cancelled, and the task no longer applies. Those two events have the same shape on the screen, but they mean entirely different things in your life. A Completed event and a Discarded event are not the same outcome, and pretending they are throws away meaning that was right there in front of you. We've spent a whole post on why soft delete is a workaround for exactly this kind of confusion.
The same is true for "update." You don't update a todo. You adjust its description because you realized you wrote it ambiguously. You postpone the due date because something else came up. You advance the date because the deadline got moved. Adjusted, Postponed, and Advanced are three completely different events with three completely different reasons, and your "update" verb erased the difference. The data after the update doesn't tell you what happened. It only tells you what is now true.
This is the part most people miss when they call something CRUD. CRUD isn't a description of the app. CRUD is a description of what your storage layer demands of the app. It's not that the domain has four operations. It's that you funneled every operation in the domain into four generic boxes because that's what the database understands. The semantics were there. You traded them for table rows.
If a Todo list has this much hidden semantics, what about the app you build at work? The order system, the booking platform, the internal HR tool, the CMS, the support ticketing thing your team built two years ago. Every one of them has registrations, cancellations, escalations, reassignments, splits, merges, deferrals, approvals, rejections, retractions, reopenings. None of those are CRUD. They were made to look like CRUD because that's what the database understands. The domain didn't agree.
"DDD Is Overkill" Talks Past the Real Question¶
Now we can get to the part where the question itself goes off the rails. Domain-Driven Design isn't one thing. It's three. And when people debate whether DDD is overkill, they almost always mean only one of those three. The other two get smuggled along for the ride, sometimes as an unfair advantage and sometimes as collateral damage. It's worth pulling them apart.
The first kind of DDD is strategic . Bounded Contexts, Context Maps, anti-corruption layers, the choreography of teams across a large organization. These are the tools you reach for when the org is big enough that two teams are using the same word to mean different things, and a third team is being quietly ground up at the boundary. For most projects we see, this part of DDD really is overkill at the start. It pays off later, but later is later. You don't need to do strategic DDD on day one.
The second kind is tactical . Aggregates, Repositories, Factories, Specifications, Domain Services, Value Objects. This is the part with the ceremony, the inheritance trees, the architectural diagrams that mix UML and flowcharts until nobody quite...