1When do I need this?
- API response caching - Cache DB query results to improve response speed
- Session storage - Share login sessions across multiple servers
- Real-time rankings/counters - View counts, likes, leaderboards
- Rate Limiting - Limit the number of API requests
2Key Services
Redis (Upstash)
Most popular, serverless free tierThe standard key-value store. Supports various data structures including strings, hashes, lists, sets, and sorted sets. Upstash is a serverless Redis service.
Memcached
Simple caching onlySpecialized for simple key-value caching. Fewer features than Redis, but can be slightly faster for simple caching use cases.
Valkey
Redis fork, open sourceAn open-source fork of Redis. API-compatible with Redis and managed by the Linux Foundation.
3Pricing
- Upstash Redis - Free tier: 10K commands/day, 256MB storage
- Redis Cloud - Free tier: 30MB (suitable for small-scale caching)
- Self-hosted Redis - Free with Docker local installation (server costs separate)
4Connection Examples
FastAPI + redis-py (Python)
# app/cache.py
import redis.asyncio as redis
REDIS_URL = "redis://localhost:6379"
redis_client = redis.from_url(REDIS_URL, decode_responses=True)# app/main.py
import json
from fastapi import FastAPI
from app.cache import redis_client
app = FastAPI()
@app.get("/products/{product_id}")
async def get_product(product_id: str):
# Check cache
cached = await redis_client.get(f"product:{product_id}")
if cached:
return json.loads(cached)
# Query from DB (example here)
product = {"id": product_id, "name": "Laptop", "price": 1200000}
# Store in cache (TTL 1 hour)
await redis_client.set(
f"product:{product_id}",
json.dumps(product),
ex=3600
)
return product
@app.post("/leaderboard")
async def update_score(user_id: str, score: int):
# Real-time ranking with Sorted Set
await redis_client.zadd("leaderboard", {user_id: score})
rank = await redis_client.zrevrank("leaderboard", user_id)
return {"user_id": user_id, "score": score, "rank": rank + 1}Hono + @upstash/redis (TypeScript)
// src/cache.ts
import { Redis } from '@upstash/redis';
const redis = new Redis({
url: 'https://your-endpoint.upstash.io',
token: 'your-token',
});
export default redis;// src/index.ts
import { Hono } from 'hono';
import redis from './cache';
const app = new Hono();
app.get('/products/:id', async (c) => {
const id = c.req.param('id');
// Check cache
const cached = await redis.get<string>(`product:${id}`);
if (cached) {
return c.json(JSON.parse(cached));
}
// Query from DB (example here)
const product = { id, name: 'Laptop', price: 1200000 };
// Store in cache (TTL 1 hour)
await redis.set(`product:${id}`, JSON.stringify(product), { ex: 3600 });
return c.json(product);
});
app.get('/leaderboard', async (c) => {
const top10 = await redis.zrange('leaderboard', 0, 9, { rev: true });
return c.json(top10);
});
export default app;Cache is a secondary store
Cached data can disappear at any time. Always use it alongside a primary data store (RDB/NoSQL), and implement logic to read from the primary source on a cache miss.