Answer A: OpenAI GPT-5.2
A) API Design 1) Create short URL - Endpoint: POST /v1/urls - Request JSON: - long_url (string, required, max e.g. 8KB) - custom_alias (string, optional; if provided must be unique and pass allowed charset/length) - expire_at (timestamp, optional) - metadata (object, optional: e.g., campaign, user_id) - Response (201): - code (string) - short_url (string) - long_url (string) - created_at (timestamp) - expire_at (timestamp|null) - Errors: - 400 invalid URL/alias - 409 alias already exists - 429 rate limited 2) Resolve/redirect - Endpoint: GET /{code} - Behavior: - 301 Moved Permanently...
Show Full Answer ▼
A) API Design 1) Create short URL - Endpoint: POST /v1/urls - Request JSON: - long_url (string, required, max e.g. 8KB) - custom_alias (string, optional; if provided must be unique and pass allowed charset/length) - expire_at (timestamp, optional) - metadata (object, optional: e.g., campaign, user_id) - Response (201): - code (string) - short_url (string) - long_url (string) - created_at (timestamp) - expire_at (timestamp|null) - Errors: - 400 invalid URL/alias - 409 alias already exists - 429 rate limited 2) Resolve/redirect - Endpoint: GET /{code} - Behavior: - 301 Moved Permanently by default (or 302 if tracking/experimentation requires) - Location header = long_url - Optional: GET /v1/urls/{code} returns JSON instead of redirect (for API clients) - Errors: - 404 not found/expired 3) Delete/disable (optional, for abuse/user control) - Endpoint: DELETE /v1/urls/{code} - Auth required - Response: 204 4) Analytics (optional, can be async/approx) - Endpoint: GET /v1/urls/{code}/stats?from=&to= - Returns aggregated counters (clicks by day, referrer, geo, etc.) Notes: - Auth: API keys/OAuth for creation and management; redirects remain public. - Idempotency: support Idempotency-Key header on POST to avoid duplicates on retries. B) Data Model and Storage Workload - Writes: 100M new/month ≈ 3.33M/day ≈ 38.6 writes/sec average (higher peak). - Reads: 100:1 => 10B redirects/month ≈ 3.86K reads/sec average (peaks much higher). Storage choice - Primary store: distributed key-value / wide-column store (e.g., DynamoDB/Cassandra/ScyllaDB) optimized for very high read QPS, low latency, horizontal scaling, and multi-DC replication. - Rationale: access pattern is primarily key lookup by short code; value is small; strong need for high availability and predictable latency. - Secondary systems: - Cache: Redis/Memcached clusters per region. - Analytics pipeline: Kafka/PubSub + stream processing + OLAP store (not on critical path). Schema 1) url_mapping (primary) - Partition key: code (string) - Columns: - long_url (string) - created_at (timestamp) - expire_at (timestamp|null) - user_id (string|null) - status (active/deleted) - checksum (optional for integrity) - TTL: if expire_at set, use native TTL so expired entries auto-remove. 2) alias_reservation (optional if supporting custom aliases with uniqueness) - key: custom_alias - value: code / ownership metadata 3) idempotency (optional) - key: (user_id, idempotency_key) - value: code - TTL: e.g., 24h Storage estimate (10 years) - New URLs in 10 years: 100M/month * 12 * 10 = 12B mappings. - Per record size rough order: - code: ~8 bytes (or up to ~10 chars) - long_url: assume avg 200 bytes (conservative), plus overhead - metadata/columns/index overhead: assume ~100–200 bytes depending on store - Total effective (including replication overhead not counted yet): ~400 bytes/record (reasonable planning figure). - Raw data: 12B * 400B = 4.8TB. - With storage engine overhead + compaction + secondary indexes: plan ~2–3x => ~10–15TB. - Replication: - Within region (RF=3): ~30–45TB. - Multi-region (e.g., 2 regions active-active): double => ~60–90TB total across all regions. (These are planning numbers; exact depends on average URL length and DB overhead.) C) Short URL Generation Goals - Short as possible - Collision-free at high scale - Supports at least 10 years of growth Keyspace math - Total codes needed in 10 years: 12B. - Use Base62 charset: [0-9][a-z][A-Z] => 62 symbols. - Length L capacity: 62^L. - 62^6 ≈ 56.8B (sufficient for 12B) - 62^7 ≈ 3.52T (more headroom) Choice - Use variable length with a floor of 6 characters. - Start at 6 chars for first ~56.8B codes; that already covers 10-year requirement with significant margin (56.8B/12B ≈ 4.7x). - Keep ability to move to 7 chars in the future without breaking existing links. Generation algorithm (no collisions) Option selected: globally unique numeric IDs + Base62 encoding. - Maintain a monotonically increasing 64-bit ID space. - Encode ID in Base62 to produce the code. - Collision avoidance: none needed because IDs are unique by construction. How to generate IDs at scale - Use a distributed ID allocator similar to Snowflake, or a central “ID service” with range leasing: 1) ID service stores a counter in strongly consistent store (e.g., etcd/Spanner) per region. 2) Each app server leases an ID block (e.g., 1M IDs) to generate locally. 3) When block exhausted, request a new block. - This avoids per-write contention while ensuring uniqueness. Handling custom aliases - If custom_alias provided: - Validate charset/length - Conditional write (compare-and-set) on url_mapping with key=alias; if exists return 409. D) Scaling and Performance High-level architecture - Anycast/GeoDNS -> Global Load Balancer -> Regional L7 load balancers -> stateless API/redirect servers. - Separate services: - Write path: URL creation service - Read path: Redirect service - Shared storage + cache Scaling reads and writes independently - Redirect service scaled horizontally based on QPS/latency (likely dominant cost). - Create service scaled based on write throughput. - Use separate autoscaling groups and independent deployment pipelines. Data partitioning - Partition by code hash (or by code itself) across DB nodes. - Even distribution because codes are effectively uniform over ID space when Base62-encoded. Caching strategy - Primary: CDN/edge caching for redirects + regional in-memory cache. 1) CDN: - Cache 301/302 responses keyed by path (code) with TTL (e.g., 5–60 minutes, or respect expire_at). - For extremely hot links, CDN can absorb most traffic globally. 2) Regional cache (Redis/Memcached): - Key: code - Value: long_url + expire_at + status - TTL: min(default_ttl, expire_at-now) - Eviction: LRU or LFU (prefer LFU for skewed popularity). Expected hit rate - URL accesses are typically highly skewed (Zipf). With CDN + regional cache, 95–99% hit rate is feasible for redirects; even 90% is helpful. - Cache warming: on write, push mapping to cache; also negative caching for misses (short TTL) to reduce repeated DB hits for invalid codes. Meeting <50ms p95 redirect latency - Critical path for cached hit: - Edge/CDN hit: often <20ms. - Regional cache hit: LB + app + Redis lookup + response: typically 5–15ms within region. - For cache miss: - Single DB read from local region replica: target 5–20ms. - Keep redirect servers close to users via multi-region + edge. - Use keep-alive, HTTP/2 between components, connection pooling to Redis/DB. - Avoid synchronous analytics; emit click events asynchronously to a queue. Write performance - Writes are low compared to reads; still handle bursts. - Write flow: 1) Generate ID/code 2) Write to DB (quorum/majority within region) 3) Write-through to cache 4) Return response - Optional: dedupe identical long_url by storing a hash->code index (trade-off; see F). E) Reliability and Fault Tolerance Availability target: 99.9% - Multi-AZ within each region for all stateful components. - At least two regions active-active for redirect traffic. Replication strategy - Within region: replication factor 3 across AZs. - Cross-region: - Asynchronous replication for url_mapping to keep write latency low and availability high. - Redirects served from local region; if local mapping missing due to replication lag, fallback to another region (see below). Data center/region failure handling (graceful degradation) - Use Global Load Balancer health checks: - If a region is unhealthy, route traffic to next closest healthy region. - For redirect requests: - If regional cache/DB is degraded, redirect service can: 1) Try cache 2) Try local DB 3) If local DB unavailable, query a remote region read endpoint (with strict timeout) or use cross-region read replica. 4) If all fail, return a fast 503 with Retry-After (graceful failure). - For write requests: - Prefer local region writes; if region down, failover to another region. - ID allocation: each region has its own ID block namespace (or uses region bits in Snowflake) to avoid conflicts during failover. CAP theorem trade-off - Choose Availability over strong Consistency for global operations: - Redirects must be highly available; stale reads are acceptable briefly. - Cross-region replication is async: a newly created short URL might not resolve in a different region for a short window. Mitigations: - After creation, return a short URL hosted on same region domain (or use edge that routes to origin region for the first few minutes). - On create, optionally do a synchronous write to two regions for premium/enterprise tier (higher latency/cost). Backups and disaster recovery - Periodic snapshots + incremental backups to object storage. - Regular restore drills. F) Trade-off Discussion 1) ID-based code generation vs random tokens - Chosen: ID-based (range leased/Snowflake) + Base62. - Gains: - No collisions, no need for retry loops. - Predictable capacity planning and simpler DB constraints. - Faster writes. - Sacrifices: - Codes are guessable/sequential (security through obscurity not provided). Mitigation: - Add optional “salted permutation” (e.g., Feistel network) over the numeric ID before Base62 encoding to make codes non-sequential while preserving uniqueness. 2) Async cross-region replication (AP) vs synchronous multi-region (CP) - Chosen: async cross-region replication. - Gains: - Lower write latency, higher availability during partial failures. - Better ability to continue serving redirects even if a region is impaired. - Sacrifices: - Eventual consistency: brief window where a newly created URL may not be readable in another region. Mitigation: - Read-repair/fallback to origin region for fresh links; optional dual-write for high-SLA customers. 3) Heavy caching/CDN vs always hitting DB - Chosen: CDN + regional cache. - Gains: - Easily meets <50ms p95 and reduces DB load drastically. - Handles traffic spikes for viral links. - Sacrifices: - Cache invalidation complexity (e.g., deleted/expired links). Mitigation: - Short TTLs, respect expire_at, and explicit purge on delete for CDN where supported; use status flags and negative caching carefully.
Result
Winning Votes
3 / 3
Average Score
Total Score
Overall Comments
Answer A is a comprehensive, deeply detailed system design that covers all six sections with substantial depth. It provides precise quantitative reasoning throughout (QPS calculations, storage estimates with replication factors, cache hit rates), addresses edge cases (idempotency, negative caching, abuse handling), and offers practical engineering details like connection pooling, HTTP/2, Feistel network for code obfuscation, and write-through caching. The API design includes rate limiting, idempotency headers, and analytics endpoints. The storage estimation accounts for replication across regions. The trade-off section identifies three genuine trade-offs with clear mitigations. The reliability section provides a detailed fallback chain for degraded scenarios. Overall, it demonstrates senior-level engineering depth and practical awareness.
View Score Details ▼
Architecture Quality
Weight 30%Answer A provides a thorough architecture with explicit QPS calculations (38.6 writes/sec, 3.86K reads/sec), multi-layer caching (CDN + regional Redis/Memcached), detailed write and read paths, connection pooling, HTTP/2 optimization, async analytics via Kafka, and a well-designed ID allocation system with range leasing. The architecture choices are well-justified and connected to the constraints.
Completeness
Weight 20%Answer A covers all six sections with substantial detail. It includes additional endpoints (DELETE, analytics), idempotency support, negative caching, alias reservation schema, detailed storage estimates with replication factors across regions (60-90TB total), and three trade-offs with mitigations. The storage estimate realistically accounts for overhead and multi-region replication.
Trade-off Reasoning
Weight 20%Answer A identifies three genuine trade-offs: ID-based vs random tokens, async vs sync cross-region replication, and heavy caching vs always hitting DB. Each trade-off includes clear gains, sacrifices, and practical mitigations (Feistel network for code obfuscation, read-repair for replication lag, short TTLs for cache invalidation). The reasoning demonstrates deep understanding of engineering trade-offs.
Scalability & Reliability
Weight 20%Answer A provides a detailed fallback chain for degraded scenarios (cache -> local DB -> remote region -> 503 with Retry-After), region-aware ID allocation to avoid conflicts during failover, explicit latency breakdown for cached and uncached paths, and discusses both within-region (RF=3) and cross-region replication. The connection between caching strategy and the 50ms p95 target is explicit and convincing.
Clarity
Weight 10%Answer A is well-organized with clear section headers, sub-sections, and bullet points. The use of notes, numbered lists, and explicit labels makes it easy to follow. The quantitative reasoning is clearly presented. Some sections are dense but remain readable.
Total Score
Overall Comments
Answer A provides an outstanding, expert-level system design. It demonstrates a deep understanding of distributed systems principles by selecting a highly appropriate tech stack (distributed K-V store), providing a detailed and realistic storage calculation, and outlining a sophisticated scaling and reliability strategy that includes CDN/edge caching, multi-region active-active deployment, and a clear graceful degradation path. The API design is comprehensive, and the trade-off discussion is nuanced and insightful. The level of detail across all sections is exceptional.
View Score Details ▼
Architecture Quality
Weight 30%The architecture is exceptionally well-suited for the problem. The choice of a distributed key-value store like DynamoDB/Cassandra is ideal for the high-read, key-lookup workload. The overall design, from Anycast/GeoDNS down to the separated read/write services, is robust, scalable, and demonstrates expert-level thinking.
Completeness
Weight 20%The answer is extremely complete, addressing all six sections in great detail. The API design is particularly thorough, including optional but important endpoints for analytics and deletion, as well as considerations for idempotency and authentication.
Trade-off Reasoning
Weight 20%The answer provides three distinct and highly relevant trade-offs. The reasoning is excellent, clearly outlining what is gained and sacrificed, and importantly, includes practical mitigations for the downsides of each choice. This demonstrates a mature understanding of engineering trade-offs.
Scalability & Reliability
Weight 20%This is an outstanding section. The plan for scaling reads and writes independently is clear. The caching strategy is multi-layered (CDN + regional cache), which is critical for meeting the latency target at a global scale. The reliability plan is also excellent, with a detailed graceful degradation path and a clear, well-mitigated AP choice in the CAP theorem.
Clarity
Weight 10%The answer is exceptionally clear and well-structured. It follows the requested A-F format perfectly, using headings, sub-bullets, and concise language to present complex ideas in an easy-to-digest manner.
Total Score
Overall Comments
Answer A is a strong, well-structured system design that covers all required sections A through F with concrete APIs, a realistic data model, quantitative capacity estimates, and a practical architecture for caching, multi-region failover, and latency control. It ties choices directly to the workload, includes operational details like idempotency, negative caching, CDN behavior, quorum/range-leased ID generation, and graceful degradation paths. Minor weaknesses are that some estimates are still coarse and a few implementation choices are presented as options rather than a single sharply committed design.
View Score Details ▼
Architecture Quality
Weight 30%Uses a coherent end-to-end architecture matched to the workload: stateless read/write services, distributed KV store, regional caches plus CDN, async analytics, multi-region routing, and a concrete ID-generation strategy. The design shows good separation of concerns and practical implementation details.
Completeness
Weight 20%Addresses all six required sections substantively and adds useful details such as auth, idempotency, optional analytics, alias reservation, backup strategy, and graceful-degradation steps. Quantitative reasoning is included in multiple sections.
Trade-off Reasoning
Weight 20%Identifies multiple meaningful trade-offs with explicit gains, sacrifices, and mitigations, including ID-based generation vs random tokens, async replication vs synchronous replication, and caching complexity vs latency. The reasoning is tied to the workload and SLA requirements.
Scalability & Reliability
Weight 20%Strong treatment of horizontal scaling, partitioning, read/write separation, expected cache hit rates, CDN support, p95 latency path, RF=3, multi-AZ and active-active regional setup, async cross-region replication, and fallback behavior during regional outages. Explicitly addresses graceful degradation with concrete request flow.
Clarity
Weight 10%Very readable, logically organized by A-F, and easy to follow. The use of bullets, formulas, and stepwise flows helps comprehension, though the answer is somewhat dense.