Answer A: Anthropic Claude Sonnet 4.6
URL Shortening Service — High-Level Design FUNCTIONAL REQUIREMENTS Users can submit a long URL and receive a unique short code (e.g., https://short.ly/aB3xYz). Visiting the short URL redirects the browser to the original destination. Short links optionally expire after a configurable TTL. Users may optionally request a custom alias. A basic click counter is maintained per link. NON-FUNCTIONAL REQUIREMENTS The system must handle roughly 20 million writes and 200 million reads per month, translating to about 8 writes/second and 80 reads/second on average, with peaks several times higher. Redirect latency should b...
Show Full Answer ▼
URL Shortening Service — High-Level Design FUNCTIONAL REQUIREMENTS Users can submit a long URL and receive a unique short code (e.g., https://short.ly/aB3xYz). Visiting the short URL redirects the browser to the original destination. Short links optionally expire after a configurable TTL. Users may optionally request a custom alias. A basic click counter is maintained per link. NON-FUNCTIONAL REQUIREMENTS The system must handle roughly 20 million writes and 200 million reads per month, translating to about 8 writes/second and 80 reads/second on average, with peaks several times higher. Redirect latency should be under 50 ms at the 95th percentile. The service must be highly available (target 99.9% uptime). Short codes must be globally unique. The system should be horizontally scalable and tolerate single-node failures gracefully. API ENDPOINTS POST /api/links accepts a JSON body with fields: longUrl (required), customAlias (optional), ttlDays (optional). It returns a JSON response containing shortCode and shortUrl. This is the write path. GET /{shortCode} is the redirect endpoint. The server looks up the code and responds with HTTP 301 (permanent) or 302 (temporary, preferred for analytics) to the original URL. GET /api/links/{shortCode} returns metadata: original URL, creation time, expiry, click count. DELETE /api/links/{shortCode} marks a link as deleted (soft delete). DATA MODEL A single primary table, links, holds the core data. Key columns: short_code (varchar, primary key), long_url (text, not null), created_at (timestamp), expires_at (timestamp, nullable), is_deleted (boolean, default false), click_count (integer, default 0), owner_id (varchar, nullable for anonymous links). An index on expires_at supports efficient expiry sweeps. If custom aliases are supported, short_code is simply set to the user-supplied value after a uniqueness check. SHORT CODE GENERATION The default approach uses a base-62 encoding (characters a-z, A-Z, 0-9) of a unique integer ID. A 7-character base-62 code gives 62^7 ≈ 3.5 trillion possible codes, far exceeding foreseeable demand. The integer ID is produced by a distributed ID generator such as a Snowflake-style service or a database sequence. This guarantees uniqueness without coordination overhead at the application layer. On write, the application encodes the generated ID to produce the short code and stores both. For custom aliases, the application checks for an existing row with that short_code before inserting; if taken, it returns a conflict error to the caller. READ AND WRITE FLOW Write path: The client POSTs to the API service. The service validates the URL (basic format check, optional blocklist check). It obtains a new unique ID from the ID generator, encodes it to a short code, and inserts a row into the primary database. The new mapping is optionally pre-warmed into the cache. The short URL is returned to the client. Read path: The client issues GET /{shortCode}. The API service first checks the distributed cache (Redis). On a cache hit, it returns the 302 redirect immediately and asynchronously increments the click counter. On a cache miss, it queries the primary database, writes the result to the cache with a TTL (e.g., 24 hours), then redirects. If the code is not found, expired, or deleted, it returns 404. STORAGE AND CACHING Primary storage is a relational database (PostgreSQL or MySQL) for its strong consistency, ACID guarantees, and straightforward unique-key enforcement. At 20 million links per month and a modest row size (~500 bytes), one year of data is roughly 120 GB — easily manageable on a single primary with read replicas. A distributed in-memory cache (Redis) sits in front of the database for the read path. Given that a small fraction of links account for most traffic (power-law distribution), a cache with an LRU eviction policy and a 24-hour TTL will achieve a high hit rate with modest memory. Estimating 10 million hot links at ~200 bytes each requires only about 2 GB of cache memory. Click counts are buffered in Redis (INCR) and flushed to the database periodically to avoid write amplification. SCALING FOR HEAVY READ TRAFFIC The API tier is stateless and scales horizontally behind a load balancer. Read replicas of the database absorb read queries that miss the cache. The cache cluster (Redis Cluster) can be sharded by short_code. A CDN can be placed in front of the redirect endpoint for the most popular links, serving the 302 response from edge nodes without hitting the origin at all. Because 302 responses are not cached by browsers by default, the CDN must be configured to cache them for a short duration (e.g., 60 seconds) to be effective. HANDLING EXPIRED OR DELETED LINKS Expiry is checked at read time: if expires_at is in the past or is_deleted is true, the service returns 404 and removes the entry from the cache. A background job runs periodically (e.g., nightly) to hard-delete or archive rows where expires_at has passed, keeping the active dataset small and index scans fast. Soft deletes (is_deleted flag) allow for audit trails and potential recovery before permanent removal. ABUSE PREVENTION AND RATE LIMITING Rate limiting is enforced at the API gateway layer using a token bucket or sliding window algorithm keyed on IP address and, for authenticated users, on user ID. Reasonable defaults: 10 writes per minute per IP for anonymous users, higher limits for authenticated accounts. On the write path, submitted URLs are checked against a blocklist of known malicious or phishing domains (maintained as a Redis set or a small in-memory trie). CAPTCHA or email verification can be required for bulk or suspicious submission patterns. Short codes that receive an unusual spike of 404 responses (e.g., enumeration attacks) can trigger temporary IP blocks. RELIABILITY AND BOTTLENECKS The primary database is the most critical single point of failure. Mitigation: synchronous replication to at least one standby with automatic failover (e.g., using a tool like Patroni). The cache layer improves availability by serving reads even during brief database degradation. The ID generator must itself be highly available; a Snowflake-style generator embedded in each API node (using node ID + timestamp + sequence) eliminates this as a separate dependency. Likely bottlenecks: the database write path during traffic spikes (mitigated by connection pooling and write batching where possible), and cache eviction under a sudden surge of unique short codes (mitigated by pre-warming popular links and tuning cache size). TRADE-OFFS AND ASSUMPTIONS Using 302 (temporary) redirects instead of 301 (permanent) means browsers do not cache the redirect, so every visit hits the service. This is intentional: it enables accurate click counting and allows links to be updated or deleted. The trade-off is slightly higher latency and load compared to 301. Base-62 encoding of a sequential ID leaks approximate creation order; if that is a concern, the ID can be hashed or a random code can be generated with a uniqueness check (retry on collision). The design assumes anonymous link creation is allowed; adding authentication would improve abuse control but reduces accessibility. Click counts use eventual consistency (buffered in Redis, flushed asynchronously) rather than strict transactional increments, accepting minor inaccuracies in exchange for much lower write load on the database. Custom aliases are supported but treated as a minority use case; they do not affect the core generation pipeline.
Result
Winning Votes
3 / 3
Average Score
Total Score
Overall Comments
The design for the URL shortening service is exceptionally well-structured, comprehensive, and practical. It addresses all aspects of the prompt with a good level of detail, making concrete choices and justifying them effectively. Strengths include a robust data model, a well-thought-out short code generation strategy, a comprehensive scaling plan for read-heavy traffic, and a strong discussion of tradeoffs, particularly regarding 301 vs 302 redirects and click count consistency. The answer identifies potential bottlenecks and proposes realistic mitigation strategies, demonstrating a solid understanding of system design principles for high-traffic services. There are no significant weaknesses; the design is ready for implementation discussions at a high level.
View Score Details ▼
Architecture Quality
Weight 30%The proposed architecture is highly coherent and well-suited for the specified workload. It clearly outlines key components such as a stateless API tier, a distributed ID generator, a relational database with read replicas, a distributed cache (Redis), and a CDN. The logical separation and interaction between these components are well-explained, demonstrating a strong architectural foundation that addresses both functional and non-functional requirements efficiently.
Completeness
Weight 20%The answer is exceptionally complete, covering every single item requested in the prompt with thorough detail. From core and non-functional requirements to API endpoints, data model, short code generation, read/write flows, storage, caching, scaling, link management, abuse prevention, reliability, and explicit tradeoffs/assumptions – all are addressed comprehensively and articulately. The inclusion of specific metrics and reasonable estimates further strengthens its completeness.
Trade-off Reasoning
Weight 20%The answer provides excellent reasoning for important design tradeoffs. The explicit discussion of 302 vs 301 redirects, the implications of sequential ID generation, the choice of strong consistency for the primary database, and the eventual consistency for click counts are all well-justified. These explanations demonstrate a deep understanding of the practical consequences of design choices in a real-world system.
Scalability & Reliability
Weight 20%The design presents a robust approach to scalability and reliability. It effectively addresses heavy read traffic through a stateless API, read replicas, sharded caching (Redis Cluster), and CDN integration. For reliability, it considers database SPOF mitigation (replication, failover), cache layer resilience, and the high availability of the ID generator. The identification of likely bottlenecks and proposed mitigations showcases a proactive approach to maintaining performance and uptime under load.
Clarity
Weight 10%The answer is exceptionally clear, well-organized, and easy to follow. It uses distinct headings for each section, aligning perfectly with the prompt's structure. The language is precise, professional, and avoids jargon where possible, making the complex technical design accessible. The depth of detail is appropriate for a high-level design, concrete enough to be practical without getting bogged down in implementation specifics.
Total Score
Overall Comments
Coherent, implementable design with clear API, data model, code-generation strategy, and solid read-heavy scaling via cache/CDN and stateless services. It addresses expiration/deletion, basic abuse controls, and identifies key bottlenecks. Some areas are a bit optimistic or under-specified (e.g., CDN caching of redirects, consistency/semantics of 404 vs 410, detailed cache invalidation patterns, multi-region considerations, and write scaling beyond a single primary), but overall it matches the workload well and includes sensible trade-offs.
View Score Details ▼
Architecture Quality
Weight 30%Presents a clean architecture: stateless API tier, Redis cache in front of an RDBMS, optional read replicas, async click counting, background expiry cleanup, and optional CDN. Components and responsibilities are well separated and flows are plausible. A few design points are slightly shaky (redirect caching behavior at CDN/browsers, and relying on a single primary as the long-term baseline), but overall it is strong.
Completeness
Weight 20%Covers all requested items: functional/non-functional requirements, endpoints, schema, uniqueness approach, read/write flows, storage+caching, scaling for read-heavy traffic, expiry/deletion, abuse/rate limiting, reliability/bottlenecks, and trade-offs/assumptions. Minor gaps: limited discussion of alias normalization/reserved words, link update semantics (if allowed), and clearer behavior for expired/deleted (404 vs 410) and cache invalidation.
Trade-off Reasoning
Weight 20%Good discussion of 301 vs 302, sequential ID leakage vs hashing/random, and eventual consistency for click counts. Notes pros/cons of RDBMS and caching choices. Could go deeper on SQL vs NoSQL at this scale, replica lag implications, and operational trade-offs of CDN caching and cache TTL choices, but the main trade-offs are acknowledged and justified.
Scalability & Reliability
Weight 20%Reasonable scaling plan for read-dominant workload: cache, replicas, sharded Redis, horizontal API scaling, optional CDN, and buffered counters to reduce DB writes. Reliability mentions failover and removal of a central ID service dependency. Missing/limited: multi-region strategy, DR/backups, handling cache outages (fallback behavior), and more concrete capacity/partitioning strategy if data grows beyond a single primary comfortably.
Clarity
Weight 10%Well structured with headings, concrete endpoint shapes, clear data fields, and step-by-step read/write flows. Assumptions and numbers are easy to follow. A couple of statements could be clearer or more accurate (notably around caching 302 redirects), but overall readability is high.
Total Score
Overall Comments
This is a very strong, well-structured system design answer that covers all the required topics with appropriate depth. It correctly estimates the workload (8 writes/s, 80 reads/s average), proposes a coherent architecture with stateless API nodes, a relational database, Redis caching, and a distributed ID generator. The answer addresses all twelve bullet points from the prompt: functional requirements, non-functional requirements, API endpoints, data model, short code generation, read/write flows, storage and caching, scaling, expiration/deletion, abuse prevention, reliability, and trade-offs. Trade-off reasoning is thoughtful and concrete — for example, the 302 vs 301 discussion, sequential vs random codes, eventual consistency for click counts, and the CDN caching nuance for 302 responses. The scaling approach is realistic and well-matched to the workload. Minor weaknesses: the answer could have discussed NoSQL as an alternative storage option more explicitly (it only mentions relational), the CDN discussion for 302 responses could have been expanded slightly, and the discussion of database partitioning/sharding for future growth beyond a single primary is absent. The abuse prevention section is solid but could mention URL scanning services or safe browsing APIs. Overall, this is a high-quality answer that would be implementable and demonstrates strong system design thinking.
View Score Details ▼
Architecture Quality
Weight 30%The architecture is coherent and well-suited to the workload. Stateless API tier, relational DB with read replicas, Redis cache, Snowflake-style ID generation, and optional CDN form a sensible stack. The read and write flows are clearly separated and logical. The choice to embed the ID generator in API nodes is a good design decision that eliminates a separate dependency. Minor gap: no discussion of database sharding for future growth beyond a single primary, and no explicit consideration of NoSQL alternatives in the architecture.
Completeness
Weight 20%The answer covers all twelve bullet points requested in the prompt thoroughly. Functional and non-functional requirements are clearly stated, API endpoints are well-defined with HTTP methods and response codes, the data model includes sensible fields and indexes, short code generation is explained with capacity math, both read and write flows are detailed, storage and caching are quantified, scaling is addressed, expiration and deletion are handled at both read time and via background jobs, abuse prevention includes rate limiting and blocklists, reliability considerations identify the main SPOF and mitigations, and trade-offs are explicitly discussed. Custom aliases are addressed. Very little is missing.
Trade-off Reasoning
Weight 20%Trade-off reasoning is a notable strength. The 302 vs 301 discussion is well-articulated with clear rationale. The sequential vs random code generation trade-off is mentioned with a practical mitigation (hashing). Eventual consistency for click counts is justified with a clear cost-benefit analysis. The CDN caching nuance for 302 responses shows depth of understanding. Could have been stronger with an explicit SQL vs NoSQL trade-off discussion and more on the trade-offs of different caching TTL strategies.
Scalability & Reliability
Weight 20%Scaling approach is realistic: horizontal API scaling, read replicas, Redis Cluster sharding, and CDN at the edge. The workload math is correct and the cache sizing estimate is reasonable. Reliability is addressed with synchronous replication, automatic failover, and the embedded ID generator design. Bottlenecks are identified (DB write path, cache eviction). However, the answer does not discuss database sharding or partitioning strategies for when the dataset grows significantly beyond a single primary's capacity, and geographic distribution or multi-region deployment is not mentioned.
Clarity
Weight 10%The answer is exceptionally well-organized with clear section headers that map directly to the prompt's requirements. Each section is concise yet substantive. Technical terms are used correctly and consistently. The writing is professional and easy to follow. The flow from requirements through architecture to trade-offs is logical. No unnecessary verbosity or tangential content.