# Command Query Responsibility Segregation Is a data layer pattern or architecture in which separate models are used for reading and writing data to/from a database. The exact meaning of the word 'model' varies from solution to solution. This principle should not be confused with the [[Command Query Separation]] principle. Several different separation levels are possible: 1. Separate interfaces (in the OOP sense) can be used. This is a very low level of separation and is usually not what people think of when talking about CQRS. It can still have benefits e.g. to easily identify code that changes the database. 2. Completely different classes can be used for reading and writing (as opposed to one class with multiple interfaces) but the same database. The database in this case is used as a synchronization mechanism (see below). 3. The different data models can run in separate processes (as separate [[Microservice Architecture|microservices]]), or even on different hardware, but use the same database as a synchronization mechanism. 4. Completely different databases can be used. The query database in this case acts as a [[Reporting Database]] which tends to be [[Eventual Consistency|Eventually Consistent]]. In this case, the main architecture question is how hard you should work to keep the two databases consistent. ## Benefits The main argument for CQRS is that a traditional CRUD (Create, Read, Update and Delete) data model has two responsibilities (reading and writing) which violates the [[Single Responsibility Principle]]. As a traditional model increases in complexity, trade-offs might be made that benefit one of those responsibilities at the expense of the other. Eventually, the traditional model does neither one of those two jobs well. By using two models to begin with, we eliminate the need for such trade-offs. ## Drawbacks However, CQRS adds significant complexity from the beginning, potentially violating [[YAGNI]]. Unless you have excellent reasons for it, you should avoid it as the added complexity significantly increases risk as it is easy to get it wrong. In addition, CQRS has implicit synchronization issues, which are not even applicable in the traditional model, which should not be taken lightly. One such reason would be if you're using event sourcing, where stored data is not easily queryable. The solution is to introduce a separate read-only database that is used to support the query model, which is kept synchronized by domain events. ## Sources - Martin Fowler. [CQRS](https://www.martinfowler.com/bliki/CQRS.html). - Chris Richardson. [CQRS](https://microservices.io/patterns/data/cqrs.html).