System Design: Designing an Online Auction System
Designing a high-scale auction system like eBay or a penny auction site is a classic concurrency challenge. The system must handle thousands of users bidding on the same item in the final seconds of an auction, ensuring that the highest bid is always recorded and no two bids are processed out of order.
1. Core Requirements
- Create Auction: Sellers can list items with a starting price and end time.
- Place Bid: Users can place a bid higher than the current price.
- Real-time Updates: All users must see the current highest bid immediately.
- Winning: Identifying the winner exactly at the end time.
- Scalability: Handling millions of auctions and high-frequency bidding surges.
2. The Bidding Challenge: Concurrency
The most critical part is the "Last Second Surge." If 10,000 people bid in the last 100ms, how do we decide who won?
Option A: Optimistic Locking (Database)
- Logic:
UPDATE auctions SET current_price = ? WHERE id = ? AND current_price < ?. - Pros: simple, keeps the database as the source of truth.
- Cons: High failure rate under heavy contention. Many users will see "Bid Failed" because someone else beat them by a microsecond.
Option B: Distributed Locking (Redis)
- Logic: Use a Redis-based lock per
auction_id. - Pros: Much faster than database locking.
- Cons: Complex to ensure durability. If Redis crashes, you could lose the final state of the bid.
3. High-Level Architecture
- Bid Service: Receives bids and validates them against the current price.
- Auction Service: Manages the lifecycle of auctions (Start/End).
- Notification Service: Pushes updates to bidders via WebSockets.
- Payment Service: Finalizes the transaction once an auction ends.
4. Real-time Updates: WebSocket Fan-out
When a new highest bid is accepted, every other person watching that auction needs to know instantly.
- The Process:
- Bid Service updates the database and Redis.
- It publishes an "Update" event to Apache Kafka.
- The WebSocket servers subscribe to Kafka and push the new price to all connected clients viewing that specific
auction_id.
5. The "Auction End" Problem
How do you stop bids at exactly 12:00:00.000?
- Worker Workers: Use a distributed job scheduler (like our Job Scheduler article) to trigger an "Auction Closed" event at the exact timestamp.
- Buffer: The Bid Service should check the auction end time from a fast in-memory cache (Redis) before processing any bid to ensure no late bids are accepted.
6. Database Selection
- Metadata/Users: PostgreSQL.
- Bid History/Current State: PostgreSQL (for ACID) + Redis (for read-speed).
- Archival: Amazon S3 for finished auctions and historical bid logs.
Summary
Building an auction system is about Precision and Speed. By using Redis for high-frequency price updates and WebSockets for real-time fan-out, while maintaining a strict ACID-compliant source of truth in SQL, you can build a platform that handles the world's most intense bidding wars.
