EasyStarter

QR Code Generator API

API DesignCachingCDN

Problem Statement

QRFactory is building a QR code API service. Features:

- Generate QR codes - accept a URL, plain text, vCard, WiFi config, or email address and return a QR code image (PNG/SVG) via REST API.Customization - set colors, size, logo overlay in the center, and error correction level.Dynamic QR codes - the QR code points to a redirect URL that can be changed after printing. Track scan analytics.Batch generation - upload a CSV of 1,000 URLs and receive a ZIP of QR code images.Scan analytics - for dynamic codes, track scan count, time, location, and device.

Targeting 50,000 API calls per day generating 100,000 QR codes per day.

What You'll Learn

Design a QR code generation API that creates, stores, and tracks QR codes for URLs, text, and contact cards. Build this architecture under realistic production constraints, then validate tradeoffs in the design lab simulation.

API DesignCachingCDN

Constraints

API calls/day~50,000
QR codes generated/day~100,000
Generation latency< 500 ms
Image sizes100×100 to 2000×2000 px
Dynamic codes tracked~500,000 total
Availability target99.5%
ApproachClick to expand

Interview-Ready Approach

1) Clarify Scope and SLOs

  • Problem statement: Design a QR code generation API that creates, stores, and tracks QR codes for URLs, text, and contact cards.
  • Design for a peak load target around 100 RPS (including burst headroom).
  • API calls/day: ~50,000
  • QR codes generated/day: ~100,000
  • Generation latency: < 500 ms
  • Image sizes: 100×100 to 2000×2000 px
  • Dynamic codes tracked: ~500,000 total

2) Capacity Planning Method

  • Convert traffic and growth constraints into request rate, storage growth, and concurrency budgets.
  • Keep at least 2-3x safety margin per tier (ingress, compute, storage, async workers).
  • Reserve explicit latency budgets per hop so p95 can be defended in review.

3) Architecture Decisions

  • API Design: Standardize API boundaries, idempotency keys, pagination, and error contracts first.
  • Caching: Put cache on hot read paths first and pick cache-aside or write-through explicitly.
  • CDN: Serve static and cacheable content from edge and keep origin strictly for misses and dynamic requests.

4) Reliability and Failure Strategy

  • Apply strict input validation and backward-compatible versioning.
  • Bound staleness with TTL + invalidation hooks for critical entities.
  • Define cache keys and purge workflows before launch to avoid stale/global outages.

5) Validation Plan

  • Run one peak-load test, one dependency-degradation test, and one failover test.
  • Verify idempotency for all retried writes and async consumers.
  • Track user-facing SLOs first: p95 latency, error rate, and successful throughput.

6) Trade-offs to Call Out in Interviews

  • API Design: Rich APIs improve developer speed but can create long-term compatibility burden.
  • Caching: Higher hit rate cuts latency/cost, but stale data and invalidation bugs become primary risks.
  • CDN: Long TTL improves latency/cost; short TTL improves freshness.

Practical Notes

  • QR code generation is CPU-bound but fast - a single server can generate hundreds per second. Horizontally scale with a load balancer.
  • Cache generated images by a hash of the input parameters - same request = same QR code, no regeneration needed.
  • Dynamic QR codes: the QR encodes a redirect URL (e.g., qr.factory/abc123). You control the redirect target in the database.

Learn the Concept

Practice Next

Reference SolutionClick to reveal

Why This Solution Works

Request path: The solution keeps ingress, service logic, and stateful dependencies separated so each layer can scale independently.

Reference flow: Web Clients -> DNS -> CDN Edge -> API Gateway -> API Service -> Redis Cache -> Primary SQL DB

Design strengths

  • Cache sits on the read path to absorb repeated queries and keep DB pressure stable.

Interview defense

  • This design makes bottlenecks explicit (ingress, core compute, persistence, async workers).
  • It supports progressive scaling without re-architecting the core request path.
  • It keeps correctness-sensitive state changes in durable systems while offloading background work asynchronously.