All eyes on AI: 2026 predictions – The shifts that will shape your stack.

Read now

Tutorial

How to Build an E-Commerce App Using Redis with the CQRS Pattern

February 25, 202616 minute read
Prasan Rajpurohit
Prasan Rajpurohit
William Johnston
William Johnston
TL;DR:
CQRS (Command Query Responsibility Segregation) separates read and write operations so each can scale independently. Redis serves as the fast read-side query store in a CQRS architecture, letting you cache data as JSON documents and search them in real time while your primary database handles durable writes.
GITHUB CODE
Below is a command to the clone the source code for the application used in this tutorial

#What you'll learn

  • What CQRS is and why it matters for microservices
  • How to separate read and write paths in an e-commerce application
  • How to store and query order data in Redis using Redis OM
  • How to use Change Data Capture (CDC) to keep Redis in sync with a primary database
  • How Redis Streams enable interservice communication in a CQRS architecture

#What is command and query responsibility segregation (CQRS)?

Command Query Responsibility Segregation (CQRS) is a critical pattern within a microservice architecture. It decouples reads (queries) and writes (commands), which permits read and write workloads to work independently.
Commands (writes) focus on higher durability and consistency, while queries (reads) focus on performance. This enables a microservice to write data to a slower system-of-record disk-based database, while pre-fetching and caching that data in a cache for real-time reads.
The idea is simple: you separate commands such as "Order this product" (a write operation) from queries such as "Show me my order history" (a read operation). CQRS apps are often messaging-based and rely on eventual consistency.
The sample data architecture that follows demonstrates how to use Redis with CQRS:
CQRS architecture diagram showing how Change Data Capture (CDC) replicates writes from a system-of-record database to Redis as the read-optimized query store
The architecture illustrated in the diagram uses the Change Data Capture pattern (noted as "Integrated CDC") to track the changed state on the command database and to replicate it to the query database (Redis). This is a common pattern used with CQRS.
Implementing CDC requires:
  1. Taking the data snapshot from the system of record
  2. Performing an ETL operation finalized to load the data on the target cache database
  3. Setting up a mechanism to continuously stream the changes in the system of record to the cache
TIP
While you can implement your own CDC mechanism with Redis using Triggers and Functions, Redis Cloud comes with its own integrated CDC mechanism to solve this problem for you.

#Why should you use the CQRS pattern?

To improve app performance, scale your read and write operations separately.
Consider the following scenario: You have an e-commerce app that allows a customer to populate a shopping cart with products. The site has a "Buy Now" button to facilitate ordering those products. When first starting out, you might set up and populate a product database (perhaps a SQL database). Then you might write a backend API to handle the processes of creating an order, creating an invoice, processing payments, handling fulfillment, and updating the customer's order history… all in one go.
This method of synchronous order processing seemed like a good idea. But you soon find out that your database slows down as you gain more customers and have a higher sales volume. In reality, most apps have significantly more reads than writes. You should scale those operations separately.
You decide that you need to process orders quickly so the customer doesn't have to wait. Then, when you have time, you can create an invoice, process payment, handle fulfillment, etc.
So you decide to separate each of these steps. Using a microservices approach with CQRS allows you to scale your reads and writes independently as well as aid in decoupling your microservices. With a CQRS model, a single service is responsible for handling an entire command from end to end. One service should not depend on another service in order to complete a command.

#What does a CQRS microservices architecture look like?

Let's take a look at the architecture of the demo app:
  1. products service: handles querying products from the database and returning them to the frontend
  2. orders service: handles validating and creating orders
  3. order history service: handles querying a customer's order history
  4. payments service: handles processing orders for payment
  5. api gateway: unifies the services under a single endpoint — see the API gateway caching tutorial for more on this layer
  6. mongodb/ postgresql: serves as the write-optimized database for storing orders, order history, products, etc.
INFO
You don't need to use MongoDB/ Postgresql as your write-optimized database in the demo application; you can use other prisma supported databases as well. This is just an example.

#How does Redis fit into a CQRS architecture?

