Distributed Systems2026-07-3110 min read

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.

text
Client
   |
   v
Redirect Service
   |
   v
PostgreSQL
   |
   v
Find Original URL
   |
   v
Redirect User

Adding 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.

text
Client
   |
   v
Redirect Service
   |
   v
Redis Cache
   |
   +------ Cache Hit ------> Redirect User
   |
   +------ Cache Miss
              |
              v
          PostgreSQL
              |
              v
        Original URL
              |
              v
        Store in Redis
              |
              v
        Redirect User

The 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.

text
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 URL

Understanding 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.

text
GET /abc123

Redis lookup:

short:abc123
      |
      v
https://example.com/article

CACHE HIT

PostgreSQL lookup avoided

Understanding 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.

text
Redis
  |
  +-- MISS
        |
        v
   PostgreSQL
        |
        +-- URL exists
        |      |
        |      v
        |   Cache result
        |
        +-- URL missing
               |
               v
             404

Why 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.

redis
SET short:abc123 "https://example.com" EX 3600

What 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.

text
Redirect Request
      |
      v
 Bloom Filter
      |
      +-- Definitely Not Present --> 404
      |
      +-- Might Exist
              |
              v
          Redis Cache
              |
         Hit / Miss
              |
              v
         PostgreSQL

Redis 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.

FeatureRedisPostgreSQL
Primary RoleCachingPersistent storage
StoragePrimarily memoryDurable database storage
Redirect UsageFirst lookupFallback/source of truth
LatencyVery lowHigher than cache lookup
Data Loss ImpactCache can be rebuiltPersistent 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.

text
                 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 Service

Key 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.