SYSTEM_DESIGN
System Design: Two-Sided Marketplace
System design of a two-sided marketplace connecting buyers and sellers, covering trust systems, payment escrow, search ranking, and the marketplace cold-start problem.
Requirements
Functional Requirements:
- Sellers list products/services; buyers browse, search, and purchase
- Trust and reputation system for both buyers and sellers
- Payment escrow: funds held until buyer confirms delivery
- Dispute resolution workflow with marketplace arbitration
- Commission/fee management: marketplace takes a percentage per transaction
- Seller onboarding with identity verification and payout setup
Non-Functional Requirements:
- Support 500K active sellers and 10M active buyers
- Search results must reflect new listings within 60 seconds
- Payment processing with PCI DSS compliance
- 99.99% availability for checkout and payment flows
- Transaction data retention for 7 years (regulatory compliance)
- Multi-currency support with real-time exchange rates
Scale Estimation
10M active buyers, 3M DAU. Listings: 500K sellers × 100 active listings = 50M listings. Search queries: 3M DAU × 4 searches = 12M searches/day = 139 QPS. Orders: 200K transactions/day = 2.3 TPS. Payment events: each transaction generates 3-5 payment events (authorization, capture, seller payout, platform fee) = 1M payment events/day. Page views: 3M DAU × 15 pages = 45M page views/day = 521 views/sec.
High-Level Architecture
The marketplace platform uses a microservices architecture with clear separation between buyer-facing, seller-facing, and platform services. The buyer path: CDN → API Gateway → Product Search (Elasticsearch) / Listing Detail (PostgreSQL + Redis cache) → Cart & Checkout → Payment Service (escrow model). The seller path: Seller Dashboard → Listing Management → Order Fulfillment → Payout Service.
The Payment Service implements a three-phase escrow model: (1) Buyer pays → funds are captured by the platform (Stripe Connect or similar); (2) Seller ships → buyer receives and confirms delivery (or auto-confirms after 14 days); (3) Platform releases funds to seller minus commission. The Dispute Service handles cases where the buyer claims non-delivery or item-not-as-described, freezing the escrowed funds until resolution.
The Trust Service maintains reputation scores for both parties. After each transaction, both buyer and seller rate each other. The aggregate score uses a Bayesian average (weighted by total transaction count) to avoid new sellers with one 5-star review outranking established sellers with hundreds of reviews.
Core Components
Escrow Payment Engine
The escrow engine manages the lifecycle of funds for each transaction. States: authorized → captured → held_in_escrow → released_to_seller | refunded_to_buyer | dispute_frozen. The engine uses Stripe Connect with the platform as the connected account: buyer's payment is captured into the platform's Stripe account, then transferred to the seller's connected account upon delivery confirmation. The platform fee (e.g., 15%) is deducted during the transfer. A scheduled job processes auto-releases: if the buyer doesn't confirm or dispute within 14 days, funds are automatically released. All state transitions are logged in an immutable ledger table for audit.
Search Ranking for Marketplace
Marketplace search ranking balances relevance with seller quality signals. The Elasticsearch query uses a function_score combining: BM25 text relevance (40%), seller trust score (25%), listing quality score based on photo count and description completeness (15%), price competitiveness percentile within category (10%), and recency boost with exponential decay (10%). New listings get a temporary boost for the first 48 hours to solve the cold-start visibility problem. Promoted listings (paid placement) are injected at fixed positions (every 5th result) and clearly labeled as sponsored.
Dispute Resolution Workflow
Disputes follow a structured workflow: buyer opens dispute → seller has 3 days to respond with evidence → if unresolved, marketplace arbitrator reviews → decision made within 5 business days. The Dispute Service manages this workflow as a state machine persisted in PostgreSQL. Evidence (photos, messages, tracking info) is stored in S3 with references in the dispute record. Automated resolution handles clear-cut cases: if tracking shows delivery and buyer claims non-delivery, the system auto-resolves in seller's favor. If the seller provides no response within 3 days, auto-resolves in buyer's favor.
Database Design
PostgreSQL schema: users table (user_id, email, type ENUM('buyer', 'seller', 'both'), trust_score FLOAT, total_transactions INT, created_at). listings table (listing_id, seller_id FK, title, description, price, currency, category_id, images JSONB, status, created_at). transactions table (transaction_id, listing_id FK, buyer_id FK, seller_id FK, amount, currency, platform_fee, escrow_status, created_at). disputes table (dispute_id, transaction_id FK, opened_by, reason, status ENUM('open', 'seller_response', 'arbitration', 'resolved'), resolution, resolved_at).
The ledger table stores all financial events: (ledger_id, transaction_id, event_type ENUM('capture', 'escrow_hold', 'seller_payout', 'platform_fee', 'refund'), amount, currency, stripe_transfer_id, created_at). This table is append-only and serves as the financial audit trail. A separate ClickHouse instance aggregates transaction data for marketplace analytics dashboards (GMV, take rate, seller performance).
API Design
POST /api/v1/listings— Create a listing; body contains title, description, price, category, images; returns listing_idPOST /api/v1/transactions— Initiate a purchase; body contains listing_id, payment_method; creates escrow and returns transaction_idPOST /api/v1/transactions/{id}/confirm-delivery— Buyer confirms delivery; triggers escrow release to sellerPOST /api/v1/disputes— Open a dispute; body contains transaction_id, reason, evidence_urls; returns dispute_id
Scaling & Bottlenecks
The marketplace cold-start problem — attracting sellers without buyers and vice versa — is solved architecturally by making the buyer experience excellent even with limited inventory. The system seeds initial listings by onboarding anchor sellers (high-volume, trusted sellers recruited with reduced commissions). Search quality is maintained even with sparse inventory by broadening results (if exact matches are few, show related categories) and prominently featuring top-rated sellers.
Payment processing is the latency bottleneck: Stripe API calls take 500ms-2s. The system uses async payment capture: the order is confirmed immediately with a pending payment status, and a background worker processes the Stripe capture. If capture fails (insufficient funds, expired card), the order is cancelled and the listing is re-activated. This pattern keeps checkout latency under 500ms while handling payment provider latency asynchronously.
Key Trade-offs
- Escrow over instant seller payment: Escrow protects buyers and reduces fraud, but delays seller cash flow by 14 days — mitigated by offering early payout (for a fee) to established sellers with high trust scores
- Bayesian average for trust scores: Prevents new sellers from gaming ratings with a few fake reviews, but makes it harder for legitimate new sellers to build reputation — the 48-hour new listing boost compensates
- 15% platform commission: Funds dispute resolution, buyer protection, and platform development, but reduces seller margins — competitive pressure from lower-fee platforms is the ongoing risk
- Async payment capture: Keeps checkout fast but introduces a window where confirmed orders may fail payment — 2-3% of orders experience this, requiring graceful user communication
GO DEEPER
Master this topic in our 12-week cohort
Our Advanced System Design cohort covers this and 11 other deep-dive topics with live sessions, assignments, and expert feedback.