Backend Development 10 min read

Design and Implementation of a High‑Concurrency Flash Sale (秒杀) System

This article explains the key concepts, simple design, practical steps, and multiple solution patterns—including front‑end scaling, cache‑based concurrency control, and database handling—used to build a reliable high‑traffic flash‑sale system.

Java Architect Essentials
Java Architect Essentials
Java Architect Essentials
Design and Implementation of a High‑Concurrency Flash Sale (秒杀) System

Knowledge Points Involved in Flash Sale System

High concurrency, cache, lock mechanisms

FIFO queue based on Redis or Memcached

Distributed clusters; JVM‑level synchronization is insufficient

Database pressure

Overselling issues

Anti‑scraping measures such as blacklists or IP limits

Using Memcached atomic operations for concurrency control

Simple Design Scheme

For example, with 10 items to flash‑sale, they are placed in cache and accessed without locks; when many users compete, only the first 10 succeed while the rest see a static "sale ended" page.

Assumed Flash Sale Scenario

Assume a product with 10 units, 100 web servers (Nginx + Tomcat), multiple app servers, and several databases.

Step 1: In the Java layer, use an AtomicInteger initialized to 10 on each web server; decreaseAndGet() >= 0 proceeds, otherwise returns the sale‑ended page. This reduces requests to 1000.

Step 2: Store the count (10) in Memcached with the product ID as key; each request calls decr(key,1) . If the result >= 0, continue; otherwise return failure. This leaves only the fastest 10 requests.

Step 3: Forward the request to the App server to create an order.

Step 4: The App server updates the product database with update table set count=count-1 where id=product_id and count>0; . If the update succeeds (affected rows = 1), record the order and commit the transaction; otherwise indicate failure.

Taobao's Flash Sale Practices

1. Front‑end

Common three tactics: Scaling (adding machines), Staticization (static assets via CDN), and Rate limiting (IP‑level request caps, sometimes gamified entry).

When the front‑end pool nears capacity, a "lossy service" rejects a portion of requests to protect overall availability.

2. Back‑end

Challenges under high concurrency and overselling:

MySQL performance degrades sharply after a certain concurrency level.

Overselling occurs because stock decrement is a transactional operation that can produce negative counts under concurrent access.

Row‑level locking in InnoDB leads to contention, deadlocks, and timeouts.

Solutions Adopted by Taobao

Disable dead‑lock detection to improve throughput.

Move queuing logic before the engine layer to reduce engine‑level concurrency.

Batch submissions to lower server‑engine interaction and I/O.

Solution 1

Shift write operations from MySQL to Redis; all writes occur in memory, avoiding locks and benefiting from Redis's high read/write performance. Asynchronously sync changes back to the database.

Pros: Solves performance bottleneck.

Cons: Does not fully prevent overselling; risk of temporary data inconsistency between Redis and DB.

Solution 2

Introduce a single queue for all DB writes, processing them serially. Stop consuming the queue when stock reaches zero, disabling purchases.

Pros: Eliminates overselling, modest performance gain.

Cons: Throughput limited by the slower of queue processing or DB writes; multiple queues needed for many products.

Solution 3

Perform write operations in Memcached, using its lightweight CAS lock to safely decrement stock.

Pros: In‑memory read/write is fast; CAS ensures only one successful write at a time.

Cons: Unverified under extreme concurrency; CAS may still affect performance.

Solution 4

Adopt a two‑phase commit: reserve stock via Redis atomic increment and transaction, then confirm the order. Asynchronously persist to DB.

Pros: Prevents overselling, keeps stock operations in memory, improving performance.

Cons: Possible data inconsistency due to async DB sync; risk of reserved stock not resulting in actual orders.

Summary

Front‑end tactics: Scaling , Rate limiting , Staticization .

Back‑end approaches: In‑memory solutions (Redis/Memcached) combined with queue‑based serialization to handle high concurrency and avoid overselling.

All information is sourced from the internet.

distributed systemsbackend designCacheRedishigh concurrencyflash sale
Java Architect Essentials
Written by

Java Architect Essentials

Committed to sharing quality articles and tutorials to help Java programmers progress from junior to mid-level to senior architect. We curate high-quality learning resources, interview questions, videos, and projects from across the internet to help you systematically improve your Java architecture skills. Follow and reply '1024' to get Java programming resources. Learn together, grow together.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.