How Redis Makes a URL Shortener Fast
Introduction
A URL shortener looks simple at first: receive a short code, query the database, find the original URL, and redirect the user. But at scale, the redirect endpoint becomes one of the hottest paths in the entire system.
A popular short URL may be requested thousands or millions of times. Querying PostgreSQL for every redirect would unnecessarily increase database load and add latency to a request that should be extremely fast.
In my Distributed URL Shortener, Redis is placed in the redirect path as a high-speed cache so frequently accessed URLs can be resolved without repeatedly hitting PostgreSQL.
Engineering Insight
The goal of Redis here is not to replace PostgreSQL. PostgreSQL remains the source of truth, while Redis provides a faster access layer for frequently requested URLs.
The Problem With Database-Only Redirects
Without caching, every redirect request must reach PostgreSQL. Even if the same short URL is requested repeatedly, the database performs essentially the same lookup again and again.
This becomes inefficient because URL shortening systems are naturally read-heavy. A URL may be created once but redirected thousands of times.
As traffic increases, database connections, CPU usage, disk access, and query processing can become unnecessary bottlenecks.
Important
Scaling PostgreSQL simply because the application repeatedly reads the same data is expensive. Caching allows those repetitive reads to be served from memory instead.
Client
|
v
Redirect Service
|
v
PostgreSQL
|
v
Find Original URL
|
v
Redirect UserAdding Redis to the Redirect Path
Redis changes the redirect flow by introducing an in-memory lookup before PostgreSQL.
When a redirect request arrives, the Redirect Service first checks Redis using the short code. If the mapping exists, the original URL can be returned immediately.
Only when Redis does not contain the mapping does the service need to query PostgreSQL.
Client
|
v
Redirect Service
|
v
Redis Cache
|
+------ Cache Hit ------> Redirect User
|
+------ Cache Miss
|
v
PostgreSQL
|
v
Original URL
|
v
Store in Redis
|
v
Redirect UserThe Cache-Aside Pattern
The strategy used here follows the cache-aside pattern. The application remains responsible for checking the cache, loading missing data from the database, and populating Redis.
Redis is therefore not directly responsible for synchronizing itself with PostgreSQL. The Redirect Service controls the caching workflow.
This pattern is widely useful because the database remains the authoritative data store while the cache can be rebuilt whenever necessary.
Best Practice
Treat the database as the source of truth and Redis as an optimization layer. Losing the cache should affect performance, not permanently lose URL data.
1. Receive short code
2. Check Redis
3. If cached:
return original URL
4. If not cached:
query PostgreSQL
5. Store result in Redis
6. Return original URLUnderstanding Cache Hits
A cache hit occurs when Redis already contains the short-code-to-original-URL mapping.
This is the ideal redirect path because the service does not need to query PostgreSQL. Redis keeps the mapping in memory and can return it with very low latency.
Popular URLs naturally become excellent cache candidates because the cost of loading them from PostgreSQL once can be amortized across many subsequent redirects.
GET /abc123
Redis lookup:
short:abc123
|
v
https://example.com/article
CACHE HIT
PostgreSQL lookup avoidedUnderstanding Cache Misses
A cache miss occurs when the requested short code is not currently available in Redis.
A miss does not automatically mean that the URL does not exist. The cache may have expired, Redis may have restarted, or the URL may simply never have been cached before.
The Redirect Service therefore falls back to PostgreSQL. If the URL exists, the result can be placed into Redis so future requests become cache hits.
Redis
|
+-- MISS
|
v
PostgreSQL
|
+-- URL exists
| |
| v
| Cache result
|
+-- URL missing
|
v
404Why TTL Matters
Cached entries should not necessarily live forever. A Time To Live, or TTL, allows Redis entries to expire automatically after a configured period.
TTL helps control memory usage and prevents stale cache entries from remaining indefinitely.
The correct TTL depends on the behavior of the application. Frequently accessed and rarely modified URLs may tolerate longer cache durations, while mutable data generally requires more careful expiration strategies.
Engineering Insight
There is no universal perfect TTL. Cache expiration should be chosen based on data volatility, memory constraints, traffic patterns, and acceptable staleness.
SET short:abc123 "https://example.com" EX 3600What About Invalid Short URLs?
Caching improves valid URL lookups, but public redirect endpoints also receive requests for short codes that do not exist.
If every invalid request causes a Redis miss followed by a PostgreSQL query, attackers or random traffic could still generate significant database load.
This is where the Bloom Filter used by the Distributed URL Shortener becomes useful. It can reject values that definitely do not exist before expensive database work is performed.
Best Practice
Redis and Bloom Filters solve different problems. Redis accelerates repeated valid lookups, while the Bloom Filter helps avoid unnecessary work for values that definitely do not exist.
Redirect Request
|
v
Bloom Filter
|
+-- Definitely Not Present --> 404
|
+-- Might Exist
|
v
Redis Cache
|
Hit / Miss
|
v
PostgreSQLRedis vs PostgreSQL
Redis and PostgreSQL should not be viewed as competing databases in this architecture. They have different responsibilities.
PostgreSQL provides durable storage and acts as the source of truth for URL metadata. Redis provides an in-memory representation of frequently accessed mappings to optimize the redirect path.
Feature Comparison
Side-by-side comparison of the two technologies.
| Feature | Redis | PostgreSQL |
|---|---|---|
| Primary Role | Caching | Persistent storage |
| Storage | Primarily memory | Durable database storage |
| Redirect Usage | First lookup | Fallback/source of truth |
| Latency | Very low | Higher than cache lookup |
| Data Loss Impact | Cache can be rebuilt | Persistent data must be protected |
What Happens If Redis Goes Down?
A cache should improve performance without becoming the only place where important application data exists.
Because PostgreSQL remains the source of truth, the system can conceptually fall back to database lookups when cached mappings are unavailable.
The consequence is degraded performance and increased database traffic rather than permanent loss of URL mappings.
Important
Caching introduces another distributed-system dependency. Production systems must think about timeouts, connection failures, fallback behavior, and preventing a Redis outage from cascading into database overload.
The Complete Redirect Strategy
Combining the different components produces a redirect path optimized around avoiding unnecessary work.
The Bloom Filter protects against definite invalid lookups, Redis handles hot URL mappings, PostgreSQL provides durable fallback storage, and Kafka allows click analytics to happen asynchronously without blocking the redirect.
Redirect Request
|
v
Bloom Filter
|
+----------+----------+
| |
Definitely Missing Might Exist
| |
v v
404 Redis
|
+--------+--------+
| |
HIT MISS
| |
| v
| PostgreSQL
| |
+--------+--------+
|
v
Redirect User
|
v
Publish Click Event
|
v
Kafka
|
v
Analytics ServiceKey Engineering Lessons
The interesting part of adding Redis is not simply calling GET and SET. The real engineering work is deciding what should be cached, how long it should remain cached, what happens on a miss, and how the system behaves when the cache is unavailable.
Caching also demonstrates an important distributed-systems principle: improving latency often introduces additional consistency and failure-handling decisions.
For a URL shortener, the read-heavy redirect workload makes Redis especially valuable because a relatively small set of popular URLs can generate a very large percentage of total traffic.
Best Practice
Use Redis because the workload benefits from caching, not simply because Redis is a popular technology. Every infrastructure component should solve a specific system problem.
Final Thoughts
Redis transforms the redirect path from a database lookup on every request into a memory-first lookup optimized for repeated reads.
Combined with PostgreSQL as the durable source of truth, a Bloom Filter for invalid requests, and Kafka for asynchronous analytics, the caching layer becomes part of a larger strategy for keeping redirects fast while reducing unnecessary work.
This is the difference between simply adding Redis to a project and designing a caching strategy around the behavior of the system.