Case study

Shrink

A self-serve URL shortener with click analytics — built solo, front to back, because I wanted to own every decision in it.

Role

Solo builder — personal project

Stack

React · Node.js · Express · PostgreSQL · Redis

The problem

A URL shortener is a deceptively simple idea with genuinely interesting engineering underneath. How do you make redirects fast at scale? Where does the relational data end and the cache begin? How do you keep click analytics correct without putting a write on the redirect path?

Built solo, end to end, with the focus on exploring caching strategy alongside a relational store rather than on hitting a feature count.

Key decisions

01

Redis in front of PostgreSQL for redirect lookups

Every redirect is a read, and most links get clicked in a burst soon after they are created. Serving those reads from memory keeps p50 redirect latency in single-digit milliseconds.

The tradeoff

Cache invalidation on edits and deletes. When a destination URL changes the entry has to be evicted immediately, which adds a write path touching both stores.

The hard part

The interesting tension was around click analytics. The naive approach — write a row on every redirect — puts a synchronous database write on exactly the path where you least want extra latency.

Queueing the analytics event and letting a background worker flush it to Postgres keeps the redirect fast and makes the analytics eventually consistent. For a click counter that is the right trade: nobody needs the number to be correct to the millisecond, and everybody notices a slow redirect.

Where it landed

The project did what it was built to do — force real decisions about caching, asynchronous writes, and the split between a fast read path and a slower analytics path. It was previously hosted on Render and may need re-deploying.

What I took from it

01

The redirect path and the analytics path have fundamentally different latency requirements. Design them separately.

02

Cache invalidation on writes is a first-class concern, not an afterthought.

03

Building something "simple" end to end reveals all the decisions that real systems have already made for you.

Want this kind of thinking on your backend?