Get in touch

Fill out this form and our team will respond as soon as we can, alternatively email us at mail@icepanel.io

Get in touch

Fill out this form and our team will respond as soon as we can, alternatively email us at mail@icepanel.io

Back to all blogs

Design eBay using IcePanel

System design of eBay on IcePanel đź§Š

c4 modelsystem designtutorial
18 Dec 2025
Blog hero image

📝 Introduction

In this post, we’ll share an example architecture for eBay – one of the largest online auction and marketplace platforms where users can buy and sell items or make direct purchases. We’ll design this as software architects and create four hierarchical diagrams: Context, Container, Component, and Code (not sure what these are? Read this). We’ll annotate the building blocks and highlight user interaction (data flow) within the system using IcePanel Flows.

Let’s first define the scope by writing the functional and non-functional requirements of the system. Afterwards, we’ll go through each layer of the C4 model.

You can view the final architecture at this link: https://s.icepanel.io/DWnaysJ3cbCQqg/eYV5


🔎 Scope

For an online auction like eBay, users should be able to:

  1. Sell an item or post it for auction with a starting price.
  2. Buy an item or place a bid with a price higher than the current bid.
  3. View an auction for an item with the current highest bid.

For non-functional requirements, the system should have:

Let’s start with the first diagram, Context.


Level 1 - Context

This context view shows the interaction between end users, our main system (eBay), and the external systems it integrates with. In this design, we have two actors:

Level 1 - Context diagram

Ebay also depends on two external systems:


Level 2 - Container

This diagram is where we model a collection of independently deployable or runnable applications or data stores that are essential for the overall software system to function. This could be a web application, server, datastore, or a streaming data platform like Apache Kafka.
This system is an event-based architecture. This approach is ideal for high-throughput bidding scenarios where services process messages asynchronously whenever an item receives a bid. Events are triggered using Kafka topics, allowing the system to handle traffic spikes gracefully while maintaining strong consistency guarantees.

Our system is composed of the following Containers:

  1. Auction Service: Manages the complete auction lifecycle, including creating new auctions when sellers list items, reading auction details and current bid status, and updating auction metadata (start time, end time, status).
  2. Bid Producer: Responsible for accepting and validating incoming bids. It validates bid amounts with atomic checks on Redis, publishes bids to Kafka for asynchronous processing, and atomically updates the bid cache.
  3. Bid Service: Consumes bid events from Kafka and provides durable persistence. It consumes bid events from a Kafka topic, persists all bids to the Auction Database (bids table) for audit trail, and updates the auction’s current price in the database.
  4. Notification Service: Manages all user communications. It consumes bid events and auction lifecycle events from Kafka, sends real-time notifications when users are outbid, and sends winning bid confirmations.

Note: Real-time solutions like WebSocket connections for live auction updates and publish/subscribe patterns are outside the scope of this design. This architecture focuses on the core bidding flow, auction management, and durable event processing.

In this architecture, we use the following technologies:

  1. AWS API Gateway: A scalable and secure entry point for all API requests coming from the frontend. This object is represented using connection via property.
  2. AWS EC2: Web service that provides reliable and secure compute for the different microservices (Auction Service, Bid Producer, Bid Service, Notification Service, Payment Service).
  3. Apache Kafka: A distributed event streaming platform that provides high throughput (millions of messages per second), durability (persists all messages to disk with replication), and ordering guarantees (partitioning by auction_id ensures sequential processing). Perfect for handling high-volume bidding periods while ensuring no bids are lost. This object is represented using a connection via property.
  4. PostgreSQL: An ACID-compliant relational database that ensures data integrity and strong consistency. Ideal for structured data like auctions and bids tables where transactional guarantees are critical.
  5. Redis: A fast in-memory cache that improves response times (sub-millisecond latency) and reduces database load. Essential for serving current bid prices to 1 million concurrent auctions.

We’ve designed two common data flows using IcePanel. Check out these flows and play them step by step to see how our system works:

Level 2 - App diagram

  1. Create a new auction listing: https://s.icepanel.io/DWnaysJ3cbCQqg/SpZW
  2. Place a bid on an auction: https://s.icepanel.io/DWnaysJ3cbCQqg/rmpv

