Suppose an interviewer asks you to design a URL shortener. You could fill the board with a load balancer, cache, queue, analytics service, and several databases before anyone has agreed on what the system must do. The harder move is to draw less: make one useful request path visible, then change the drawing as the requirements become clearer.
This is a construction exercise for a fictional service, not a prescribed architecture. The exact boxes matter less than whether another person can follow a request and see which decisions remain open.
Set the boundary before choosing boxes
Start by repeating the task in operational terms. In this example, a user submits a long URL and receives a short URL. A visitor opens that short URL and gets redirected to the stored destination. Ask whether custom aliases, accounts, expiration, analytics, and deletion matter now. For this first drawing, assume they do not. We will revisit expiration shortly.
Then draw a boundary around the service you are designing. Put the user who creates a link and the visitor who follows one outside it. Treat the browser as the client for both. The destination website is also outside your service. This keeps a redirect from looking like your server fetches the destination page on the visitor's behalf.
Creator's browser → [ URL shortener ]
Visitor's browser → [ URL shortener ]
Visitor's browser ← redirect response
Visitor's browser → Destination website
These arrows are intentionally broad. The creator's request means "create a mapping." The visitor requests a short link, receives a redirect response, then navigates to the destination. You can say that while drawing rather than spending time on a perfect legend.
The Software Engineering Institute's book record for Documenting Software Architectures: Views and Beyond describes choosing what information to document and using views to communicate an architecture. That is guidance for focusing this drawing on a reader and a question. It is not evidence that a particular drawing method improves interview outcomes.
Draw the redirect path first
The visitor path gives the diagram a clear question: what happens after someone opens a short URL? Replace the broad service box with a redirect service and a store of code-to-destination mappings. For now, assume one logical store and no traffic or latency target. "Logical" matters here: the drawing does not claim there is one physical database machine.
Visitor's browser
│ GET /abc123
▼
Redirect service ── lookup code abc123 ──→ Mapping store
▲ │
└──────── destination URL ─────────┘
│ 3xx response with Location header
▼
Visitor's browser ── new request ──→ Destination website
Walk that path aloud. The service extracts the code, looks up its destination, and returns a redirect response containing that destination in the Location header. The browser then requests the destination website. If the code has no mapping, the service needs an error response; do not quietly draw a successful arrow for every lookup.
Notice what the labels do. "Lookup code" tells the reader why the store is involved. "Destination URL" tells them what comes back. "3xx response" distinguishes a redirect from proxying the website's content. If you cannot explain an arrow in a short phrase, the arrow may be hiding a decision.
Add creation only when its relationship is clear
Now account for the creator. The browser submits a destination URL; a link creation service chooses an available short code and writes the mapping. It returns the short URL to the creator. On a small diagram, creation and redirect may sit in one API box if you explain the two operations. Here they are separate labels because their responsibilities differ, not because they must be separate deployments.
Creator's browser ── submit URL ──→ Link creation service
Creator's browser ←── short URL ─── Link creation service
│ write code → destination
▼
Mapping store
▲ lookup code
│
Visitor's browser ── GET /code ──→ Redirect service
Visitor's browser ←── redirect ─── Redirect service
The code must identify one mapping. The diagram does not yet decide whether codes are random, sequential, or derived from a hash. It also leaves open how concurrent requests avoid assigning the same code. Mark that beside the write arrow if the conversation turns to it; adding a "code generator" box without explaining uniqueness would only make the drawing busier.
At this point, trace both operations against the assumptions. Can the creator retrieve the short URL after a write? Can a visitor follow it? What does an unknown code produce? If those answers are visible or stated, the first useful view is complete. Capacity planning, authentication, abuse controls, and monitoring may matter in a real service, but none has been specified here. Name them as open questions instead of silently implying they are solved.
Revise for an expiring link
Now the interviewer adds a requirement: creators may choose an expiration time. A redirect decision made at or after that time must reject the link. This is a change to the request path, not just an extra field in a box.
First, change the stored mapping from code → destination to code → destination, expiresAt. The creation path accepts an expiration time and writes it with the destination. On the redirect path, the service compares expiresAt with server time after the lookup and before deciding whether to return a redirect. A missing or expired mapping takes an explicit error path. You can revise the earlier drawing in place:
Creator ── URL + expiration ──→ Link creation service
│ write code, destination, expiresAt
▼
Mapping store
│ mapping or missing
▼
Visitor ── GET /code ───────→ Redirect service
Visitor ←── redirect ──────── if mapping exists and is unexpired at decision time
Visitor ←── error page ────── if missing or expired
This revision exposes a real choice. Checking the expiration on each lookup does not require a cleanup job to make later redirect decisions reject an expired link, although old records may remain until a separate process removes them. A response approved just before the boundary may finish just after it; the decision time, not the response arrival time, defines the rule in this example. Deleting expired records in the background alone cannot enforce that boundary. The response for expired and unknown codes also needs a product decision; the diagram should show the branch without pretending that choice has been made.
If the conversation later calls for a cache, place it on the lookup path. A cache hit must still be checked against expiresAt at the redirect decision, so a cached destination cannot extend the link's validity. A cache box added before that rule can make the revised drawing less accurate. The order of construction matters because each new requirement tells you which relationship to inspect.
Use the drawing as a conversation
During the interview, point to the path you are discussing. A box should name a responsibility, and an arrow should name the data or request crossing it. When a requirement changes, update the affected box, arrow, or branch and walk the path again. You may redraw a cramped section, but you do not need to replace the whole board to show one changed decision.
This sketch is deliberately a request-flow view. It does not prove the design will meet a traffic target, survive a store outage, or prevent abusive links. Those questions call for more requirements and perhaps a different view. For the next practice round, change one assumption, such as allowing destination edits, and see whether you can revise the diagram while keeping the browser's redirect path intelligible.
You can rehearse that revision in Lycana: speak or type the first set of components, inspect the resulting connections, then edit the redirect path as the expiration rule changes. The useful test is whether you can still explain each arrow after the change.


