</> MAANG.io
system design · 301

Advanced

Master system design interviews with scalable architecture patterns, distributed systems, and real-world design challenges.

0/480 solved 0% complete

Section 11: The Product Team's Wishlist - Follow-up Feature Evolution

Executive Summary: The redirect service ships and Maya's newsletter link works. Now product shows up with four requests: vanity aliases, click analytics, expiring links, and destinations you can edit. This section adds each one without tearing anything down. Aliases go into the same table with a conditional put, in a length band that can never collide with generated codes. Analytics flows through the Kafka pipeline that Section 6 reserved for it. Expiration is checked lazily and never recycles a code. Editable destinations are the hard one, because they break the immutability that every earlier section relied on. They need a version field, optimistic concurrency, deliberate cache invalidation, and a refusal to edit 301 links.

The interviewer relaxes. The adversarial part of the hour is over and the generative part begins. "Maya loves it. She wants tiny.example/fall-sale instead of aZ3kP9q, she wants to see who clicked, she wants the link to die after the sale, and next month she wants to point it at the winter collection. Evolve your design."

There are two ways to fail here: discovering the MVP must be rebuilt, or admitting you quietly built all of this already. The answer that scores walks each feature through a door the earlier sections deliberately left unlocked.

Custom Aliases: Same Table, Different Length Band

The access pattern doesn't change. A redirect for fall-sale is still a single-key lookup on short_code. So the alias goes in the same links table, written with a conditional put (insert-if-absent):

Interviewer: "Two customers ask for fall-sale in the same millisecond. Who wins?"

Candidate: "The storage engine decides. Both requests send PutItem with the condition that short_code doesn't exist yet. Exactly one succeeds, and the other gets 409 Conflict with a suggestion. There's no read-then-write window and no lock. Section 5 listed conditional put as an access pattern for exactly this case."

The real design choice is the length rule. Aliases must be 8–30 characters from [A-Za-z0-9-]. Generated codes are exactly 7 characters today, so the two namespaces can't overlap. The paid 6-character vanity tier from Section 9 is the one exception to the 8-character floor. It sits below the generated length, so it can't collide either. If we allowed a 7-character alias, Maya could claim a code the range allocator from Section 8 will mint someday. That would mean a duplicate-key failure for an unrelated customer, or worse. A reserved-word blocklist (api, login, admin, help and similar) protects routes and stops people from impersonating our own pages.

The alias create also clears any negative-cache entry for fall-sale, the same way any create does (Section 7). A vanity alias is exactly the code someone tests before claiming it.

Interviewer: "Why not a separate aliases table? It's cleaner."

Candidate: "Length tells us which table to read, so it wouldn't cost a second lookup. It costs a second of everything else: two cache keyspaces, two replication setups, two disable paths, and a uniqueness rule that spans tables, which a single conditional put can't enforce. One table with disjoint key shapes keeps one of each."


Quick check before moving on:

Sign in to continue reading

The rest of this lesson is available with a free account. Signing in with Google or Microsoft is free.

Sign in to read the full lesson

Sign in to MAANG.io

Use your Google or Microsoft account — no password to remember.

Continue with Google Continue with Microsoft

Please accept the terms above to continue.