Note that in the current architecture all the services use the same underlying database. Even though you're technically separating reads and writes, you can't scale the write-optimized database independently. This is where Redis comes in. If you put Redis in front of your write-optimized database, you can use it for reads while writing to the write-optimized database. The benefit of Redis is that it's fast for reads and writes, which is why it's the best choice for caching and CQRS.
INFO
For the purposes of this tutorial, we're not highlighting how communication is coordinated between our services, such as how new orders are processed for payment. That process uses Redis Streams, and is outlined in our interservice communication guide.
TIP
When your e-commerce app eventually needs to scale across the globe, Redis Cloud provides Active-Active geo-distribution for reads and writes at local latencies as well as availability of 99.999% uptime.
Let's look at some sample code that helps facilitate the CQRS pattern with Redis and a primary database (MongoDB/ PostgreSQL).

#What does the e-commerce app frontend look like?

The e-commerce microservices app consists of a frontend, built using Next.js with TailwindCSS. The app backend uses Node.js. The data is stored in Redis and MongoDB/ PostgreSQL using Prisma. Below you will find screenshots of the frontend of the e-commerce app:
  • Dashboard: Shows the list of products with search functionality
E-commerce dashboard displaying a product catalog with search bar, product thumbnails, prices, and Add to Cart buttons
  • Shopping Cart: Add products to the cart, then check out using the "Buy Now" button
Shopping cart page listing selected products with quantities, subtotals, and a Buy Now checkout button
  • Order history: Once an order is placed, the Orders link in the top navigation bar shows the order status and history
Order history page showing a list of past orders with order IDs, statuses, and timestamps
NOTE
Below is a command to the clone the source code for the application used in this tutorial

#How do you build the CQRS write side (commands)?

Let's look at the sample code for the order service and see the CreateOrder command (a write operation). Then we look at the order history service to see the ViewOrderHistory command (a read operation).

#Create order command API

The code that follows shows an example API request and response to create an order.

#Create order request

#Create order response

When you make a request, it goes through the API gateway to the orders service. Ultimately, it ends up calling a createOrder function which looks as follows:
INFO
For tutorial simplicity, we add data to both primary database and Redis in the same service (double-write). As mentioned earlier, a common pattern is to have your services write to one database, and then separately use a CDC mechanism to update the other database. For example, you could write directly to Redis, then use RedisGears to handle synchronizing Redis and primary database in the background. For the purposes of this tutorial, we don't outline exactly how you might handle synchronization, but instead focus on how the data is stored and accessed in Redis.
TIP
If you're using Redis Cloud, you can take advantage of the integrated CDC mechanism to avoid having to roll your own.

#How does Redis OM store orders?

Note that in the previous code block we call the addOrderToRedis function to store orders in Redis. We use Redis OM for Node.js to store the order entities in Redis. This is what that function looks like:
Sample Order view using Redis Insight
Redis Insight interface displaying an Order JSON document with fields like orderId, orderStatusCode, userId, and product details
TIP
Download Redis Insight to view your Redis data or to play with raw Redis commands in the workbench.

#How do you query order history from Redis (the read side)?

The code that follows shows an example API request and response to get a customer's order history.

#Order history request

#Order history response

When you make a request, it goes through the API gateway to the order history service. Ultimately, it ends up calling a viewOrderHistory function, which looks as follows:
INFO
Note that the order history service only needs to go to Redis for all orders. This is because we handle storage and synchronization between Redis and primary database within the orders service.
You might be used to using Redis as a cache and both storing and retrieving stringified JSON values or perhaps hashed values. However, look closely at the code above. In it, we store orders as JSON documents, and then use Redis OM to search for the orders that belong to a specific user. Redis operates like a search engine, here, with the ability to speed up queries and scale independently from the primary database (which in this case is MongoDB/ PostgreSQL).

#Next steps

This tutorial demonstrated how to use Redis with the CQRS pattern to separate read and write workloads in an e-commerce microservices application. Redis reduces the load on your primary database while giving you fast, searchable JSON document storage on the read side.
To continue building out your microservices architecture with Redis, explore these related tutorials:

#Additional resources