Reviewed by 6 specialized AI reviewers. Explore the diagram and the full per-section feedback below.
Loading diagram…
The candidate demonstrates awareness of the main components and core flows, but the design lacks the precision, end-to-end clarity, and scalability depth expected at senior level. The most concerning issue is that the primary read/redirect path is not modeled clearly enough, and several supporting areas (NFRs, entity modeling, API completeness, and capacity-to-infra mapping) remain only partially thought through.
NFRs are listed but not made measurable enough
The section mentions availability, latency, scalability, durability, fault tolerance, and uniqueness, which is a reasonable start, but most of them are not quantified. For a senior-level answer, availability should be expressed as an SLA/SLO (for example 99.9% or 99.99%), latency should specify percentile and scope (for example p95 or p99 for redirect vs create-short-URL APIs), and durability should be stated with a target. Add concrete targets so the design can be evaluated objectively.
Consistency model is not defined
The answer does not state whether the system requires strong or eventual consistency for URL creation, uniqueness enforcement, and reads after writes. This matters because uniqueness of short URLs usually needs strong guarantees at write time, while analytics or replicas may tolerate eventual consistency. Explicitly call out which operations require strong consistency and which can be eventually consistent.
Numbers are not tied to workload assumptions
The latency target is given, but there are no assumptions about traffic volume, read/write ratio, peak QPS, storage growth, or regional distribution. At senior level, NFRs should be justified against expected scale so it is clear whether the targets are realistic. Tie the <100 ms and <1 second goals to expected request rates and peak load assumptions.
Availability requirement is too vague
Saying the system 'cannot afford down-time' is directionally correct but not actionable. No real system has absolute zero downtime, so this should be translated into a concrete uptime target and failure expectations, such as tolerated maintenance windows, RTO, and RPO. That makes the requirement implementable and testable.
Latency target needs endpoint-level clarity
The statement 'API Latency should be <100 ms, Turn around time can be <1 second' is ambiguous. In a URL shortener, redirect/read traffic and short-URL creation traffic often have different latency expectations. Clarify which APIs must meet <100 ms, whether this is average or tail latency, and what 'turn around time' refers to.
Scalability is stated without a success criterion
Saying the system should be scalable is too generic for senior-level NFRs. Define what scaling means in practice: expected growth in URLs stored, peak requests per second, and whether the system should scale horizontally without downtime. This turns scalability from a vague goal into an evaluable requirement.
Relationships between entities are not defined
The entities are listed, but the design does not state how they relate to each other. For a senior-level core-entities section, you should explicitly define relationships such as whether one User can own many URLMetaData records and whether each URLMetaData belongs to exactly one User or can exist anonymously.
Core flow entity coverage is too thin
For a URL shortening domain, User and URLMetaData cover part of the model, but the core flow is underspecified at the entity level. If the functional requirements include creating and resolving shortened URLs, the shortened URL itself should be represented clearly as a first-class domain concept rather than being implied inside URLMetaData. Add an explicit ShortURL/Link entity or clearly redefine URLMetaData as the canonical shortened-link entity.
Entity naming mixes concept and attributes
URLMetaData is a vague container-style name, and the parenthetical list includes fields rather than additional entities or relationships. At this level, prefer clear domain nouns like User and ShortURL/Link, then describe how they relate. This makes the model easier to reason about and shows stronger domain decomposition.
Core traffic and storage estimates are present
The design includes baseline write QPS, read QPS from the stated read:write ratio, and monthly/yearly storage estimates. This covers the minimum capacity inputs needed to reason about scale.
Numbers are in a reasonable ballpark
For 100M URLs per month, estimating roughly 40 writes/sec and 400 reads/sec is directionally correct, and 1 KB per record leading to about 100 GB/month is a plausible first-order storage estimate.
Calculations stop at averages and ignore peak load
Using only monthly averages understates required capacity. Real systems need peak QPS assumptions (for example 2x-10x average, plus diurnal traffic skew) to size app servers, databases, caches, and network links. Add peak write/read QPS and design against those numbers, not just the average 40/400 QPS.
Capacity model is not methodical end-to-end
The section goes from monthly volume to average QPS and storage, but does not continue into bandwidth, cache hit assumptions, replication overhead, index/storage amplification, or growth over retention. For a senior-level answer, extend the chain from traffic to storage and network: request size x QPS, response size x QPS, DB replication factor, index overhead, and backup requirements.
No linkage from numbers to infrastructure sizing
The calculations are not tied back to whether the proposed high-level design can handle the load. Senior-level capacity work should explicitly map 400 read QPS / 40 write QPS (and peak values) to expected database capacity, cache need, shard count if any, and whether a single primary with replicas is sufficient.
Storage estimate likely excludes operational overhead
The 1 KB per URL record is acceptable as a rough estimate, but actual storage is usually higher once indexes, replication, tombstones/deletes, backups, and analytics/event logs are included. Call out whether 1 KB is raw logical data only, then add an overhead multiplier for a more realistic total.
Core create and redirect flows are covered
The API includes the two essential routes for a URL shortener: creating a short URL via POST /shorten and resolving a short code via GET /{shortened_url}. That maps directly to the primary functional behavior.
Appropriate redirect semantics on lookup
Using HTTP redirect responses (301 or 302) for short URL resolution is the correct REST-friendly behavior for this use case, since clients can follow the redirect directly to the original URL.
Conflict handling for custom aliases is considered
Returning 409 Conflict when a requested custom alias is already taken is a solid API design choice because it clearly communicates a resource naming collision and gives clients a deterministic failure mode.
URL design is not resource-oriented
The create endpoint uses an action-style path (/shorten) rather than a resource-oriented REST design. For a senior-level API, model shortened links as a resource, e.g. POST /urls or POST /links, and return the created short-link resource including its id/code and metadata.
CRUD coverage for the primary resource is incomplete
Only create and redirect are defined. If the shortened URL is the primary entity and expiration/custom alias are part of its lifecycle, the API should also define at least a retrieval endpoint for metadata (e.g. GET /urls/{code}) and, if supported by the requirements, update/delete semantics. Without this, the resource model is only partially exposed.
HTTP status codes for creation are not ideal
POST /shorten returns 200, but resource creation should typically return 201 Created, ideally with a Location header pointing to the created resource. This makes the API more standard and easier for clients to integrate with.
Redirect behavior is underspecified
The design says 301 or 302 but does not define when each is used. That ambiguity can cause inconsistent client and cache behavior. Specify a clear rule, such as 302/307 for normal redirects if destinations may change, or 301/308 only when permanence is guaranteed.
Error handling is too narrow
Only the 409 alias-conflict case is defined. A robust REST API should also specify common failure responses such as 400 for invalid URL or malformed request body, 404 when a short code does not exist, and 410 if an expired link is accessed. Define a consistent error response schema with code/message fields.
Request and response schema needs tighter API conventions
Field names like OriginalUrl and Shortend_url are inconsistent and contain spelling/casing issues. Use a consistent JSON convention such as originalUrl, customAlias, expiresAt, and shortUrl. Clear, stable naming improves client usability and reduces integration mistakes.
Read and write paths are separated
Splitting URL creation into a write service and using separate read replicas for lookup is a solid high-level pattern for a URL shortener. It aligns the architecture with the typical read-heavy access pattern and gives a reasonable path to scale reads independently from writes.
Cache is included in the lookup path
Using Redis in front of persistent storage is an appropriate choice for hot short-URL lookups. This can significantly reduce database load and improve redirect latency for frequently accessed links.
Database-enforced uniqueness is acknowledged
Relying on the database to enforce uniqueness for short codes and retrying on collision is a practical safety mechanism. It avoids trusting only application-side checks for correctness under concurrent writes.
Read path is logically incorrect for redirects
The diagram routes API Gateway directly to read replicas, but the read replicas are modeled as services rather than actual database replicas, and there is no clear end-to-end redirect flow from short code to original URL. For a working design, the request should go from gateway to a URL lookup service, which checks Redis, falls back to the database, and returns the original URL or redirect response. As drawn, the data flow is ambiguous and does not clearly satisfy the core read requirement.
Cache ownership and access pattern are inconsistent
Both the read replicas and write service talk to Redis, but the responsibilities are unclear. The note says Redis is used to check custom alias uniqueness, while the read path also appears to depend on it. This creates confusion about whether Redis is a read-through cache, write-through cache, or just a temporary uniqueness check. Define a clear pattern: for example, lookup service checks Redis first for shortCode->originalUrl, falls back to DB on miss, and write service populates or invalidates cache after successful writes.
No clear redundancy beyond generic replication labels
The design mentions write replicas and read replicas, but it does not show how the API Gateway, Redis, or primary data store avoid single points of failure. At senior level, basic HA should be explicit: multiple stateless service instances behind the gateway, Redis with replication/sentinel or managed HA, and a database deployment with failover. Without that, the system has obvious availability gaps.
Scalability strategy is only partial
Read scaling is implied, but write scaling is not well thought through. URL generation depends on DB uniqueness checks and retrying collisions, which can become expensive under higher write concurrency. A stronger design would explain partitioning strategy or a more deterministic ID generation approach so writes do not bottleneck on repeated collision handling.
No async path for non-critical heavy work
The core shorten and redirect flows can be synchronous, so this is not a functional blocker. However, if expiration cleanup, analytics, or link deactivation propagation are expected operationally, introducing a background worker or queue would keep the online path lean and avoid overloading the main service with maintenance tasks.
Database choice is underspecified relative to topology
The design lists 'Mongo or Dynamo' interchangeably, but the replication and read-replica model differs significantly between them. DynamoDB does not map cleanly to traditional read replicas in the same way Mongo does. Pick one datastore and align the architecture to its actual scaling and redundancy model.
Draw your architecture for URL Shortener and get an instant hire/no-hire signal from 6 specialized AI reviewers — free to start.