Skip to content

Redis Api Caching

DodaTech 2 min read

title: "Redis API Caching — In-Memory Data Store for Fast API Responses" description: "Redis provides sub-millisecond in-memory caching for API responses with built-in TTL, eviction policies, and data structures for complex caching scenarios." date: 2026-06-28 lastmod: 2026-06-28 weight: 20 tags: [apis, caching] }

Redis caches API responses in memory with sub-millisecond read times, automatic TTL expiry, configurable eviction policies, and rich data structures for advanced caching.

What You'll Learn

  • Redis as an API cache layer
  • TTL and eviction policies
  • Redis cache patterns

Why It Matters

Redis caching reduces database load by 90%+ and serves cached responses in 1-5ms compared to 50-200ms database queries.

Code Examples

import redis
import json

r = redis.Redis(host='localhost', port=6379, decode_responses=True)

@app.route('/api/products/<int:product_id>')
def get_product(product_id):
    # Try cache first
    cached = r.get(f'product:{product_id}')
    if cached:
        return jsonify(json.loads(cached))

    # Cache miss - fetch from DB
    product = db.execute("SELECT * FROM products WHERE id = ?", [product_id])

    # Cache with TTL and cache-aside pattern
    r.setex(f'product:{product_id}', 300, json.dumps(product))
    return jsonify(product)

# Cache-aside pattern helper
def cache_aside(key, fetch_func, ttl=300):
    cached = r.get(key)
    if cached:
        return json.loads(cached)
    data = fetch_func()
    r.setex(key, ttl, json.dumps(data))
    return data

# Batch cache with pipeline
def get_products_batch(product_ids):
    pipe = r.pipeline()
    for pid in product_ids:
        pipe.get(f'product:{pid}')
    results = pipe.execute()
    return results

# Cache with hash data structure
def cache_user_profile(user_id, profile_data):
    r.hset(f'user:{user_id}', mapping=profile_data)
    r.expire(f'user:{user_id}', 600)
const redis = require('redis');
const client = redis.createClient();

async function getProduct(productId) {
  const cacheKey = `product:${productId}`;

  // Cache-aside pattern
  const cached = await client.get(cacheKey);
  if (cached) return JSON.parse(cached);

  const product = await db.query('SELECT * FROM products WHERE id = $1', [productId]);
  await client.setEx(cacheKey, 300, JSON.stringify(product));
  return product;
}

Common Mistakes

1. No TTL on Cache Keys

Without TTL, stale data persists forever in Redis.

2. Cache Key Collisions

Use namespaced keys like product:123 not just 123.

3. Storing Large Objects

Large JSON objects consume memory. Cache only what's needed.

4. No Error Handling for Redis Failures

Redis down should not crash your API. Fail open to database.

5. Cache Stampede Without Locking

Multiple requests for expired key all hit DB simultaneously.

Practice Questions

  1. What is cache-aside pattern?
  2. Why set TTL on cached items?
  3. How do you handle Redis connection failures?
  4. What Redis data structures are best for API caching?
  5. What is cache warmup?

Answers:

  1. Check cache first, fetch from DB on miss, store in cache for next time.
  2. To ensure data freshness and prevent stale data.
  3. Use try/catch and fall back to database queries.
  4. Strings for simple values, Hashes for structured data.
  5. Pre-populating cache with frequently accessed data before serving traffic.

Challenge: Implement a Redis caching layer for your API with cache-aside pattern, TTL management, and graceful fallback when Redis is unavailable.

FAQ

How much memory does Redis need for caching?

: Depends on dataset size. 1GB of Redis can cache approximately 1-2 million small API responses.

Is Redis cache slower than local memory cache?

: Yes, local memory (5-50ns) is faster than Redis (1-5ms network), but Redis is shared across instances.

Can Redis persist cache data across restarts?

: Yes, with RDB/AOF persistence, but cache typically uses ephemeral data.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro