There's one interview round you genuinely can't wing: "design and walk me through a feature, from the database to the screen, in one of your real stacks." You either have a real system in your head to walk through, or you're improvising, and improvising shows.
The good news is you don't need a huge system. One shipped feature, understood properly, is enough. Here's how I take a vague sentence and turn it into a design, using something I actually built into my CMS.
The requirement, in one sentence
Here's the whole spec, the way it actually arrived:
"The blog URLs should be readable, not database ids, and good for SEO."
That's it. No schema, no acceptance criteria, no edge cases. That's what a client or a PM hands you, and the interview version isn't much longer. The work is turning that into something buildable, and the mistake is to start drawing boxes before you've asked anything.
Ask questions before you design
Four questions, in this order, before a single line of schema:
- What's the worst outcome if we get this wrong? Here it's obvious: links that already exist out in the world, shared, indexed by Google, stop working. Any design that can break an old link is disqualified.
- What's the smallest data change that could work? A new field on the post, not a new collection, not a service. Reach for the smallest thing first and only grow it if forced.
- Who creates the value, and when? The slug comes from the title. Generated automatically on the first save so nobody has to think about it, but editable for the cases where the automatic version is bad.
- What's already out there that this has to not break? Every post published so far has a numeric-id URL in the wild.
Those answers basically are the design. The diagram is just writing them down.

The design that fell out
Data: one nullable field
A single slug field on the post document. Nullable, because every existing post starts without one. A unique index so two posts can't collide.
Generation: once, from the title, then frozen
On the first save of a post, if there's no slug, generate one by lower-casing the title and replacing anything non-alphanumeric with dashes. Store it. Never regenerate it on a later edit, even if the title changes, because that would silently change the URL, which is the exact thing question one ruled out.
Routing: accept the slug or the id
The blog route resolves its parameter as either a slug or a raw id. New links use the slug, every old numeric-id link still hits the same handler and returns the same post. Nothing 404s, ever. This is what makes the whole thing safe to ship.
The edge case: titles that are mostly symbols
A post titled == vs === Isn't Really About Two Equals Signs slugifies to vs-isnt-really-about-two-equals-signs, which drops the one keyword people actually search for. So the slug field stays editable, and for a title like that you set it by hand to something like double-equals-vs-triple-equals-javascript. The automatic path covers most posts -- the manual override covers the rest.
Where the stack choice actually shows up
The interview loves "MERN vs PERN, what changes?" For a feature like this, the honest answer is: almost nothing changes in the design, and the thing that does change is who enforces the rules.
- On Postgres, "slugs are unique" is a one-line
UNIQUEconstraint, and the database refuses a bad write no matter which code path tries it. - On MongoDB, it's a partial unique index (you have to exclude nulls), and more of the "is this slug taken" logic tends to live in application code.
That's the real shape of most MERN-vs-PERN differences. Not speed, not scale at the sizes most apps actually run at. It's how many of your invariants the database guarantees for you versus how many your code has to remember to check.
"When would you split this into a service?"
For this feature, you wouldn't. A slug is a field and a route. Pulling it into its own service would add a network hop and a deployment for zero benefit.
The trigger for splitting isn't "the codebase got big." It's when one part has a genuinely different scaling profile or deploy cadence than the rest, image processing that needs its own workers, an analytics pipeline that shouldn't share a database connection pool with your API. Name that trigger in an interview instead of a line count and you sound like someone who's actually run one.
Quick recap
- The "design a feature" round can't be faked; one real shipped feature, understood end to end, is enough to answer it
- Ask four things before designing: worst failure, smallest data change, who creates the value and when, what existing thing you must not break
- The slug design: one nullable indexed field, generated once from the title and then frozen, a route that accepts slug or id so old links never die
- MERN vs PERN mostly changes who enforces invariants, the database or your code, not raw performance
- Split a monolith when a piece has its own scaling or deploy needs, not when it gets large
The point of walking through a small real feature isn't the feature. It's showing that you design by asking what breaks and what's smallest, not by reciting patterns you read about.




Comments
No comments yet — be the first to share your thoughts.