An e-commerce platform allows customers to discover products, manage a shopping basket, place orders, make payments, and track deliveries. Behind this familiar experience is a collection of systems responsible for product information, inventory, pricing, payments, fulfilment, and customer accounts.
Designing such a platform is a common system design interview question because it involves several important engineering challenges. The system must support high read traffic, prevent products from being oversold, process payments safely, and continue operating when individual services fail.
In this post, we’ll design an e-commerce platform using a microservice architecture, beginning with the requirements before exploring the most important services, data flows, and trade-offs.
A system design interview may begin with a broad prompt:
Design an e-commerce platform like Amazon.
Trying to design every Amazon feature would be impossible within a single interview. A real platform might include advertising, recommendations, customer reviews, seller management, warehouses, subscriptions, fraud detection, international taxation, and many other systems.
The first step is therefore to reduce the problem to a manageable scope.
For this design, we will focus on the main customer journey. Customers can browse and search for products, view product details, add items to a basket, complete checkout, make a payment, and view the status of their orders.
The platform will use microservices so that major business capabilities can be developed and scaled independently. Clients will access those services through an API Gateway rather than communicating with every internal service directly.
Before designing the architecture, clarify what the platform must do.
The main functional requirements are centred around the purchasing journey. Customers should be able to create an account, browse the product catalogue, search for products, add products to a basket, and place an order. The system must take payment, update inventory, and allow customers to track the order after checkout.
Administrators or sellers must also be able to manage product details, prices, and available stock. More advanced features such as product reviews, personalised recommendations, promotional campaigns, subscriptions, and returns may be left outside the initial scope.
The non-functional requirements are equally important. Product pages and search results should load quickly, even during busy periods. Orders and payments must be processed reliably, and the system must prevent accidental duplicate charges. Product browsing should remain available even if a non-essential service is experiencing problems.
The system should also support sudden changes in traffic. An ordinary day may produce predictable demand, while a major promotion could increase request volume several times over within minutes.
Different parts of the platform require different consistency guarantees. A product description can tolerate a short delay before an update becomes visible. Inventory and payment data require much stricter handling because stale or duplicated operations could lead to overselling or charging a customer twice.
The architecture should be based on the actions customers perform rather than on a collection of technologies.
The first important workflow is product discovery. A customer opens the web or mobile application, browses categories, searches for products, and views product details. This is primarily a read-heavy workload and should be optimised for low latency.
The second workflow is basket management. Customers add products, change quantities, and remove items. A basket may remain active for several days and may need to work for both signed-in and anonymous customers.
The most critical workflow is checkout. The system validates the basket, confirms current prices, reserves inventory, creates an order, collects payment, and begins fulfilment. Several services participate in this process, so failures must be handled carefully.
Finally, the customer needs to track the order. The fulfilment service updates its status as the order is prepared, dispatched, and delivered. These updates can also trigger email, push, or SMS notifications.
Understanding these workflows helps separate operations that must complete immediately from those that can be processed asynchronously.
A few approximate calculations help establish the expected size of the system.
Suppose the platform has 20 million registered customers and five million daily active users. If each active user views an average of 40 product or search pages per day, the platform will handle around 200 million read requests each day.
That is an average of roughly 2,300 reads per second, but traffic will not be evenly distributed. During a major promotion, the peak could be ten times higher.
Orders occur much less frequently than product views. If the platform processes one million orders per day, the average order rate is around 12 orders per second. Peaks may still be considerably higher, particularly when limited-stock products become available.
These figures suggest that browsing and search require aggressive caching and horizontal scaling. Checkout traffic is lower, but it requires stronger consistency, reliable event processing, and careful failure recovery.
Clients communicate with the platform through an API Gateway. The gateway exposes a public API while hiding the structure of the internal services.
A simplified API might include:
GET /products
GET /products/{productId}
GET /search?q={query}
GET /basket
POST /basket/items
DELETE /basket/items/{itemId}
POST /checkout
GET /orders/{orderId}
GET /orders
The main data entities include customers, products, product variants, prices, inventory records, baskets, orders, order items, payments, and shipments.
Although these entities are related, they should not all live in one shared database. In a microservice architecture, each service should generally own its data and expose it through a defined API or event stream.
The Catalogue Service might store product descriptions, categories, attributes, and media references. The Inventory Service stores available and reserved quantities. The Order Service owns order records and their current status, while the Payment Service owns payment attempts and transaction references.
This separation prevents one service from directly changing another service’s data. It also allows each service to choose storage that matches its workload.
The platform begins with several clients. Customers may use a web application, mobile application, tablet application, or another connected device. Administrators and sellers may use a separate management portal.
All client traffic passes through the API Gateway:
Web App ───────┐
Mobile App ────┼──→ API Gateway
Admin Portal ──┘ │
├──→ Identity Service
├──→ Catalogue Service
├──→ Search Service
├──→ Basket Service
├──→ Pricing Service
├──→ Inventory Service
├──→ Checkout Service
├──→ Order Service
└──→ Payment Service
│
Message Broker
│
┌─────────┼─────────┐
↓ ↓ ↓
Fulfilment Notification Analytics
Service Service Pipeline
The web application and mobile applications provide different user interfaces, but they use the same underlying platform APIs. Keeping business logic in backend services ensures that pricing, stock validation, and checkout rules remain consistent across all clients.
Static web content, product images, and other media can be delivered through a content delivery network. This reduces latency for customers and prevents large files from consuming application server capacity.
The API Gateway is the entry point to the backend platform. It routes requests to the correct service and provides shared functionality such as authentication, rate limiting, request logging, and response compression.
It can also combine results from several services when necessary. A product page, for example, may need product information from the Catalogue Service, a price from the Pricing Service, and availability from the Inventory Service.
The gateway should not contain the platform’s core business logic. Its purpose is to manage and route external requests. Checkout rules, price calculations, and inventory decisions remain inside the services that own those responsibilities.
Multiple gateway instances should run behind a load balancer so that the gateway does not become a single point of failure.
The Identity Service manages customer accounts, authentication, addresses, and permissions. It may use an external identity provider or issue tokens that the API Gateway validates.
The Catalogue Service owns product names, descriptions, categories, attributes, and media references. Catalogue data is read frequently but updated relatively infrequently, making it a good candidate for caching.
The Search Service maintains an index optimised for keyword search, filtering, sorting, and category navigation. Product changes are published as events so the search index can be updated asynchronously.
The Basket Service stores the products a customer intends to buy. It may use a fast key-value store because baskets are frequently updated and naturally organised by customer or session ID.
The Pricing Service calculates the current price of each product. It may also apply discounts, promotional rules, taxes, or customer-specific pricing.
The Inventory Service tracks available and reserved stock. It must handle concurrent purchases carefully to prevent more units from being sold than are actually available.
The Checkout Service coordinates the process of turning a basket into an order. It communicates with pricing, inventory, order, and payment services, while ensuring that partial failures are handled correctly.
The Order Service creates and manages orders. It stores the products purchased, the confirmed prices, delivery address, payment state, and fulfilment status.
The Payment Service communicates with an external payment provider. It should store provider references and idempotency keys, but should avoid storing sensitive card details unless the platform is specifically designed and certified to do so.
The Fulfilment Service manages the process of preparing and dispatching an order. The Notification Service sends confirmation emails, delivery updates, and other customer communications.
Services can communicate synchronously or asynchronously.
Synchronous communication is appropriate when an immediate answer is required. During checkout, for example, the system may need to confirm whether an item is available before it can continue. Internal HTTP or RPC calls can provide that response.
Asynchronous communication is useful when the caller does not need an immediate result. Once an order is confirmed, an event can be published to a message broker. Fulfilment, notifications, analytics, and other services can process that event independently.
Events reduce direct dependencies between services. The Order Service does not need to wait for an email to be sent before confirming an order to the customer.
However, events may be delayed, delivered more than once, or processed out of order. Consumers should be idempotent, and important events should include identifiers, timestamps, and version information.
The most important part of this design is the checkout workflow. Product browsing can tolerate stale data or temporary failures, but checkout coordinates inventory, orders, and payments across several independent services.
When the customer selects checkout, the platform should not trust the prices or availability previously displayed in the basket. Both may have changed.
The Checkout Service first retrieves the basket and validates each product. It requests the current prices from the Pricing Service and attempts to reserve the required stock through the Inventory Service.
If inventory is available, the Order Service creates a pending order containing a snapshot of the purchased items and their confirmed prices. Storing a snapshot is important because the product name or price may change after the order has been placed.
The Payment Service then requests payment through an external provider. If the payment succeeds, the order moves to a confirmed state and the inventory reservation becomes a completed stock deduction.
An order-confirmed event is then published. The Fulfilment Service can begin preparing the order, while the Notification Service sends a confirmation to the customer.
A traditional database transaction cannot easily cover several independent microservices and an external payment provider.
Instead, the checkout process can use a saga. A saga divides the workflow into a sequence of local transactions. If one step fails, compensating actions undo the work completed by earlier steps.
For example, if inventory is reserved but payment fails, the reservation must be released. If payment succeeds but the Order Service temporarily fails, the system must retain enough information to recover safely without charging the customer again.
The Checkout Service may act as an orchestrator that records the progress of each checkout. This makes the workflow easier to understand and allows incomplete transactions to be retried or compensated.
Every important operation should use an idempotency key. If a client retries the checkout request because of a network timeout, the platform should return the existing result rather than creating a second order or payment.
Inventory is one of the most difficult parts of an e-commerce platform because many customers may attempt to buy the final unit at the same time.
A simple read followed by a write is unsafe. Two checkout requests could both read an available quantity of one and both complete the purchase.
The Inventory Service should reserve stock using an atomic conditional update. The update succeeds only when enough unreserved stock remains.
A reservation should have an expiry time. If the customer abandons checkout or payment fails, the stock can be released and made available to another customer.
This approach reduces overselling, although the business may still need procedures for rare discrepancies caused by damaged products, warehouse errors, or delayed stock updates.
Search should not query the transactional catalogue database directly for every request. Customers expect filtering, sorting, autocomplete, and text relevance, which are better supported by a dedicated search index.
When a product is created or changed, the Catalogue Service publishes an event. The Search Service consumes that event and updates its index.
The search index will therefore be eventually consistent. A newly updated product may take a short time to appear, but this is normally acceptable. The authoritative product details and checkout validation still come from the services that own that data.
Product pages and category listings are highly cacheable because they are read frequently and change relatively slowly.
Frequently accessed product data can be stored in an in-memory cache, while images and static assets are served through a CDN. Search results may also be cached for common queries, although personalisation and rapidly changing inventory can make cache keys more complicated.
Prices and availability should be treated more carefully. Cached values can be displayed while browsing, but the platform should retrieve or validate the latest values during checkout.
This gives customers a fast browsing experience without relying on stale information when an order is created.
Every network call and infrastructure component can fail, so the design must avoid turning a small failure into a platform-wide outage.
Each service should run as multiple instances across more than one availability zone. Load balancers and service-discovery mechanisms should stop sending traffic to unhealthy instances.
Calls between services should have strict timeouts. Retries should use exponential backoff and should only be attempted when the operation is safe or protected by an idempotency key. Circuit breakers can temporarily stop requests to a failing dependency, preventing a growing backlog of blocked connections.
Critical events should be stored durably in the message broker. Events that repeatedly fail can be moved to a dead-letter queue for investigation.
The platform should also support graceful degradation. If recommendations or reviews are unavailable, customers should still be able to browse and purchase products. If the Notification Service is down, orders can still be placed and confirmation messages can be sent later.
Checkout should fail safely. If the platform cannot confirm the result of a payment or inventory operation, it should record the transaction as unresolved and reconcile it rather than making an unsafe assumption.
The API Gateway should validate authentication tokens and apply rate limits before traffic reaches internal services. Services must still perform their own authorisation checks for sensitive operations.
All network communication should be encrypted. Personal information such as addresses should be protected at rest, and access to it should be restricted and audited.
Payment details should normally be collected using components provided by a trusted payment processor. This reduces the amount of sensitive card information handled directly by the platform and limits the scope of payment security requirements.
The Payment Service should verify signed callbacks from the payment provider rather than trusting requests based only on an order identifier. Refunds and other administrative actions should require strong permissions and produce audit records.
The platform should also protect itself against automated abuse. Rate limiting, bot detection, fraud checks, and unusual-purchase monitoring may be applied at different stages of the customer journey.
A microservice architecture is difficult to operate without strong observability.
Each request should receive a correlation identifier at the API Gateway. That identifier can be passed between services and included in structured logs, making it possible to trace a checkout across pricing, inventory, orders, and payments.
The platform should monitor request latency, error rates, traffic, database performance, cache hit rates, message queue depth, and service resource usage. Business-level measurements are equally important, including successful checkouts, payment failures, abandoned baskets, inventory reservation failures, and delayed fulfilment events.
Alerts should focus on symptoms that affect customers. A falling checkout success rate is usually more urgent than high CPU usage on one replaceable service instance.
Distributed tracing is particularly useful for finding slow calls and understanding where a multi-service workflow failed.
During the interview, begin by explaining the scope and the main customer journey. Make it clear that the initial design covers product discovery, basket management, checkout, payment, and order tracking.
Next, introduce the clients and API Gateway. Explain that web, mobile, and administrative applications use the gateway as the platform’s public entry point. The gateway handles shared concerns and routes requests to independently deployed services.
Walk through the high-level architecture before exploring individual technologies. Then follow one checkout request through the system, from basket validation and inventory reservation to payment and order confirmation.
The checkout flow provides a natural opportunity to discuss the most important trade-offs. Product browsing is optimised for fast, highly available reads, while inventory and payments require stronger consistency and idempotent operations. Search indexes and notifications can be updated asynchronously, but order and payment states must be recoverable.
When presenting the solution, explain why each component exists. A message broker is useful because it separates order confirmation from fulfilment and notifications. A dedicated search index supports queries that would be inefficient in the catalogue database. A reservation system prevents concurrent customers from purchasing the same final unit.
Finish by returning to the original requirements. The design supports several types of clients, uses an API Gateway to provide a consistent external interface, and divides business responsibilities across scalable microservices. It also protects the most critical workflows against duplicate requests and partial failures.
Once the core platform is working, several capabilities can be introduced.
A recommendation service could use browsing and purchasing events to create personalised product suggestions. Customer reviews and ratings could be added as a separate service, while a promotion service could manage discount codes, campaigns, and eligibility rules.
The fulfilment design could be expanded to support multiple warehouses. An order-routing service could choose a warehouse based on stock availability, delivery distance, cost, and expected dispatch time. Large orders might be divided into several shipments.
For international growth, the Pricing Service could support multiple currencies and tax rules. Product information may need translation, and data storage might need to meet regional privacy requirements.
The platform could also adopt multi-region deployment. Product browsing can be served from several regions relatively easily, but globally consistent inventory and order processing require more careful ownership and failover rules.
These improvements should be introduced according to measured need. The system should begin with the simplest design that meets the current requirements and evolve as traffic, product features, and operational demands grow.
An e-commerce platform combines read-heavy product discovery with highly sensitive order, inventory, and payment workflows.
Web applications, mobile applications, and administrative clients access the platform through an API Gateway. Behind the gateway, microservices own individual business capabilities such as identity, catalogue, search, baskets, pricing, inventory, checkout, orders, payments, fulfilment, and notifications.
Each service owns its data and communicates through a mixture of synchronous requests and asynchronous events. Product information and search results can be cached and eventually consistent, while inventory reservations, orders, and payments require stronger guarantees.
The checkout workflow is the heart of the design. It validates prices, reserves inventory, creates an order, processes payment, and triggers fulfilment. A saga coordinates these operations, while idempotency keys and compensating actions protect the system against retries and partial failures.
The most important lesson is that different parts of an e-commerce platform have different priorities. Browsing must be fast and highly available. Checkout must be correct and recoverable. A strong design recognises this difference and applies the appropriate architecture to each part of the customer journey.