Runbook — Maîtriser les coûts
title: Runbook — Maîtriser les coûts (builds, providers, Neon) description: Découpler l'activité de développement de la dépense cloud : Ignored Build Step, push groupés, previews sur demande, cap dur de dépense, ledger des providers et réglages à poser dans les tableaux de bord.
Ce qui s'est passé (mesuré)
Du 27/09 au 02/10 (UTC), le projet Vercel orbit-easyconnector-app a produit 1 690 déploiements (API Vercel, liste exhaustive) : chaque push de chaque branche lançait un build, 480 (28 %) ont échoué après environ une minute de Build CPU. Le coût Vercel est presque entièrement du Build CPU ; le runtime est négligeable.
- 1 135 déploiements viennent des anciens dépôts reliés au projet avant le 01/10 ; 555 viennent du dépôt Orbit.
- Le 01/10, les PR #1 à #8 du dépôt Orbit totalisent 518 commits (451 pour la seule branche
rebuild/orbit-runtime, 445 déploiements en 4,6 h, un toutes les 3,8 s en médiane). - Aucun workflow GitHub ne pousse ni ne déploie (permissions en lecture seule, test
finops-policy.test.ts).
Les règles (tenues par des tests dans le dépôt de l'app)
| Règle | Où elle vit |
|---|---|
On commite autant que nécessaire, on pousse par lots, on lance pnpm premerge avant de pousser | AGENTS.md, skill platform-ops §9 |
Une preview est sur demande : [preview] dans le message du dernier commit du push | scripts/vercel-ignore.mjs |
Aucun build si rien de ce qui peut changer l'app web n'a bougé depuis le dernier déploiement réussi de la branche (app, dépendances workspace lues dans les package.json, lockfile, entrées racine) | idem, branché par ignoreCommand dans apps/web/vercel.json |
| En cas de doute (SHA inconnu, erreur git), le build a lieu : on n'ignore jamais à tort un déploiement de production | idem |
| Chaque provider payant a une ligne (déclencheur, facturation, budget, plafond, interrupteur, observabilité) ; une nouvelle variable provider sans ligne fait échouer les tests | apps/web/src/config/providers-ledger.ts |
Une alerte n'est pas un plafond : ORBIT_SPEND_CAP_USD fait refuser par le ledger toute réservation qui dépasserait la dépense réglée du mois (platform-cap) | moteur, ledger.integration.test.ts |
Un build de production sans changement de code (variable d'environnement modifiée) se fait par Redeploy manuel dans Vercel.
Réglages à poser dans les tableaux de bord (le dépôt ne peut pas les porter)
- Vercel → Settings → Billing → Spend Management : montant mensuel, case « Pause production deployment » à la limite ; Usage : alertes 50 / 75 / 100 %.
- Vercel → projet → Settings → Git : Root Directory
apps/web, « Include source files outside of the Root Directory » activé ; un seul dépôt connecté (BoostEcom/orbit.easyconnector.app). Ne pas poser d'Ignored Build Step dans le dashboard :vercel.jsonfait foi. - Variables Vercel :
ORBIT_SPEND_ALERT_USDetORBIT_SPEND_CAP_USD(cap supérieur à l'alerte). Tant qu'elles sont vides, aucune protection de dépense n'est active. Pour couper net les générations payantes : mettre une valeur minuscule dansORBIT_SPEND_CAP_USDet redéployer. - AI Gateway : recharge automatique désactivée (le crédit prépayé est la limite dure côté provider). ElevenLabs et Resend : dépassement (overage) désactivé. GitHub → Billing → Spending limit : 0 USD.
Neon : lire la facture des branch-hours
La base d'Orbit est la base Neon orbit-easyconnector-app, créée par le Marketplace Vercel, dans une organisation Neon gérée par Vercel (le connecteur Neon n'y voit aucun projet). Le dépôt ne crée aucune branche Neon. Si l'intégration est appliquée à « All Environments » avec la case « Create a database branch for each preview deployment » cochée, chaque branche git en preview peut en créer une.
Borne haute à partir des déploiements Vercel de ce projet : au plus ≈ 8 089 branch-hours si chacune des 92 branches git avait eu une branche Neon jusqu'au 03/10 (4,3 % de 186 979), au plus ≈ 108 019 h dans le scénario absurde d'une branche par déploiement jamais supprimée (58 %). Orbit ne peut donc pas expliquer seul cette facture.
À faire pour conclure :
- Vercel → Storage →
orbit-easyconnector-app→ Settings : décocher « Create a database branch for each preview deployment » ; supprimer les branchespreview/*restantes. - Neon (ouvert depuis cette page) → Billing / Usage : branch-hours par projet et par branche ; poser une alerte de consommation.
- Variable
DATABASE_URL: l'intégration injecte des nomsDATABASE_POSTGRES_*, mais l'app ne lit queDATABASE_URL. AjouterDATABASE_URL= l'URL poolée (Production et Preview) ; les migrations utilisent l'URL non poolée.
Crons
Trois crons, environ 4 380 déclenchements par mois, authentifiés par CRON_SECRET. generations-sweep (toutes les 10 min) est le filet des générations non réglées ; le ralentir allonge la récupération sans réduire la facture mesurée. Un cron toutes les 10 minutes réveille la base : à surveiller côté Neon (compute-hours).