Naming Events Beyond CRUD¶
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.
Think in Processes, Not in Data¶
The most important shift when naming events is moving from nouns to verbs, from data to processes. Instead of asking "which data changed?" ask "why did it change?" The cause matters more than the effect.
Steve Yegge's famous essay "Execution in the Kingdom of Nouns" describes how object-oriented programming sometimes forces everything into noun form, obscuring the actions that actually matter. The same principle applies to events. When you name an event OrderUpdated, you are describing a data mutation. When you name it OrderShipped, you are describing a business process. The first is a database operation. The second is something that happened in the real world.
Events should capture what happened in the domain, not what changed in a table. This is not just a naming convention. It is a design decision that shapes how readable, maintainable, and useful your event store becomes over time. As we explored in DDD: Back to Basics, the ubiquitous language of your domain should be the foundation for everything you build, and event names are no exception.
Why CRUD Names Hurt¶
CRUD names hide business meaning behind technical abstraction. When every change is an "update" and every removal is a "delete," you lose the ability to distinguish between fundamentally different business operations.
Consider a banking system where account changes are all recorded as AccountUpdated. Three months later, compliance asks: "Show me every account that was frozen due to suspicious activity." You cannot answer that question. The events that would tell you are buried under a generic label, indistinguishable from routine address changes or phone number updates.
You lose the "why" behind every change. And once that information is gone, it is gone forever. You cannot reconstruct intent from a generic event name. No amount of clever querying will recover what was never recorded. This is exactly the kind of signal loss that makes event sourcing less valuable, as discussed in Event Sourcing is Not For Everyone: if your events do not carry meaningful information, you are storing noise.
Renaming CRUD verbs does not help either. Add, Modify, and Remove are just synonyms. ItemModified carries exactly as much information as ItemUpdated, which is to say: almost none.
Speak the Language of the Domain¶
Event names should come directly from conversations with domain experts. If you sit in a meeting and hear a loan officer say "the application was approved," your event should be LoanApplicationApproved. If a warehouse manager says "we picked the order," your event should be OrderPicked. If a domain expert cannot understand an event name, that name is wrong.
This is the ubiquitous language at work. The same words that business people use in hallway conversations should appear in your event types. Not technical translations, not abbreviated versions, not "developer-friendly" alternatives. The actual words.
Be specific rather than generic. InvoiceSent tells you exactly what happened. DataUpdated tells you nothing. SubscriptionRenewed tells a clear story. RecordModified is a dead end. Every generic name is a missed opportunity to capture domain knowledge in your system. Your event store should read like a business journal, not a database transaction log.
Watch for Pairs¶
Many business processes have natural counterparts. An account that can be opened can be closed. A feature that can be activated can be deactivated. A request that can be submitted can be approved or rejected. When you name one side of a pair, the other side should be immediately obvious.
Opened and Closed. Activated and Deactivated. Submitted, Approved, and Rejected. These pairs and triplets reflect real business states and transitions. They make your event model self-documenting. Anyone reading the event types can understand the lifecycle of an entity without looking at a single line of code.
If the counterpart is not obvious, that is a signal worth paying attention to. Maybe there is a gap in your domain understanding. Maybe you are modeling something incorrectly. Missing pairs often point to missing conversations with domain experts.
Process Triplets¶
Long-running processes typically have three states: started, completed, and failed. Your event names should reflect this. PaymentInitiated, PaymentSucceeded, PaymentFailed. ShipmentDispatched, ShipmentDelivered, ShipmentLost. VerificationStarted, VerificationPassed, VerificationFailed.
These triplets map directly to state transitions. They make it trivial to build projections that show process status, calculate success rates, or identify stuck processes. When a payment is stuck in Initiated without a corresponding Succeeded or Failed, you know something went wrong. The absence of an expected event is just as informative as its presence.
The Reservation Pattern¶
Some processes require expressing an intention before confirming the result. A customer requests a seat, and the system either reserves it or denies the request. This is the reservation pattern, and it shows up everywhere: SeatRequested followed by SeatReserved or SeatDenied. TicketHeld followed by TicketConfirmed or TicketReleased.
The pattern separates intent from outcome. The request event captures what someone wanted to do. The result event captures what actually happened. This separation is particularly valuable in asynchronous systems and sagas, where the time between request and result might span seconds, minutes, or even days. Each event tells its part of the story, and together they form a complete narrative.
Prefer Fine-Grained Events¶
When in doubt, choose the more specific event name. CustomerAddressChanged and CustomerPhoneNumberChanged are better than CustomerProfileUpdated. Why? Because you can always combine fine-grained events into coarser views, but you cannot split a coarse event into finer ones after the fact.
If all you have is CustomerProfileUpdated, you cannot answer "How often do customers change their address?" without parsing the event payload and comparing field values. With CustomerAddressChanged, the answer is a simple count. Fine-grained events preserve semantics. Coarse events discard them.
This is a one-way door. Once you have recorded thousands of CustomerProfileUpdated events, you cannot retroactively split them into specific field-level events. The information about which fields changed might be in the payload, but the semantic distinction is lost. As we discussed in Versioning Events Without Breaking Everything, events are immutable. Design them right the first time, because you will live with them.
Events Tell a Story¶
Here is the best litmus test for your event names: read them in sequence. If you read the events for a single aggregate in chronological order, they should form a logbook that tells you exactly what happened.
OrderPlaced. PaymentReceived. OrderPicked. OrderPacked. ShipmentDispatched. ShipmentDelivered.
That is a story. Anyone can read it and understand the lifecycle of that order. Now compare it with the CRUD version:
OrderCreated. OrderUpdated. OrderUpdated. OrderUpdated. OrderUpdated. OrderUpdated.
The second version is technically accurate and practically useless. You know something happened six times, but you have no idea what. A domain expert reading the first sequence would nod along. A domain expert reading the second would ask: "But what actually happened?"
This storytelling quality is not a nice-to-have. It is what makes event sourcing powerful. Your event store is a historical record. Like any good record, it should be readable, understandable, and meaningful. As explored in All Models Are Wrong, Some Are Useful, your model does not need to be perfect, but it needs to be useful. And usefulness starts with clarity.
When CRUD Actually Fits¶
There are rare cases where CRUD vocabulary is the right choice. When something is genuinely created in the domain sense, not as a database operation but as a real act of making something new, then "Created" is appropriate.
ArtworkCreated makes sense when an artist brings a new piece into existence. DocumentDrafted might be even better, but DocumentCreated is defensible if the domain truly speaks of creation. The key question is: does the business use this word?
Consider AccountCreated versus AccountOpened. Nobody walks into a bank and says "I'd like to create an account." They say "I'd like to open an account." The domain language is clear. AccountOpened is the right name. AccountCreated is the database leaking into the domain.
The distinction is subtle but important. "Create" as a business concept (an artist creates a sculpture) is valid. "Create" as a database operation (INSERT INTO accounts) is not. Listen to how domain experts talk. That is your answer.
Your Naming Checklist¶
To help you evaluate your event names, here is a quick reference. Does the name describe a business occurrence, not a data operation? An event should reflect what happened in the domain. Would a domain expert understand it without explanation? If you need to translate, the name is wrong. Is it specific enough to distinguish from similar events? Generic names hide information. Does it use past tense? Events are facts that already happened. Does the sequence of events read like a logbook? If you read them in order, the story should be clear.
If an event name fails any of these checks, reconsider it. The investment in a good name pays off every time someone reads the event store, debugs an issue, builds a projection, or explains the system to a new team member. Good event names are not a luxury. They are the foundation of a system that remains understandable as it grows.
A Language Worth Learning¶
Naming events well is not about following rules. It is about learning to think in the language of your domain rather than the language of your database. It takes practice, it requires conversations with domain experts, and it means resisting the temptation to fall back on comfortable CRUD terminology.
If you want to explore how EventSourcingDB supports expressive event modeling, the Getting Started guide walks you through writing your first events. For deeper reading on domain modeling and event design, visit cqrs.com.
And if you are in the middle of naming your events and want to talk it through, reach out at hello@thenativeweb.io. Sometimes the best name comes from a conversation.