Level 3 - Component

In the C4 model, a component is a grouping of related functionality encapsulated behind a well-defined interface. For example, a collection of classes behind an interface. Let’s look at the Components in eBay’s auction system.

1. Bid Producer

The diagram below shows how a user interacts with the Bid Producer to place a bid on an auction. When a user sends a POST /bid request, the Bid API first validates the request and extracts the auction_id and bid_amount. It then retrieves the current highest bid from the cache (using optimistic locking) and checks if the new bid amount exceeds it. If the bid is too low, an error is returned to the bidder. This prevents race conditions when multiple bidders submit bids simultaneously.

Once the Redis lock is acquired, the Bid Kafka Publisher sends a new bid event to the bid-events topic in Kafka. The bid event includes auction_id, user_id, bid_amount, and timestamp. After publishing to Kafka, the service atomically updates the current highest bid in Redis (auction:{id}:price) before releasing the lock.

Level 3 - Component diagram for Bid Producer

2. Auction Service

The Auction Service manages the complete auction lifecycle and provides read/write access to auction data. When a user requests auction information via GET /auctions/:auctionId, the Auction API first checks the Auction Cache (Redis) to retrieve hot auction data with sub-millisecond latency. If the data isn’t cached, the Auction Controller queries the Auction Repository, which fetches auction details from the Auction Database (PostgreSQL).

The Redis Client manages all cache operations, storing frequently accessed auction data with time-to-live (TTL) values to reduce database load. The Auction Repository handles all database interactions, including creating new auction listings when sellers post items, updating auction metadata (start time, end time, reserve price), and querying active auctions with filters.

When an auction ends, the Auction Controller determines the winning bidder by querying the highest bid from the database. It then triggers the Auction Payment Controller, which initiates the payment flow by calling the Payment Service. The Payment Controller handles payment confirmations, failures, and refund processing for cancelled auctions.

Level 3 - Component diagram for Auction service

3. Bid Service

The Bid Service handles all bid processing in our online auction system. When a bid event is published to Kafka, the Bid Consumer polls messages from the bid topic and processes each bid event asynchronously. It interfaces with the Bid Repository, which serves as the data access layer for storing and retrieving bid information. The Bid Repository executes SQL queries against the Auction Database (PostgreSQL) to persist bids into the database and maintain bid history.

Level 3 - Component diagram for Bid service

Let’s go one level deeper with the source code in the Code layer.


Level 4 - Code

This is where we can view implementation details at the code level. We don’t recommend creating extensive diagrams for this; instead, we link directly to the code. However, here’s the general structure of these components for reference. We’ll briefly go over two Components: Auction and Bid Producer.

Classes in “Auction Service”

This component manages auction lifecycle and real-time auction data access. The Auction API class exposes RESTful endpoints for retrieving auction details, current high bids, and auction status. The API first checks Redis cache for hot auction data before querying the database. The Auction Controller coordinates between cache, repository, and payment processing. The Auction Repository serves as the data layer for fetching auction information from the Auction Database.

Auction Controller

Redis Client

Auction Repository

Auction Payment Controller

Classes in “Bid Producer”

This component handles the bid submission workflow with strong consistency guarantees. The Bid API class provides RESTful endpoints for users to place bids and check bid status. The Bid Validator ensures bid amounts meet minimum requirements and auction eligibility rules. The Optimistic Lock Manager implements Redis-based locking to prevent race conditions during concurrent bidding. The Kafka Producer handles asynchronous event publishing for downstream bid processing and notifications.

These classes have roughly the following methods:

Bid API

Cache Client

Kafka Producer


Conclusion

In this post, we designed an online auction platform (eBay) using the C4 model on IcePanel. We began with the core requirements like strong consistency, real-time updates, and fault tolerance, and modeled the system from the top down, starting with the Context layer, followed by the Container, Component, and finally the Code layer.

If you enjoyed this post, check out our previous design deep dives using IcePanel:

  1. Design YouTube
  2. Design Ticketmaster

📚 Resources

Shehab

Get cool architecture news

Sign up for our free newsletter.

Stay chill

Get in touch

Fill out this form and our team will respond as soon as we can, alternatively email us at mail@icepanel.io