How do you implement event sourcing and CQRS for complex business applications?
Event sourcing stores state changes as a sequence of immutable events rather than just current state. Instead of storing "account balance is $500", store all transactions: "deposited $1000", "withdrew $300", "deposited $200", "withdrew $400". Current state is derived by replaying events. Benefits: complete audit trail (every state change is recorded), temporal queries (what was the state at any point in time), event replay (reprocess events with new business logic), and debugging (reproduce any bug by replaying events). Implementation: define events as immutable facts (OrderPlaced, PaymentReceived, ItemShipped), store in an append-only event store (EventStoreDB, or PostgreSQL with an events table), implement aggregates that apply events to derive current state, and publish events to consumers via a message bus. CQRS (Command Query Responsibility Segregation): separate write model (commands: PlaceOrder, CancelOrder) from read model (queries: GetOrderStatus, ListRecentOrders). Write side processes commands, validates business rules, and produces events. Read side subscribes to events and maintains optimized read models (denormalized tables, search indexes, materialized views). This allows independent optimization: write side optimized for consistency and business logic, read side optimized for query performance and different consumption patterns. When to use: complex business domains with rich audit requirements (finance, healthcare, legal), systems needing temporal queries, and domains where multiple views of the same data are needed. When NOT to use: simple CRUD applications (event sourcing adds significant complexity), systems where current state is the only need, and small teams without event-driven experience. Challenges: eventual consistency between write and read models, event schema evolution (events are immutable, so schema changes require careful versioning), and increased complexity in development and operations.