How do URL shorteners work?
What actually happens between clicking a short link and landing on the destination page: short codes, database lookups, HTTP redirects and why the status code matters.
A URL shortener is, at its core, a lookup table with an HTTP redirect attached. The interesting parts are how the keys are generated and what happens on the redirect path.
Step 1: storing the destination
When you submit a long URL, the service validates it and stores it in a database alongside a newly generated short code:
a8K3xPq→https://example.com/products/spring-collection
Validation matters more than it sounds. The destination will eventually be handed to a browser as a Location header, so a shortener that accepts anything can be used to launch javascript: URLs or to probe private network addresses. Zurl accepts only http and https, and checks the protocol after parsing the URL rather than by matching text — otherwise tricks like a tab character inside javascript: slip through.
Step 2: generating the short code
There are two broad approaches, and the difference is significant.
Sequential encoding
Take the database row id, encode it in base62, and use that as the code. Row 1 becomes 1, row 100000 becomes q0U. It is compact and collisions are impossible by construction.
The problem is that it is completely predictable. Anyone can walk the entire link database by counting, which exposes every link anyone has ever created. It also leaks how many links the service has ever stored.
Random generation
Generate a random string from a fixed alphabet and check that it is not already taken. Zurl uses seven characters from a 56-character alphabet, which gives roughly 1.7 × 1012 possibilities. Codes cannot be enumerated in practice, and nothing about your link volume is revealed.
Two details matter here. The randomness must be cryptographically secure — Math.random() is predictable enough to be attacked. And the mapping from random bytes to characters must avoid modulo bias: naively taking a byte modulo 56 makes the first 32 characters of the alphabet more likely than the rest, because 256 does not divide evenly by 56. The fix is rejection sampling, which discards bytes that would skew the distribution.
Handling collisions
With random codes, two links can in principle be assigned the same code. The robust solution is a unique constraint in the database plus a retry: attempt the insert, and if the database rejects it, generate a new code and try again. Checking "is this code free?" before inserting is a race condition — two simultaneous requests can both see the code as free.
Step 3: the redirect
When someone opens the short link, the service:
- Extracts the code from the path.
- Looks it up, using an indexed query on a unique column.
- Checks whether the link exists, is expired, or has been disabled.
- Returns an HTTP redirect with a
Locationheader pointing at the destination.
The browser receives the redirect and immediately requests the destination. The user typically never notices the intermediate hop.
Why the status code matters
This is the decision most shortener implementations get wrong.
A 301 Moved Permanently tells the browser the mapping will never change. Browsers take that literally and cache it aggressively — often until the cache is manually cleared. It saves a round trip on repeat visits.
A 302 Found tells the browser the redirect is temporary, so it asks the server again next time.
The trap with 301 is that it makes link management stop working. If you disable a link, change its destination, or let it expire, anyone who already visited it keeps going to the old destination — potentially for years — because their browser never asks again. For a service that offers editable, expirable, disableable links, that is a correctness bug, not an optimisation. Zurl uses 302 for this reason and accepts the extra round trip.
Recording the click without slowing it down
Analytics is the part most likely to hurt performance. Writing a click record takes a database round trip, and if the redirect waits for it, every visitor pays that cost.
The fix is to send the redirect first and record the click afterwards. On modern serverless platforms there is an explicit mechanism for work that should continue after the response has been delivered. The visitor is already on their way to the destination while the click is being written.
It also means an analytics failure cannot break a redirect. If the write fails, it is logged and the visitor is unaffected — the right trade-off, since the redirect is the product and analytics is reporting.
What gets recorded
This is a design decision, not a technical necessity. A shortener could store the full IP address, the complete user-agent string and the full referring URL for every click. That produces a detailed record of individual people.
Zurl records a coarse country, a device and browser category, and the referring host only. The IP address is used to derive the country and then discarded; the user-agent is reduced to three labels and discarded. There is enough data to answer "where is my traffic coming from?" and not enough to profile a visitor. See the privacy page for specifics.
Trying it
The URL shortener does all of the above in a few milliseconds. If you want to build it into your own application, the API exposes the same functionality.