Aller au contenu principal
Rolling releases Vercel : canary sans monitoring, mon incident
Retour au blog
Veille

Rolling releases Vercel : canary sans monitoring, mon incident

Patrice Huetz11 avril 20266 min

Vercel a lancé les Rolling Releases en juin 2025 : déploie progressivement une nouvelle version à 1%, 5%, 25%, 100% des utilisateurs avec rollback automatique si un seuil d'erreur est dépassé. Sur le papier, c'est la baguette magique pour dormir tranquille. En pratique, je n'avais pas de monitoring en place, et j'ai eu 2h40 d'incident invisible pendant un déploiement qui aurait dû être safe. Voici ce qui s'est passé, pourquoi le rolling release n'a pas rollback automatiquement, et la config qui aurait changé l'issue.

L'incident — 4 mars 2026, 22h47

🔒

Soutenez mon travail sur Patreon

Accès anticipé aux articles, contenu exclusif, et la satisfaction de soutenir un auteur indépendant.

Rejoindre — à partir de 3€/mois

Je déploie une nouvelle version de patricehuetz.fr qui ajoute un champ view_count sur la table blog_posts. Le migration Drizzle passe. Le déploiement passe à Vercel. Je configure la rolling release : 10% pendant 30 min, puis 50% pendant 30 min, puis 100%.

Je vais me coucher. Je me réveille à 1h27. Le site est OK. Tout a l'air normal. Je regarde les logs Vercel au matin : le déploiement est à 100%. Jusque-là, parfait.

Sauf que le lendemain matin, un lecteur me ping sur Twitter : « Ton compteur de vues est coincé à 0 sur tous les articles ». Je check. Effectivement. Puis je check les logs détaillés : depuis 23h17, tous les appels à increment_view_count() retournent une 500 silencieusement. 2h40 d'incident où aucun compteur n'était mis à jour.

Pourquoi le rolling release n'a pas rollback

C'est la vraie question. Vercel Rolling Releases est censé détecter les anomalies et rollback. Pourquoi ça n'a rien fait ?

Raison 1 : pas de métrique configurée

Par défaut, Rolling Releases monitore le taux de 5xx HTTP. Mon erreur renvoyait une 500 sur une route d'API interne qui n'est appelée que par le frontend en background pour incrémenter les compteurs. Le taux de 500 global sur mon site est resté à 0,1% (les 500 sur cette API représentaient 3% des requêtes globales, sous le seuil par défaut de 5%).

Le rolling release n'a pas détecté parce que la métrique observée était trop agrégée.

Raison 2 : pas de custom health check

Vercel permet de définir un custom health check qui appelle une route à chaque déploiement et vérifie une condition métier. Je n'en avais pas configuré. Sans, Rolling Releases ne peut pas savoir que « le compteur de vues est cassé » — ce n'est pas dans ses capteurs par défaut.

Raison 3 : pas d'alerting

Même si Vercel avait détecté quelque chose, je n'avais pas configuré d'alerting sur mon email ou Slack. Il y a des warnings dans le dashboard Vercel, mais je ne les ai pas vus parce que je dormais.

La config qui aurait tout changé

Rolling releases Vercel avec garde-fous complets
Rolling releases Vercel avec garde-fous complets

Étape 1 : une route de health check métier

typescript
// app/api/health/deep/route.ts
export async function GET() {
  const checks = await Promise.all([
    checkDbConnection(),       // Turso ping
    checkBlobConnection(),      // Vercel Blob ping
    checkViewCountIncrement(),  // ← le check qui aurait sauvé
    checkApiResponseTime(),
  ]);

  const allHealthy = checks.every(c => c.ok);
  return Response.json(
    { status: allHealthy ? "healthy" : "degraded", checks },
    { status: allHealthy ? 200 : 503 }
  );
}

async function checkViewCountIncrement() {
  try {
    const before = await db.get("test-counter").catch(() => 0);
    await db.run("UPDATE counters SET value = value + 1 WHERE id = 'test-counter'");
    const after = await db.get("test-counter");
    return { ok: after === before + 1, name: "view_count_increment" };
  } catch (e) {
    return { ok: false, name: "view_count_increment", error: String(e) };
  }
}

Étape 2 : configurer Vercel pour utiliser ce check

Dans le dashboard Vercel → Rolling Releases → Custom Health Check : pointer vers /api/health/deep. Si la route retourne un 5xx pendant 2 minutes consécutives, rollback automatique.

Étape 3 : un alerting minimal

Ajouter un webhook Slack qui reçoit les événements Vercel « rolling release degraded » ou « rollback triggered ». Coût : 0 €, temps : 10 minutes.

bash
# Dans les env vars du projet Vercel
VERCEL_WEBHOOK_URL=https://hooks.slack.com/services/XXXX/YYYY/ZZZZ

Étape 4 : un check externe de dernier recours

En plus du health check Vercel, j'utilise maintenant un cron externe (BetterStack Uptime, 0 € free tier) qui appelle /api/health/deep toutes les 2 minutes depuis l'extérieur. Si 3 échecs consécutifs, alerte Slack + SMS.

Le bilan de l'incident

MétriqueValeur
Durée incident2h40
Requêtes view_count perdues~180
Compteurs désynchronisés47 articles
Temps de détection (via Twitter)9h 30 min après début
Temps de fix12 min après détection
Temps de reconstruction des données2h (recalcul depuis logs)

Leçon principale : un rolling release sans monitoring dédié, c'est pire qu'un déploiement classique. Tu as l'illusion d'être protégé.

Ma config actuelle depuis mars

  1. 1.Custom health check métier sur /api/health/deep — vérifie 8 choses critiques
  2. 2.Rolling release avec rollback auto si health check fail 2 min consécutives
  3. 3.Webhook Slack sur tous les événements de rolling release (started, degraded, rolled-back, completed)
  4. 4.Cron externe BetterStack toutes les 2 min en backup
  5. 5.Runbook documenté pour chaque type d'incident (rollback manuel, restoration de données)

Coût total de cette config : 30 minutes de setup + 0 €/mois. Aurait évité 9h de perte de données.

💡
Active Rolling Releases **seulement** si tu as un custom health check et de l'alerting. Sinon, c'est un faux sentiment de sécurité.
⚠️
Les métriques par défaut de Vercel (taux 5xx global) ne détectent **pas** les bugs métier subtils. Tes health checks doivent tester tes **fonctionnalités critiques**, pas juste « le site répond ».

Ce qu'il faut retenir

  1. 1.Un rolling release sans monitoring est pire qu'un déploiement classique — faux sentiment de sécurité.
  2. 2.Les métriques par défaut sont trop agrégées pour détecter les bugs métier.
  3. 3.Custom health check métier obligatoire pour que le rollback auto soit utile.
  4. 4.Alerting Slack + cron externe en backup pour dormir tranquille.
  5. 5.30 minutes de setup aurait évité 9h d'incident.

Pour le workflow complet de dev + déploiement avec Ralph Loop et ses garde-fous, j'ai écrit un livre dédié :

La Boucle Ralph
La Boucle Ralph

Guide Pratique du Coding Autonome par IA.

Découvrir →
🔒

Soutenez mon travail sur Patreon

Accès anticipé aux articles, contenu exclusif, et la satisfaction de soutenir un auteur indépendant.

Rejoindre — à partir de 3€/mois

Commentaires

Chargement des commentaires...

Laisser un commentaire