Back to results for “Architecture”
Node.js › Architecture & Design Patterns

What is the CQRS (Command Query Responsibility Segregation) pattern, and when is it appropriate to introduce in a Node.js system?

Advanced

Answer

CQRS separates the models used for writing data (commands, which change state) from the models used for reading data (queries, which return state), often backed by entirely different data representations or even different databases optimized for each purpose -- this is valuable when read and write workloads have very different scaling or shape requirements (like a system with heavy, complex reporting queries but simple writes), but it's genuinely overkill for most CRUD applications, adding synchronization complexity (especially if paired with eventual consistency between the write and read models) that isn't justified without a real need.
// Command side: normalized write model
async function createOrder(command) {
  await db.orders.insertOne({ id: command.id, items: command.items, status: 'pending' });
  eventBus.publish('OrderCreated', command);
}

// Query side: denormalized read model, updated asynchronously via the event
eventBus.subscribe('OrderCreated', async (event) => {
  await readDb.orderSummaries.insertOne({ id: event.id, itemCount: event.items.length });
});
Real-world example An analytics-heavy e-commerce platform maintains a separate, denormalized read database optimized for dashboard queries, updated asynchronously whenever the normalized write database records a new order, so complex reporting queries never compete for resources with the transactional order-placement path.

Common follow-ups: What's the specific risk of eventual consistency between the write and read models, and how do you communicate that to end users?;What's a simpler intermediate step short of full CQRS for a team not ready for that complexity?