Theo's Corner
dev / irl / thoughts
← Back
tech

How I use Redis for caching in practice

Theo|Jul 2026|~4 min read

Redis gets mentioned a lot as "the caching thing" without much explanation of what that actually means in practice. Here's how I actually use it in real projects.

What caching is solving

Database queries take time. If the same data gets requested repeatedly — a user's profile, a list of servers, configuration that rarely changes — hitting the database every single time is wasteful. Caching means storing the result of an expensive operation somewhere fast so subsequent requests can skip the expensive bit entirely.

Redis is in-memory, which means reads and writes are extremely fast — microseconds rather than the milliseconds a database query might take. For frequently requested data that doesn't change often, the difference is significant.

The basic pattern

Cache-aside is the most common pattern. When a request comes in, check Redis first. If the data is there (a cache hit), return it immediately. If it's not (a cache miss), fetch from the database, store the result in Redis with a TTL (time to live), and return it. Next request hits the cache.

// Check cache
let data = await redis.get(`user:${userId}`);

if (!data) {
    // Cache miss — fetch from DB
    data = await db.query('SELECT * FROM users WHERE id = $1', [userId]);
    // Store with 5 minute TTL
    await redis.setex(`user:${userId}`, 300, JSON.stringify(data));
}

return JSON.parse(data);
TTL is important — it's how long the cached data lives before Redis evicts it. Too short and you're hitting the database almost as much as without caching. Too long and you're serving stale data. Find the right balance for your use case.

Session storage

Redis is also what I use for session storage in the the panel. Sessions need to be fast to read on every authenticated request, they have a natural expiry (the session timeout), and they don't need to survive a Redis restart. That's an ideal Redis use case — fast, temporary, with built-in TTL handling.

Rate limiting

Another common Redis pattern. For each client, increment a counter in Redis with a short TTL. If the counter exceeds the limit before the TTL expires, reject the request. Redis's atomic increment operations make this clean and race-condition free.

What Redis isn't for

Redis is not a replacement for a proper database. It's volatile by default — a restart loses everything unless you've configured persistence. It's a complement to PostgreSQL, not a replacement. Keep your source of truth in Postgres. Use Redis for the fast, temporary layer on top.