Un LLM privé qui coûte 24 € par mois quand il dort
Un GPU L40S allumé en continu coûte environ 1 100 € par mois. Pour trois développeurs, un « veilleur » en Python l’éteint après 10 minutes sans requête et le rallume à la demande : environ 24 € HT par mois au repos, 100 € pour deux heures par jour ouvré.

Auto-héberger un modèle de langage bute toujours sur la même ligne de facture. Chez Scaleway, un GPU L40S (48 Go de mémoire[1]) coûte 1,47 € HT de l’heure[2]. Allumé en continu, cela fait environ 1 100 € par mois[2].
Notre besoin était modeste : trois associés qui codent avec des agents, quelques heures par jour, rarement en même temps. Payer 730 heures par mois pour en utiliser une quarantaine, c’est financer plus de 90 % de sommeil.
La réponse habituelle est une API mutualisée, payée au token. Elle évite toute exploitation et c’est souvent le bon choix ; on y revient en fin d’article. Notre objectif était ailleurs : traiter les prompts sur des machines que nous administrons, en France, sans écrire leur contenu dans les journaux ni sur les disques de cette chaîne. Il nous fallait un serveur à nous, sans la facture d’un serveur allumé.
L’idée tient en une phrase : ne payer le GPU que quand il travaille. Scaleway facture le calcul GPU à la minute[3] ; une fois la machine éteinte, il ne reste que ses disques et son adresse IP[4]. Il ne manquait que quelqu’un pour tenir l’interrupteur.
Architecture
Un veilleur à ~10 € par mois tient l’interrupteur d’un GPU à 1,50 € de l’heure
- Vérifie la clé (sinon 401, GPU jamais réveillé)
- Relaie en flux, sans écrire les corps
- Réveille le GPU : 503 + Retry-After
- L’éteint après 10 min de silence
Devant le GPU, on a placé une petite machine toujours allumée, une DEV1-S à environ 7 € par mois[5], que nous avons appelée le veilleur. C’est le seul point d’entrée public. Sur le serveur GPU, le moteur d’inférence n’écoute que sur l’adresse privée ; seul SSH reste ouvert, aux adresses d’administration.
Le veilleur fait quatre choses, en 480 lignes de Python sans aucune dépendance externe.
Il authentifie. Une clé par personne, reconnue par son empreinte SHA-256. Sans clé valide, il répond
401et ne réveille jamais le GPU. C’est le premier piège à éviter : si n’importe quel robot qui scanne Internet peut allumer votre GPU, c’est vous qui payez ses visites.Il relaie. Les requêtes partent vers vLLM, le moteur d’inférence open source qui expose une API compatible OpenAI[6]. Les réponses reviennent en flux (SSE), morceau par morceau, sans que le veilleur écrive le corps des requêtes ni des réponses.
Il réveille. Une requête authentifiée arrive alors que le GPU dort : le veilleur demande à l’API de Scaleway de l’allumer, puis répond :
HTTP/1.1 503 Service Unavailable
Retry-After: 30
Content-Type: application/json
{"error": {"code": "gpu_starting", "message": "Le GPU démarre (3 à 5 min). Réessayez dans 30 s."}}
Il éteint. Toutes les 30 secondes, il vérifie deux conditions : aucune requête depuis dix minutes, et aucune en cours. Si les deux sont vraies, il éteint.
Le 503, ou l’art de ne rien coder côté client
Le plus agréable, dans ce design, c’est ce qu’il n’a pas fallu écrire côté client. Notre configuration opencode, que T3 Code réutilise, traverse le démarrage toute seule : elle réessaie après chaque 503, avec un délai d’attente porté à 600 secondes.
Mesuré, GPU éteint : message envoyé, quatre réponses « Le GPU démarre », puis la vraie réponse 3 min 35 après l’envoi, sans intervention. L’utilisateur voit un agent qui réfléchit un peu longtemps ; il ne voit pas une machine qui démarre. C’est une observation sur notre chaîne, pas une promesse pour tout client : la politique de reprise se vérifie outil par outil.
Mesuré · GPU éteint, 2 × L4
Un réveil à froid, vu par l’agent
- 0 sMessage envoyé. Le veilleur vérifie la clé, demande à Scaleway d’allumer le GPU, puis répond 503 « Le GPU démarre », avec Retry-After: 30.
- toutes les 30 sLe client réessaie seul. Quatre réponses « Le GPU démarre » pendant que la machine démarre et que vLLM charge le modèle.
- 3 min 35Première réponse du modèle, en flux. Aucune intervention humaine. ✓ 200
- +10 minsans requêteExtinction. Aucune requête en cours, aucune nouvelle depuis 10 minutes : le veilleur éteint le GPU, qui ne facture plus le calcul.
La règle qu’il fallait prouver
Le veilleur compte les requêtes en cours, et l’extinction attend qu’il n’y en ait plus aucune. La règle existait dès la première version ; aucun test ne la prouvait. Notre relecteur a refusé de valider sans un test unitaire : simuler une requête en cours au-delà du délai d’inactivité, vérifier que le GPU reste allumé, puis que l’extinction suit la fin de la requête. Ce test échoue si l’on retire la règle ; il protège le compteur, sans remplacer un essai avec une longue réponse réelle.
Ce genre de règle casse rarement en démonstration. Elle casse un après-midi de travail, quand un agent génère un long fichier.
Ce qu’il écrit, et ce qu’il n’écrit pas
Pour chaque requête, le veilleur écrit une seule ligne JSON dans le journal système de sa machine : horodatage, identifiant associé à la clé, chemin, statut HTTP, durée, et le décompte des tokens lorsqu’il est disponible. Jamais les corps, ni les clés elles-mêmes.
Compter les tokens d’une réponse en flux sans la stocker demande une astuce : si la requête ne contient pas de champ stream_options, le veilleur y ajoute {"include_usage": true}, pour que le moteur envoie le décompte à la fin du flux[7]. Un champ déjà présent reste inchangé, et le décompte peut alors manquer. Le veilleur garde en mémoire les 16 derniers kilo-octets du flux, le temps d’y chercher ce décompte.
C’est notre définition de la confidentialité : zéro contenu, pas zéro métadonnée. Nous l’avons confrontée à un test rejouable, dont nous détaillons la méthode et les limites dans un article dédié.
Toute l’infrastructure est décrite en OpenTofu, le fork open source de Terraform[8]. Une décision a compté plus que les autres : l’état allumé ou éteint du GPU n’appartient pas à OpenTofu.
resource "scaleway_instance_server" "gpu" {
type = var.gpu_types[0] # à la création ; ensuite, choisi par le veilleur
# …
lifecycle {
# Allumé/éteint et type appartiennent au veilleur, jamais à OpenTofu.
ignore_changes = [state, type]
}
}
Avec cette ligne, OpenTofu ignore l’état d’alimentation lors des mises à jour de la VM[9] : un tofu apply lancé par un collègue ne rallume pas un GPU à 1,50 € de l’heure que le veilleur venait d’éteindre. Elle ne protège pas, en revanche, d’une opération qui recréerait la machine[9]. L’allumage et l’extinction restent la responsabilité d’un seul composant. Deux autres règles vont dans le même sens.
- Le volume qui porte les poids du modèle (50 Go) est protégé contre la destruction (
prevent_destroy)[9]. Le retélécharger, c’est payer du GPU à attendre un téléchargement. - Changer de modèle est une variable.
tofu applymet à jour les métadonnées de la machine sans la recréer ; le nouveau modèle est chargé au prochain démarrage du service, ou au prochain réveil du GPU.
Même logique pour les utilisateurs : en ajouter un, c’est une ligne dans une liste. Le veilleur vérifie ses métadonnées chaque minute et se relance si elles ont changé, sans toucher au GPU ; une réponse en cours à ce moment-là peut être coupée.
Aux tarifs publics de Scaleway (région Paris, hors taxes) :
- un fixe d’environ 24 € par mois, GPU éteint : ~10 € de disques (système et poids)[10], ~7 € pour les deux adresses IPv4[11], ~7 € pour la machine du veilleur[5] ;
- environ 1,50 € par heure de GPU allumé (1,58 € en repli sur deux L4)[2], facturée à la minute[3].
Le calcul se fait donc en temps allumé, plus en tokens. Chaque reprise de travail après une extinction ajoute un démarrage (environ cinq minutes) et une traîne de dix minutes avant la prochaine extinction : environ un quart d’heure.
Coût mensuel, HT
Même à 12 h par jour, on reste loin du GPU allumé en permanence
| Usage par jour ouvré | Coût mensuel HT |
|---|---|
| 0 h | 24 € |
| 1 h | ~65 € |
| 2 h | ~100 € |
| 4 h | ~165 € |
| 6 h | ~230 € |
| 8 h | ~300 € |
| 12 h | ~430 € |
| Allumé en permanence | ~1 120 € |
| Usage du serveur partagé | Temps GPU allumé | Coût HT |
|---|---|---|
| Un message isolé, GPU éteint | ~15 min | ~0,40 € en plus du fixe |
| Une session d’une heure | ~1 h 15 | ~1,90 € en plus du fixe |
| 2 h par jour ouvré | ~50 h par mois | ~100 € par mois, fixe compris |
| 8 h par jour ouvré | ~180 h par mois | ~300 € par mois, fixe compris |
| Allumé en permanence | 730 h | ~1 120 € par mois |
Hypothèses : 22 jours ouvrés, une reprise par jour, des heures de serveur partagé (pas par personne). Installation et exploitation non comptées.
Deux conséquences pratiques. À durée d’allumage égale, plusieurs utilisateurs partagent la même facture ; ils partagent aussi la capacité du GPU. Et chaque minute de traîne coûte 2,5 centimes : nous sommes passés de 15 à 10 minutes. Plus court, on éteindrait entre deux questions et on rallongerait les attentes ; plus long, on paierait du sommeil.
| Moment | Mesuré, un utilisateur |
|---|---|
| Réveil complet, GPU éteint (2 × L4) | 3 min 35 entre l’envoi et la réponse |
| Allumage jusqu’au modèle prêt | 2 min 29 sur L40S ; 4 min 54 sur 2 × L4 (premier allumage) |
| Premier message d’une session d’agent | ~20 à 30 s |
| Génération de code | ~61 tokens/s sur L40S, ~44 sur 2 × L4 |
Le chiffre qui surprend est le troisième. Avant même votre question, opencode envoie, dans notre configuration, environ 20 000 tokens d’instructions et de définitions d’outils. Le modèle les lit à environ 1 000 tokens par seconde : une vingtaine de secondes de silence. Ensuite, le cache de préfixe de vLLM évite de recalculer ce début de conversation tant qu’il reste en mémoire[12], et les tours suivants repartent vite. Après une extinction, le cache disparaît ; sans lui, relire de longs contextes à chaque tour dégraderait fortement le confort.
La pénurie de GPU. C’est la vraie contrepartie de l’extinction. Chez Scaleway, une instance éteinte rend sa machine physique[3] : chaque rallumage doit en trouver une libre. Garder la machine réservée (le mode standby) est facturé comme allumé[3], ce qui annule l’intérêt. Nous l’avons vécu un lundi matin ; notre carnet de bord Scaleway raconte cette matinée. Le veilleur essaie alors deux L4 à la place du L40S ; si aucun des deux types n’est libre, il répond une erreur explicite (503 gpu_unavailable, Retry-After: 300), là où sa première version renvoyait un 502 muet.
Un point unique de panne, dans les deux sens. Si le veilleur tombe, plus personne n’accède au modèle. S’il tombe pendant que le GPU tourne, plus personne ne l’éteint, et la facture court. Une alerte indépendante, hébergée hors de Scaleway, prévient alors l’un de nous si le GPU tourne sans que le veilleur réponde, ou s’il reste allumé plus de quatre heures ; elle n’éteint rien.
Une capacité mesurée à un seul utilisateur. Le moteur traite au plus 16 séquences à la fois ; c’est ce réglage qui lui permet de démarrer, pas une garantie pour seize personnes. Nos débits ont été mesurés avec un seul utilisateur. Au-delà de quelques personnes actives en même temps, il faut un test de charge, et probablement un GPU plus gros.
Un prototype pour trois associés. Le veilleur n’a plus la clé cloud d’OpenTofu : la sienne est limitée aux instances du projet, celle du veilleur comprise, et sa rotation est décrite. Chaque clé d’accès est limitée à 60 requêtes par minute et à 4 requêtes simultanées. Seuls les administrateurs peuvent éteindre le GPU à la main, et une telle extinction coupe encore les réponses en cours. L’extinction automatique, elle, est décidée sous le même verrou que l’admission des requêtes : une requête admise n’est plus coupée, et celle qui arrive pendant l’extinction rallumera le GPU. Avant un usage client, il manque un plafond de dépense actif : celui du veilleur existe, mais il est désactivé, et un redémarrage du veilleur le remettrait à zéro.
Ne choisissez pas cette architecture sur la seule promesse d’économies. À faible consommation de tokens, une API mutualisée évite le coût fixe et toute l’exploitation. Pour un agent qui renvoie de longs contextes à chaque tour, le résultat dépend des tarifs d’entrée, de sortie et de cache de l’API : l’ordre peut s’inverser. Nous n’avons pas établi de seuil de rentabilité à qualité comparable ; ce projet répond d’abord à un besoin de contrôle des données.
Ne le faites pas non plus si :
- vous avez besoin du meilleur modèle du marché : un modèle ouvert de 27 milliards de paramètres[13] n’est ni Claude ni GPT ;
- votre usage est quasi continu : l’extinction n’apporte plus rien, comparez avec une machine louée au mois ;
- vous ne pouvez pas tolérer qu’un matin, faute de GPU disponible, le service ne démarre pas.
Faites-le si la question « où sont traités nos prompts ? » a de la valeur pour vous ou pour vos clients. Pour notre petite équipe, l’infrastructure coûte environ 24 € HT par mois au repos, plus 1,50 € par heure de GPU allumé.
Sources
NVIDIA — L40S GPU for AI and Graphics Performance
nvidia.com · non daté · consulté le · Fiche produit vivante, section « NVIDIA L40S GPU Specifications » : 48 Go de mémoire GDDR6 avec ECC.
Scaleway — GPU Instances Pricing
scaleway.com · non daté · consulté le · Grille vivante, prix avant taxes, zone PAR-2 : L40S-1-48G à 1,47 € l’heure (environ 1 073 € par mois) ; L4-2-24G (deux L4) à 1,58 € l’heure.
Scaleway Documentation — Instances FAQ
scaleway.com · non daté · consulté le · Page revue le 19 décembre 2025. Instances GPU facturées à la minute de fonctionnement ; « power off » rend la machine physique au pool ; le mode standby est facturé comme une instance allumée.
Scaleway Documentation — How to power off your Instance
scaleway.com · non daté · consulté le · Page revue le 17 septembre 2025 : une instance éteinte ne facture que ses volumes et son adresse IP flexible réservée.
Scaleway — Virtual Instances Pricing
scaleway.com · non daté · consulté le · Grille vivante, prix avant taxes : DEV1-S à 0,00898 € l’heure, environ 6,55 € par mois, stockage et IPv4 exclus.
vLLM (GitHub) — vllm-project/vllm
github.com · non daté · consulté le · Dépôt du projet, licence Apache-2.0 ; le README annonce un serveur d’API compatible OpenAI.
vLLM Docs — Per-Request Metrics
docs.vllm.ai · non daté · consulté le · Documentation stable (v0.33.0, la version servie par notre prototype) : en flux, le décompte d’usage arrive dans un dernier morceau, envoyé après le contenu quand stream_options.include_usage vaut true.
OpenTofu (Linux Foundation) — OpenTofu
opentofu.org · non daté · consulté le · Page d’accueil, question « Why was OpenTofu created? » : fork de Terraform, créé après le passage de HashiCorp à la licence BUSL.
OpenTofu Docs — Resource Behavior
opentofu.org · non daté · consulté le · Documentation vivante, personnalisations du cycle de vie : prevent_destroy, ignore_changes (attributs pris en compte à la création, ignorés lors des mises à jour).
Scaleway — Storage Pricing
scaleway.com · non daté · consulté le · Grille vivante, prix avant taxes : Block Storage 5K, région Paris, 0,000130 € par Go et par heure.
Scaleway — Network Pricing
scaleway.com · non daté · consulté le · Grille vivante, prix avant taxes : adresse IPv4 supplémentaire d’une instance, 0,005 € l’heure.
vLLM Docs — Automatic Prefix Caching
docs.vllm.ai · non daté · consulté le · Documentation stable (v0.33.0), section Introduction.
Qwen (Hugging Face) — Qwen/Qwen3.8-27B-FP8
huggingface.co · non daté · consulté le · Fiche vivante du modèle servi par notre prototype, dépôt créé le 13 août 2026 : 27 milliards de paramètres, licence Apache 2.0.

