Les requêtes base de données sont le goulot d’étranglement de la plupart des applications web. Une requête qui prend 50ms sous charge légère en prend 500ms quand le trafic explose. Redis élimine ça en stockant les données fréquemment accédées en mémoire, avec des temps de réponse sous la milliseconde. Ce n’est pas qu’un cache. Redis gère le stockage de sessions, le rate limiting, le messaging pub/sub temps réel et les files de jobs, ce qui en fait le couteau suisse de l’infrastructure backend pour les applications Node.js et TypeScript.
Cacher les requêtes base de données
L’utilisation la plus immédiate de Redis est le cache des appels base de données coûteux ou répétitifs. Une page produit qui tape dans PostgreSQL à chaque requête peut servir les mêmes données depuis Redis en moins d’une milliseconde après le premier fetch.
import { Redis } from 'ioredis';
const redis = new Redis(process.env.REDIS_URL!);
async function getCached<T>(key: string, ttl: number, fetcher: () => Promise<T>): Promise<T> {
const cached = await redis.get(key);
if (cached) return JSON.parse(cached);
const data = await fetcher();
await redis.set(key, JSON.stringify(data), 'EX', ttl);
return data;
}
router.get('/projects/:slug', async (req, res) => {
const project = await getCached(`project:${req.params.slug}`, 3600, () =>
db.project.findUnique({ where: { slug: req.params.slug } })
);
res.json(project);
});
Le helper getCached abstrait le pattern read-through. Le premier appel tape dans la base et écrit dans Redis avec un TTL. Chaque appel suivant dans la fenêtre du TTL saute la base entièrement. Sur une application Next.js servant des centaines d’utilisateurs concurrents, ça seul peut diviser les temps de réponse par dix.
Stockage de sessions
Stocker les sessions dans Redis au lieu de la mémoire ou d’une base SQL résout deux problèmes : ça survit aux redémarrages serveur, et ça fonctionne sur plusieurs instances Node.js derrière un load balancer.
import session from 'express-session';
import RedisStore from 'connect-redis';
app.use(
session({
store: new RedisStore({ client: redis }),
secret: process.env.SESSION_SECRET!,
resave: false,
saveUninitialized: false,
cookie: { secure: true, maxAge: 86400000 },
})
);
Redis stocke la session comme une paire clé-valeur avec expiration automatique. Pas de jobs de nettoyage, pas de sessions périmées qui s’accumulent dans PostgreSQL, pas de sticky sessions nécessaires au niveau du load balancer.
Rate limiting
Protéger les endpoints API contre les abus nécessite de compter les requêtes par client dans une fenêtre de temps. Redis rend ça atomique et rapide avec la commande INCR et l’expiration de clé.
async function rateLimit(req: Request, res: Response, next: NextFunction) {
const key = `rate:${req.ip}`;
const current = await redis.incr(key);
if (current === 1) {
await redis.expire(key, 60);
}
if (current > 100) {
return res.status(429).json({ error: 'Too many requests' });
}
next();
}
Chaque IP obtient un compteur qui se réinitialise toutes les 60 secondes. La combinaison INCR et EXPIRE est atomique dans Redis, donc il n’y a pas de race conditions même sous trafic concurrent intense. Ce pattern fonctionne pour le rate limiting API, le throttling de tentatives de connexion et la protection de soumission de formulaires.
Pub/Sub pour le temps réel
Le pub/sub Redis permet la communication temps réel entre processus Node.js sans que des librairies WebSocket gèrent l’état. Un processus publie un événement, chaque subscriber le reçoit instantanément.
const publisher = new Redis(process.env.REDIS_URL!);
const subscriber = new Redis(process.env.REDIS_URL!);
subscriber.subscribe('notifications');
subscriber.on('message', (channel, message) => {
const payload = JSON.parse(message);
broadcastToClients(payload);
});
async function notify(event: string, data: unknown) {
await publisher.publish('notifications', JSON.stringify({ event, data }));
}
Ce pattern alimente les dashboards live, les applications de chat et les fonctionnalités d’édition collaborative. Chaque instance Node.js souscrit au même channel Redis, donc le scaling horizontal ne casse pas les fonctionnalités temps réel.
Conclusion
Redis se place entre l’application et la base de données, absorbant la charge qui ralentirait tout le reste. Cache, sessions, rate limiting et pub/sub couvrent la grande majorité des cas d’usage pour les backends Node.js. C’est une seule dépendance qui élimine des catégories entières de problèmes de performance et de scaling.