•CASE STUDY

Coupon Distribution System

8 min read·1,436 words·Advanced

How to use this case study

SDE-2 / Mid

  • Focus on sections 1-3: requirements, API design, and high-level architecture
  • Understand how unique code generation works and how redemption validation works in real-time

SDE-3 / Senior

  • Be ready to discuss the campaign engine design, how to prevent coupon fraud, and the trade-offs between SQL vs NoSQL for coupon storage
  • Know how to scale redemption to 5K req/sec

Staff / Principal

  • Be prepared to discuss the event-driven architecture for coupon lifecycle tracking, CRM integration patterns, and how to design the analytics pipeline for ROI measurement
  • Discuss consistency guarantees for distributed coupon issuance

Problem RestatementProblem

Design a highly scalable system that can generate and distribute unique, trackable coupons to millions of users. The solution must support personalization, real-time redemption validation, lifecycle tracking, and seamless integration with a CRM for targeted campaigns and analytics.

RequirementsRequirements

1.1 Functional

  • Generate coupons: Unique codes per user, tied to specific campaigns.
  • Track metadata: Expiry, discount type/value, usage limits.
  • Support types: One-time and multi-use coupons.
  • Real-time validation: Validate and apply coupons at checkout in under 100ms.
  • CRM Integration: Targeted audience segmentation and campaign triggers.
  • Event tracking: Emit events for issued, delivered, redeemed, and expired coupons.

1.2 Non-Functional

  • High Scalability: Support millions of users and thousands of redemptions per second.
  • High Availability: ≥ 99.9% uptime.
  • Security: Prevent tampering, brute-force, and replay attacks.
  • Auditability: Complete audit trails for ROI and fraud detection.

1.3 Scale Estimates

Users

100 million

Campaigns

10,000 active campaigns

Redemptions

5,000 requests/sec peak

  • Storage: Highly compressed coupon records for historical tracking (billions of rows).

1.4 API Design

The core APIs required for the service:

GET/v1/couponsGet CouponsFetch active coupons for a user.
POST/v1/campaigns/:id/issueGenerate CouponIssue a new coupon for a user.
POST/v1/coupons/redeemRedeem CouponValidate and apply a coupon.
POST/v1/eventsTrack EventLog coupon usage events.

High-Level ArchitectureArchitecture

2.1 Overview

  • Campaign Engine: Orchestrates user selection and issuance rules.
  • Coupon Generator: Creates unique codes and persists metadata.
  • Redemption API: Validates and tracks coupon state in real-time.
  • Analytics: Aggregates usage events for ROI and fraud detection.

2.2 Architecture Diagram

Architecture diagram
%%{init: {"look":"handDrawn","handDrawnSeed":7,"theme":"base","fontFamily":"Virgil, \"Segoe Print\", \"Comic Sans MS\", cursive","themeVariables":{"fontFamily":"Virgil, \"Segoe Print\", \"Comic Sans MS\", cursive","fontSize":"16px","primaryColor":"#fff4e6","primaryBorderColor":"#1e1e1e","primaryTextColor":"#1e1e1e","secondaryColor":"#e7f5ff","tertiaryColor":"#ebfbee","lineColor":"#1e1e1e","textColor":"#1e1e1e","mainBkg":"#fff4e6","nodeBorder":"#1e1e1e","clusterBkg":"#f8f9fa","edgeLabelBackground":"#ffffff","classText":"#1e1e1e"}}}%%
flowchart LR
    U["User - Web/Mobile"] -->|"GET /coupons?userId"| AG["API Gateway"]
    CD -->|"validate & update status"| DB
    AG -->|"fetchCoupons(userId)"| CD["Coupon Distribution Service"]
    AG -->|"redeemCoupon(userId)"| CD["Coupon Distribution Service"]
    CD -->|"queryAssignedCoupons(userId)"| DB[(Coupon DB)]
    CD -->|"if none → request new"| CG["Coupon Generation Service"]
    CG -->|"generateUniqueCode() + persist"| DB
    CG -->|"emitCouponCreatedEvent"| MQ[(Message Queue / Kafka)]
    CRM["CRM / Campaign Engine"] -->|"eligibility rules, personalization"| CD
    MQ -->|"analytics + targeting feedback"| CRM
    U -->|"POST /redeemCoupon {couponId}"| AG
    MQ --> NS["Notification Service"]
    NS -->|"send coupon assigned"| U
    classDef userFlow fill:#f0f8ff,stroke:#333,stroke-width:1px;
    classDef coreService fill:#e0ffe0,stroke:#333,stroke-width:1px;
    classDef asyncFlow fill:#fff0f0,stroke:#333,stroke-width:1px;
    classDef crmFlow fill:#fef7e0,stroke:#333,stroke-width:1px;
    class U,AG userFlow;
    class CD,CG,DB coreService;
    class MQ,NS asyncFlow;
    class CRM crmFlow;

Data ModelData model

coupons Table

CREATE TABLE coupons (
  id UUID PRIMARY KEY,
  code TEXT UNIQUE,
  user_id TEXT,
  campaign_id TEXT,
  discount_type TEXT,
  discount_value DECIMAL,
  expiry_date TIMESTAMP,
  usage_limit INT,
  usage_count INT DEFAULT 0,
  status    ENUM('active','used','expired'),
  created_at TIMESTAMP
);

campaigns Table

CREATE TABLE campaigns (
  id               UUID PRIMARY KEY,
  name             TEXT,
  start_date       TIMESTAMP,
  end_date         TIMESTAMP,
  target_segment   TEXT,
  delivery_channel TEXT,
  created_by       TEXT
);

FlowsFlows

  1. Coupon Issuance
  • CRM signals a new campaign
  • Campaign Engine selects target users
  • Coupon Generator issues unique codes and writes to the store
  • Notification Service delivers coupons

  1. Redemption
  • User submits code at checkout
  • Redemption API checks:
  • Existence and active status
  • Ownership (for personalized coupons)
  • Expiry and usage limit
  • On success: apply discount, update usage count

  1. CRM Feedback Loop
  • Redemption events streamed back to CRM
  • CRM updates user lifecycle and may trigger follow-up campaigns

Scale ConsiderationsScale

  • Coupon Generation
  • Use UUIDv4 or HMAC(userID + campaignID + timestamp) for uniqueness
  • Batch issuance via async workers (Kafka/RabbitMQ)
  • Data Storage
  • Shard by campaign or geographic region
  • Cache active coupons in Redis for < 100 ms lookups
  • Redemption API
  • Stateless, horizontally scalable microservice
  • JWT-based tokens to reduce DB hits
  • Delivery Pipeline
  • Asynchronous messaging with retries and dead-letter queues
  • Analytics
  • Stream all lifecycle events to a data lake (BigQuery / Snowflake)
  • Build real-time dashboards for ROI and fraud monitoring

Deep Dive Topics: Approaches, Trade-OffsDeep dive

As we drill into the heart of the system, we’ll explore two key modules—Coupon Generation & Security, and Redemption API Design—each with multiple implementation strategies, along with their pros and cons.

1. Coupon Generation & Security

Approach A: UUIDv4 Codes

Generate a random UUIDv4 for every coupon (e.g. 550e8400-e29b-41d4-a716-446655440000).

  • Pros
  • Statistically unique without external coordination
  • Easy to generate in parallel across worker pools
  • No predictable pattern, hard to brute-force
  • Cons
  • Long code length can be cumbersome for users to type
  • No embedded metadata (campaign, user) for quick lookups
  • Requires DB lookup on redemption

Approach B: Structured Codes with Embedded Metadata

Compose codes as <CAMPAIGN>–<USERHASH>–<RAND> (e.g. BDAY2023–U1234–X9Y8Z).

  • Pros
  • Self-descriptive: campaign and user segment encoded
  • Can validate prefix before hitting DB
  • Shorter, more human-friendly than full UUID
  • Cons
  • Slightly more complex generator logic
  • Metadata patterns may leak campaign details
  • Collisions risk if random segment is too short

Approach C: Signed JWT Tokens

Issue each coupon as a signed JSON Web Token containing payload fields (userId, campaignId, expiry).

  • Pros
  • Stateless validation: signature check avoids DB hit
  • Payload carries all metadata needed at redemption time
  • Expiry is built into the token (the exp claim)
  • Cons
  • Token lengths can be 200+ characters, unfriendly for manual entry
  • Requires robust key management for signing and rotation
  • Revoking a single token can be tricky without a revocation store

2. Redemption API Design

Approach A: Fully Stateless JWT Validation

