A URL shortener is the classic "sounds trivial, actually teaches you a lot" system. You take a long URL, hand back a short one, and when someone visits the short link you send them to the original. You could build a working version in an afternoon with a database table and two routes. The reason it shows up in interviews is that the moment you care about scale, short codes, and speed, every simple choice turns into a real decision.

Let me start with the shape of the workload, because it drives everything. This system is read heavy and write light. You create a short link once. It might then get clicked thousands or millions of times. So the redirect path has to be blisteringly fast and cheap, while the creation path can afford to do a bit more work. Any design that treats reads and writes as equally important is optimizing the wrong thing.

The core question is how you generate the short code. You have two main families of approaches, and the trade-off between them is the heart of the design.

The first approach is hashing. Take the long URL, run it through a hash, and use some characters of the output as the code. It is simple and stateless. The problem is collisions. Two different URLs can hash to the same short prefix, and now you have to detect that and retry with a different slice, which means a database check on every creation and awkward edge cases. It works, but it gets fiddly.