Le Redis traditionnel nécessite un serveur en marche, un coût mensuel fixe et une gestion de connexions incompatible avec les architectures serverless. Upstash résout ça avec un service Redis serverless facturé à la requête, qui communique en HTTP et tourne nativement sur les runtimes edge. Pour les développeurs qui déploient sur Vercel, Cloudflare Workers ou toute plateforme serverless, c’est la façon la plus simple d’ajouter du cache, du rate limiting et des jobs en arrière-plan sans gérer d’infrastructure.
Client Redis basé sur HTTP
Les clients Redis standards utilisent des connexions TCP persistantes. Ça ne fonctionne pas dans les fonctions serverless où chaque invocation est isolée et de courte durée. Le client @upstash/redis communique en HTTP REST, ce qui signifie pas de connection pooling, pas de timeouts, et pas de pénalité de cold start.
import { Redis } from '@upstash/redis';
const redis = Redis.fromEnv();
export async function getCached<T>(
key: string,
ttl: number,
fetcher: () => Promise<T>
): Promise<T> {
const cached = await redis.get<T>(key);
if (cached) return cached;
const data = await fetcher();
await redis.set(key, data, { ex: ttl });
return data;
}
Redis.fromEnv() lit UPSTASH_REDIS_REST_URL et UPSTASH_REDIS_REST_TOKEN depuis les variables d’environnement. Le client sérialise et désérialise le JSON automatiquement, donc pas de JSON.parse manuel. Chaque appel est une requête HTTP unique, entièrement compatible avec les runtimes edge où les sockets TCP ne sont pas disponibles.
Rate limiting avec @upstash/ratelimit
Construire du rate limiting from scratch implique de gérer des fenêtres glissantes, des token buckets et des compteurs atomiques. Upstash package tout ça dans une seule librairie qui fonctionne directement avec le middleware Next.js.
import { Ratelimit } from '@upstash/ratelimit';
import { Redis } from '@upstash/redis';
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
const ratelimit = new Ratelimit({
redis: Redis.fromEnv(),
limiter: Ratelimit.slidingWindow(10, '10 s'),
analytics: true,
});
export async function middleware(request: NextRequest) {
const ip = request.headers.get('x-forwarded-for') ?? '127.0.0.1';
const { success, remaining } = await ratelimit.limit(ip);
if (!success) {
return NextResponse.json({ error: 'Too many requests' }, { status: 429 });
}
const response = NextResponse.next();
response.headers.set('X-RateLimit-Remaining', String(remaining));
return response;
}
export const config = { matcher: ['/api/:path*'] };
L’algorithme de fenêtre glissante distribue les requêtes uniformément au lieu de permettre des rafales aux frontières de fenêtres. Ça tourne à l’edge, ce qui signifie que le rate limiting se fait avant que la requête n’atteigne le serveur d’origine. Le flag analytics envoie les données d’usage au dashboard Upstash pour le monitoring.
QStash pour les jobs en arrière-plan
Les fonctions serverless ont des limites de temps d’exécution. Une fonction Vercel timeout après 10 secondes sur le plan hobby. Les tâches longues comme l’envoi d’emails, le traitement d’images ou la synchronisation de données doivent tourner de manière asynchrone. QStash est la message queue HTTP d’Upstash qui déclenche des webhooks avec livraison garantie.
import { Client } from '@upstash/qstash';
const qstash = new Client({ token: process.env.QSTASH_TOKEN! });
export async function POST(request: Request) {
const order = await request.json();
await db.order.create({ data: order });
await qstash.publishJSON({
url: `${process.env.APP_URL}/api/jobs/send-confirmation`,
body: { orderId: order.id, email: order.email },
retries: 3,
delay: '5s',
});
return Response.json({ status: 'created' });
}
La route API crée la commande et enqueue le job d’email en une seule requête. QStash gère les retries, les délais et les dead letter queues. Si le endpoint webhook échoue, QStash retente jusqu’à trois fois avec un backoff exponentiel. Pas de queues Redis à gérer, pas de worker processes à maintenir en vie.
Conclusion
Upstash comble le fossé entre les bases de données managées et le compute serverless. Du Redis HTTP qui tourne à l’edge, du rate limiting qui se déploie en middleware, et des jobs en arrière-plan qui survivent aux timeouts de fonctions. Pour les développeurs TypeScript qui construisent sur Vercel ou des plateformes similaires, ça supprime la friction infrastructure qui accompagne habituellement l’ajout de cache, de queues et de traitement asynchrone.