Free preview

Short, Unguessable, Twelve Billion — Pick Two

In one line: the chapter states two requirements confidently and never brings them into contact. They conflict, and the arithmetic that shows it is short enough to do in an interview.

The three claims

ClaimSourceWhat it demands
ReadableLesson 2 — short links easy to read and type; 6-character minimumA small string space
UnguessableLesson 2 — 'should not be guessable'A sparse string space
12 billion URLsLesson 3 — 200M/month for 5 yearsA large occupied set

Small, sparse, and heavily occupied are three properties that cannot coexist. Here is the arithmetic.

The counting argument

6 characters in base 58  ->  58^6 = 38,068,692,544 possible strings
URLs stored after 5 years           12,000,000,000
                                    --------------
Occupancy                                    31.5%

Roughly one guess in three would hit a live URL

At 31.5% density, an attacker generating random 6-character strings hits a real, resolvable URL about once every three attempts.

That is not "difficult to predict." It is enumerable. A single machine can generate and test millions of candidates an hour, and a third of them work.

What that yields depends on what people shorten — and Lesson 2's requirement exists precisely because the answer is often sensitive: private documents, unlisted photo albums, internal dashboards, password reset links, pre-release pages. The whole reason to require unpredictability is that a short URL is frequently the only access control on the resource behind it.

And notice what does not help. The chapter's mechanism is:

"If a server issued IDs sequentially, the resulting short URLs would be predictable. To avoid this, the server selects an ID at random from its assigned range."

Random assignment defeats an attacker who guesses "what comes after the last one I saw?" It does nothing against an attacker who simply tries random strings, because the density is a property of how full the space is, not of the order you filled it.

Randomizing the order of allocation does not make a dense space sparse. That is the sentence the chapter needs and does not have.

What length actually delivers unpredictability

Take a target density — say 0.01%, so roughly one in ten thousand guesses succeeds — and solve for the length:

LengthSpace sizeOccupancy at 12BGuessable?
6 chars38 billion31.5%Trivially
7 chars2.2 trillion0.54%Marginal — 1 in 185
8 chars128 trillion0.009%No — 1 in 10,700
11 chars25 quintillion0.00000005%

Eight characters is the honest minimum, and it costs almost nothing

The table makes the resolution obvious: 8 characters gives a density of about one in ten thousand, which is a genuine security property rather than a claim.

And the cost of moving from 6 to 8 is negligible:

tiny.url/27qMi5      6 characters
tiny.url/27qMi57J    8 characters

Two characters. Still trivially readable, still fits anywhere a 6-character code fits, still typeable from a poster.

So the design's own requirements are satisfiable — just not at the length it advertises. The fix is to raise the floor from 6 characters to 8, and the readability requirement barely notices.

Which makes the omission more interesting rather than less: the conflict is real, the arithmetic is one line, and the resolution is cheap. A requirement conflict that is expensive to resolve is a hard problem; one that is cheap to resolve is an unexamined one.

And here is the twist — the design already produces 8+ characters, by accident

Lesson 9 established that IDs are drawn randomly from a range spanning 10⁹ to 2⁶⁴, and that 97.7% of such values need 11 characters.

So in practice the system is generating 11-character URLs almost always, which is unguessable — density about 5 × 10⁻¹⁰.

Which means the design is safe by accident and confusing by construction:

AdvertisedActual
Length"minimum six characters"11 characters, 97.7% of the time
GuessabilityAddressed by random assignmentAddressed by the space being enormous

Both requirements end up satisfied — but not for the reasons given, and not at the length promised. The 6-character minimum is a floor that essentially nothing reaches, and the unpredictability comes from sparsity the design never mentions rather than from the randomization it does.

That is worth stating plainly in an interview, because it is a better answer than either "six characters is fine" or "six characters is broken." The system works; the explanation of why it works is wrong.

The custom-alias hole this leaves open

There is one place where the sparsity argument fails completely, and the design does not address it.

Custom aliases are chosen by users, and users choose words. Not random strings — coffee, sale, docs, invite, q3-report.

So the custom-alias namespace is not sparse at all. It is concentrated in the tiny subset of strings that are pronounceable English, which is a vanishingly small fraction of 58⁶ but an extremely predictable one.

An attacker enumerating a dictionary against custom aliases has a far higher hit rate than one guessing random strings, and the design's own note concedes the shape of the problem:

Note: This calculation assumes users select custom short URLs uniformly at random. In practice, some words are significantly more popular than others. Therefore, this estimate represents a lower bound on the probability of collisions.

That note is about collisions, but the same non-uniformity is a security issue: predictable aliases are predictable to attackers, not just to each other.

The resolution is a product decision rather than a technical one: custom aliases should be treated as public by definition. If you choose your own memorable short link, you have chosen a guessable one, and the service should say so. Anything requiring secrecy must use a generated identifier.

Unpredictability is a property you can guarantee for identifiers you generate and cannot guarantee for identifiers users choose.

The keyed permutation is the resolution worth knowing: keep a sequential id internally so uniqueness stays guaranteed by construction, and map it through a reversible keyed permutation on the way out so the issued codes look unordered.

Key takeaway

Three of the chapter's claims cannot all hold: 6 characters gives 38 billion strings, 12 billion URLs occupy 31.5% of them, and one guess in three would hit a live link. Randomizing the order of allocation does not make a dense space sparse — the chapter's stated mechanism addresses the wrong attack. The honest fix is 8 characters (one in ten thousand density) at a cost of two characters. But the twist is that the design already produces 11-character URLs 97.7% of the time, so it is safe by accident: both requirements hold, neither for the stated reason, and the advertised six-character floor is essentially never reached. And custom aliases break the argument entirely, because users choose words rather than random strings — unpredictability is guaranteeable for identifiers you generate and not for identifiers users choose.

Interview signal by level

LevelWhat a strong answer sounds like
L4"We use base-58 so the URLs are readable, and we pick IDs randomly rather than sequentially so they're hard to guess."
L5Questions the mechanism: "random assignment stops someone predicting the next ID, but if the space is small relative to what we've stored, an attacker can just try random strings. I'd want to check the density."
Staff+Does the arithmetic: "six characters is 58^6, about 38 billion, and we're storing 12 billion — 31.5% occupancy, so one guess in three hits. Randomizing allocation order doesn't help, because density is about how full the space is, not the order you filled it. Eight characters gets you to one in ten thousand and costs two characters, so the fix is cheap. Though in practice IDs drawn randomly from a 64-bit range are 11 characters 97.7% of the time, so the system is actually safe — just not for the reason stated, and the six-character minimum is a floor nothing reaches. The real hole is custom aliases: users pick words, so that namespace is predictable by construction, and I'd treat user-chosen aliases as public by definition."

Next: the workflow, concurrency, and custom-alias bookkeeping.

Enjoying the preview?

Create a free account to unlock the rest of this course, the in-browser judge, and live AI mock interviews.

Sign up free to continue