Omid Sayfun
Omid SayfunComputer Geek
Home
Notebook
Journey

Online

Github
Linkedin
Hevy
Plyatomic
Notebook
The trap of making everything dynamic
March 01, 2024
A try at type-safe groupBy function in TypeScript
April 10, 2025
Email special headers
November 20, 2024
Adding prettier to eslint
April 10, 2025
Storing Vector in Postgres with Drizzle ORM
March 21, 2024
Upgrading my blog to Next 15
April 05, 2025
Canvas macOS issue
February 20, 2024
tsx doesn’t support decorators
March 26, 2025
Validating NestJS env vars with zod
February 06, 2025
Extending Window: types vs interfaces
March 21, 2025
Loading env file into Node process
February 06, 2025
Add update date field to Postgres
February 27, 2024
Using node API for delay
February 06, 2025
React Component Lifecycle
November 28, 2024
How CQRS is different than Event Sourcing
August 18, 2024
RabbitMQ exchange vs queue
August 14, 2024
PgVector similarity search distance functions
August 13, 2024
PgVector indexing options for vector similarity search
July 31, 2024
Using puppeteer executable for GSTS
June 08, 2024
Why EQ is Your Next Career Upgrade
May 13, 2024
Counting GPT tokens
June 30, 2024
Logging route handler responses in Next.js 14
June 19, 2024
Redirect www subdomain with Cloudflare
June 17, 2024
Logging requests in Express app
June 16, 2024
Move Docker volume to bind mount
June 12, 2024
Next.js Hydration Window Issue
May 29, 2024
Using Git rebase without creating chaos in your repo
May 16, 2024
Implementing RPC Calls with RabbitMQ in TypeScript
March 16, 2024
Optimize webpage load with special tags
March 15, 2024
What the hell is Open Graph?
March 13, 2024
My go-to Next.js ESlint config
March 10, 2024
List of useful Chrome args
March 10, 2024
Combining RxJS observables - Part 1
February 20, 2024

How CQRS is different than Event Sourcing

August 18, 2024

Have you ever found yourself in a heated debate about CQRS and Event Sourcing, only to realize that you and your opponent are talking about two different things? These two patterns often get mixed up, but they're actually distinct concepts that can be used independently or together. Let's break it down and see what makes each of them tick.

What's CQRS Anyway?

CQRS, or Command Query Responsibility Segregation (try saying that five times fast!), is like having two separate entrances to your favorite restaurant. One door is for placing orders (commands), and the other is for checking the menu or asking about daily specials (queries).

In CQRS, we split our application's operations into two models:

  1. Command model: Handles write operations (create, update, delete)
  2. Query model: Handles read operations

This separation allows us to optimize each model independently. For example, we might use a normalized database for our command model to ensure data integrity, while our query model could use a denormalized database for faster reads.

Event Sourcing: The Historian

Now, let's talk about Event Sourcing. Imagine if, instead of just keeping track of your current bank balance, your bank recorded every single transaction you've ever made. That's essentially what Event Sourcing does for your application.

In Event Sourcing:

  1. We store every state change as an event
  2. The current state is derived by replaying all events
  3. The event log becomes the single source of truth

It's like having a time machine for your data. You can reconstruct the state of your application at any point in time by replaying events up to that point.

CQRS vs Event Sourcing: The Showdown

Now that we've got the basics down, let's compare these two patterns:

Pros of CQRS:

  1. Scalability: You can scale read and write operations independently
  2. Performance: Optimized read and write models can lead to better performance
  3. Flexibility: Easier to adapt to changing business requirements

Cons of CQRS:

  1. Complexity: Two models mean more code to maintain
  2. Eventual consistency: The read model might lag behind the write model
  3. Learning curve: It's a significant shift from traditional CRUD operations

Pros of Event Sourcing:

  1. Audit trail: Complete history of all changes
  2. Temporal queries: Ability to determine the state at any point in time

Continue Reading

  • Event replay: Easier to fix bugs by replaying events
  • Cons of Event Sourcing:

    1. Complexity: Requires a different way of thinking about data
    2. Performance concerns: Replaying a large number of events can be slow
    3. Event schema evolution: Changing event structures can be challenging

    CQRS and Event Sourcing are not mutually exclusive. In fact, they often work well together. You could use Event Sourcing in your command model to capture all changes as events, and then use CQRS to separate your read and write concerns.

    But remember, just because you can use them together doesn't mean you always should. Each pattern comes with its own complexity, and combining them multiplies that complexity. As with all things in software development, it's essential to consider your specific use case and requirements before diving in.

    So, the next time someone asks you about CQRS and Event Sourcing, you can confidently explain the difference. Just don't be surprised if you end up in a lengthy discussion about the pros and cons – everyone loves a good architectural debate!

    tl;dr

    CQRS separates read and write operations into distinct models, optimizing each for its specific purpose.

    Event Sourcing stores all state changes as events, allowing for complete historical reconstruction.

    While they're different patterns, they can be used independently or together, each bringing its own set of advantages and challenges to the table.

    • 02-20-2026

      The trap of making everything dynamic

    • 04-11-2025

      A try at type-safe groupBy function in TypeScript

    • 04-10-2025

      Email special headers

    • 04-10-2025

      Adding prettier to eslint

    • 04-09-2025

      Storing Vector in Postgres with Drizzle ORM