Skip to content
System design course
Ch.4 · Designing real systems·concept ·9 min read

Designing an e-commerce store (Amazon)

A large online store — catalog and search, carts, the order workflow, and inventory management that must not oversell.


The problem

Design Amazon (the storefront core): browse/search a huge catalog, add to cart, checkout, and place orders — with inventory that must not oversell. It composes many subsystems (search, cart, orders, payments, inventory) into one read-heavy, money- handling marketplace.

Step 1 — Requirements

Functional: browse/search products; product pages; cart; checkout + order; inventory tracking; order history; recommendations; reviews.

Non-functional: read-heavy (browse ≫ buy), low-latency catalog/search, strong consistency for inventory + orders + payment (no overselling, no double-charge), high availability, huge scale (peak events like Prime Day).

  • Catalog — products in a store optimized for reads; denormalized product pages cached + CDN’d (mostly static). Sharded by product id.
  • Search — an inverted index (Chapter 4 search) with faceted filters (category, price, brand) and ranking (relevance, popularity, sponsored).
  • Recommendations — “customers also bought,” related items (collaborative filtering).

These are the read-heavy surfaces — caching and indexes dominate.

Step 3 — Cart

The cart is per-user, read/write often, must persist across devices and survive sessions:

  • Store in a fast KV store (e.g. DynamoDB/Redis), keyed by user; merge guest carts on login.
  • Carts are eventually consistent and tolerant — a brief glitch is fine; the price/ availability is re-validated at checkout, not trusted from the cart.

Step 4 — Inventory (don’t oversell — the core consistency problem)

When many buyers grab the last units, you must not sell more than you have:

  • Inventory counts in a strongly consistent store; decrement atomically at order placement (conditional update: decrement only if available >= qty).
  • Or reserve stock at checkout (a hold/lease) and confirm on payment, releasing on abandon — the hold pattern from Airbnb.
  • High-contention items (a hot deal) → the decrement is the bottleneck; serialize per-SKU or use atomic counters; accept that this path is CP.

Step 5 — The order workflow (a saga)

Checkout coordinates inventory, payment, and fulfillment without one global transaction → a saga (reuse DoorDash):

checkout → reserve inventory → authorize payment → create order
   → capture payment → fulfillment/shipping
   (any failure → compensate: release inventory, void/refund)

Idempotent steps + compensations; the order is a durable state machine (placed → paid → shipped → delivered).

Step 6 — Architecture

browse → catalog (cached/CDN) + search index + recommendations
cart → KV store (per user)
checkout → order saga: inventory (CP) + payment + order state machine
fulfillment → warehouse/shipping services (async)

Built as microservices (catalog, cart, order, inventory, payment, fulfillment), each scaled independently — Amazon famously pioneered this.

Trade-offs to raise

  • Catalog/search eventually consistent (fast) vs inventory/order strongly consistent (correct). Split by data — most of the site is AP, the money/stock path is CP.
  • Atomic decrement-at-order (simple, contention on hot SKUs) vs reserve/hold (better UX, more moving parts).
  • Saga (no global txn, compensations) vs distributed transaction.

The interview cue

“Catalog + search index + recommendations are read-heavy, cached/CDN’d, eventually consistent; the cart is a per-user KV store re-validated at checkout; inventory is strongly consistent with atomic decrement / reserve-and-confirm to avoid overselling; checkout is an order saga (inventory + payment + state machine) with compensations; everything is microservices.” Read-heavy catalog + CP inventory + order saga is the answer; implementation next.