Client submits a signed token; API verifies signature and expiry, applies discount.

  • Pros
  • Extremely low latency (cryptographic check only)
  • No persistent state required for validation
  • Effortless horizontal scaling
  • Cons
  • Hard to track usage count or multi-use limits without state
  • Revocation needs a secondary store lookup anyway
  • No native protection against replay unless you embed nonce logic

Approach B: Database-Driven Idempotent Transactions

On redeem, perform a single DB transaction:

  1. SELECT ... FOR UPDATE
  2. Check status/limits
  3. UPDATE usage_count or mark used
  • Pros
  • Strong consistency guarantees (ACID)
  • Easy to enforce single-use or multi-use limits
  • Built-in audit trail in redemption records
  • Cons
  • Higher latency due to DB round-trips (lock contention)
  • Scalability bottleneck if redemption volume spikes
  • Requires careful sharding or partitioning for throughput

Approach C: Hybrid Caching (Redis) + Persistent Store

  1. Cache active coupon states in Redis
  2. On redeem: Lua script atomically checks the coupon and decrements its remaining uses
  3. Durably record the redemption before confirming to the user: write it to the DB (or a replicated Kafka topic that a consumer applies to the DB). Periodic sync alone isn't enough — if Redis fails before the sync, the decrement is lost and a single-use coupon becomes usable again.
  4. On restart or failover, rebuild Redis counts from the DB (usage limit − recorded redemptions).
  • Pros
  • Sub-10 ms lookups and decrements under heavy load
  • Lua scripts provide atomic usage-count enforcement
  • Fall-back to DB on cache miss or sync lag
  • Cons
  • Increased system complexity (cache invalidation, sync jobs)
  • Risk of cache/DB divergence if not carefully orchestrated
  • Redis single-node failure can block redemptions unless clustered

Next Steps

  1. Choose your generation strategy based on user experience vs. operational simplicity.
  2. Select an API pattern that meets your latency and consistency SLAs.
  3. Prototype and load-test each approach under realistic redemption rates.

By weighing these approaches, you’ll tailor a coupon system that balances performance, usability, and security at scale.

Tradeoffs & ExtensionsTrade-offs

7.1 Tradeoffs

  • Idempotency vs. Performance: Checking for duplicate redemptions in a global distributed system can introduce significant latency. Using a fast Redis-based "first-capture" lock balances speed with strict single-use requirements.
  • Code Length vs. Security: Short codes (6-8 chars) are great for UX but vulnerable to brute-force. We mitigate this with strict rate-limiting and account-level locks.

7.2 Extensions

  • Dynamic Pricing: Integrate with a pricing engine to adjust coupon values based on real-time inventory or user behavior.
  • Referral Tracking: Expand the data model to track which user "referred" another, rewarding both upon successful coupon redemption.
  • Fraud Detection AI: Stream redemption events to a machine-learning model to detect anomalous patterns (e.g., thousands of attempts from one IP).

Wrap-UpWrap-up

The Coupon Distribution System is a critical piece of marketing infrastructure. By decoupling coupon generation from real-time redemption and leveraging a high-performance caching layer, we ensure that the system remains responsive even during the most aggressive sales events.

More Case Studies

Frequently Asked Questions

What is the Coupon Distribution System system design question?

Coupon Distribution System is a system design interview question asked at FAANG companies. It covers distributed systems,security,event driven and tests your ability to design scalable, production-ready systems. InterviewSkool's breakdown walks you through requirements, API design, architecture, and trade-offs.

Which companies ask the Coupon Distribution System question?

Companies have reportedly asked variations of this question in system design interviews. The exact wording may differ, but the core design challenges remain the same.

How should I prepare for the Coupon Distribution System interview question?

Start with the problem statement and scale estimates, then design the high-level architecture. Focus on the core components, data model, and API design. InterviewSkool's breakdown covers the full solution with mermaid diagrams and trade-off analysis to help you prep efficiently.

What level is the Coupon Distribution System question?

This question is suitable for SDE-2, SDE-3, and Staff engineer interviews. The level guidance on this page provides specific tips for each level — SDE-2 candidates should focus on core architecture, while Staff engineers should discuss trade-offs, monitoring, and incremental rollouts.

Practice with a Mock Interview

Apply what you learned in a live system design mock interview with InterviewSkool's AI interviewer.

Start System Design Interview →