Design an E-Commerce Shopping Website
Company: J.P. Morgan
Role: Software Engineer
Category: System Design
Difficulty: medium
Interview Round: Technical Screen
## Design an E-Commerce Shopping Website
Design the backend system for an online shopping website (similar to a general-purpose retail store such as Amazon). Users browse a catalog of products, add items to a cart, and place orders that are paid for and fulfilled. Your design should cover the core read and write paths and then go deep on order placement under concurrency.
This is a 45-minute system-design round. Start by scoping the problem, sketch a high-level architecture, then drive into the two deep dives the interviewer cares about: **guaranteeing that a submitted order is not duplicated**, and **preventing the same last unit of inventory from being sold to two buyers at once**.
### Constraints & Assumptions
- Catalog size on the order of tens of millions of distinct products (SKUs).
- Roughly 50 million daily active users; assume a read-heavy workload with a browse-to-purchase ratio around 100:1.
- Peak traffic during sales events can be 5-10x the daily average; the checkout path must stay correct under that spike.
- A product's available inventory is a finite, decrementing count; overselling (committing more units than exist) is unacceptable.
- Orders and payments must be durable and auditable; an order, once accepted, must never silently disappear.
- Target p99 latency: catalog/product reads under ~200 ms, order placement under ~1 s end to end (excluding external payment-gateway time).
### Clarifying Questions to Ask
- What is the read/write split and the expected peak QPS for browse vs. checkout, and do we need to design explicitly for flash-sale spikes?
- Is inventory tracked at a single global level per SKU, or per warehouse/fulfillment center (which changes how we reserve stock)?
- Is payment handled by an external gateway (Stripe/Adyen/etc.), and is order creation synchronous with payment or can payment be confirmed asynchronously via webhook?
- What consistency guarantee does the business require for inventory — never oversell (strong), or is a small, reconcilable oversell acceptable for higher throughput?
- What are the durability and audit requirements for orders and payments (e.g. financial-grade, exactly-once accounting)?
- Do we need multi-region/active-active, or is a single primary region with replicas acceptable for v1?
### Part 1
Propose a high-level architecture for the whole system: the major services, the data stores behind them, and how a request flows on both the **read path** (browse catalog, view a product, view a cart) and the **write path** (add to cart, place an order). Cover how you keep the read path fast and the write path durable.
```hint Decompose by domain
Split along bounded contexts: catalog/search, cart, inventory, order, payment, and fulfillment. Each owns its own data store so one hot service does not couple to another.
```
```hint Two very different access patterns
The read path is high-volume and tolerant of slight staleness (cache + read replicas + a search index), while the write path is lower-volume but must be durable and transactional (a relational store of record per order). Designing them with the same store usually fails one or the other.
```
#### What This Part Should Cover
```premium-lock What This Part Should Cover
```
### Part 2
Deep dive: **idempotent order placement.** Network retries, double-clicks, and client timeouts mean the "place order" request can arrive more than once for what the user intends as a single purchase. Design the order-submission path so that retries never create duplicate orders (and never double-charge the customer).
```hint Make the request carry its own identity
Have the client generate a unique idempotency key per checkout attempt and send it with the request; the server keys order creation on it so a replay returns the original result instead of creating a new order.
```
```hint Enforce it at the store, not just in app code
A unique constraint on the idempotency key (or an INSERT ... ON CONFLICT / dedup table inside the same transaction that writes the order) makes deduplication atomic even under concurrent retries — application-level checks alone race.
```
#### What This Part Should Cover
```premium-lock What This Part Should Cover
```
### Part 3
Deep dive: **preventing oversell under concurrency.** Two customers try to buy the last unit of a product at the same time. Design inventory reservation so that exactly one of them succeeds and the count never goes negative, and discuss how reservations are released if a checkout is abandoned.
```hint Turn the decrement into a guarded atomic operation
Conditionally decrement only if stock is available — e.g. `UPDATE inventory SET qty = qty - 1 WHERE sku = ? AND qty >= 1` and check the affected-row count, or an atomic Redis decrement with a floor. The loser sees zero rows updated and is rejected.
```
```hint Reserve, then confirm, then expire
Separate "reserve for this cart" from "commit on payment success." A reservation holds stock with a TTL; if payment does not complete, a background sweep returns the units. This avoids both overselling and stock that is locked forever by abandoned carts.
```
```hint Pick a concurrency-control style and own its trade-off
Pessimistic row locking (`SELECT ... FOR UPDATE`) is simple and correct but limits throughput on a hot SKU; optimistic concurrency (version/compare-and-set with retry) scales better under contention but must handle retries. Name which you choose and why.
```
#### What This Part Should Cover
```premium-lock What This Part Should Cover
```
### What a Strong Answer Covers
```premium-lock What a Strong Answer Covers
```
### Follow-up Questions
- During a flash sale, a single popular SKU becomes a write hotspot and your inventory row is a point of contention. How do you keep that one counter from becoming a bottleneck without overselling?
- A payment is charged successfully but the order-confirmation write fails (or vice versa). How do you keep money and orders consistent, and how do you recover?
- If the business is willing to tolerate a tiny, reconcilable oversell in exchange for much higher checkout throughput, how would your inventory design change, and how would you reconcile afterward?
- How would you extend the single-count inventory model to multiple warehouses/fulfillment centers, where stock and reservations are per-location?
Quick Answer: This question evaluates a candidate's ability to design scalable, distributed backend systems for high-traffic e-commerce workloads. It tests practical knowledge of inventory concurrency control, idempotent order processing, and read-heavy architecture patterns commonly assessed in senior software engineer system design interviews.