Introduction

By 2026, more than 20 years have passed since the publication of Eric Evans’s “Blue Book,” and 15 years have passed since the release of Greg Young’s “CQRS Documents.” In the years since, a fair number of books have appeared on the practical application of DDD and CQRS principles, such as Vaughn Vernon’s “Implementing Domain-Driven Design” or Millett and Tune’s “Patterns, Principles, and Practices of Domain-Driven Design.” Despite this long history of theory and the considerable body of material available, a developer setting out to apply DDD and CQRS principles in practice constantly runs into questions for which no clear-cut answers exist. Stack Overflow often offers little more than hints at solutions, and the rise of AI, with its tendency to produce contradictory recommendations, has only made things worse. Should aggregates really be made as small as possible, and where is the line beyond which further splitting stops being useful? How should a large aggregate be split while preserving the relationships between entities? Should an aggregate contain fields like name or description that have no bearing on its behavior? Does the application layer contain domain logic? Should events be “thin,” carrying only identifiers, or should “fat” events that carry execution context be preferred? At what point in the code are events created (the new operator)? If this happens inside the aggregate, how should the code be organized when the aggregate itself is being created? Does the repository need a save method? Where does transaction-management code belong? Should the application layer publish events? Where does command validation live in a CQRS architecture? How is synchronous communication organized between a client and a server that operates asynchronously? My colleague and I were no exception either: many of these questions had no answer for us. So, before actually starting work on a new project, we decided to consolidate the experience gained on previous projects, and held a series of meetings where we spent long stretches discussing our assumptions, trying to “stress-test” them and see where theory runs into trouble in practice. Over time, our understanding of DDD and CQRS grew, and many practical problems began to fit naturally into the architecture we were developing in parallel. We recorded all of our discussions in notes, and it’s those very notes that we want to share with you, the reader.