Le blog

Infrastructure

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é.

Portrait de Raphaël Prasquier

Raphaël Prasquier

Infrastructure & sécurité applicative

Publié
Mis à jour
Lecture
11 min
Sur un fond nuit, une grande lampe de bureau lavande éteinte et, à son pied, une petite veilleuse menthe allumée.
Illustration conçue avec l’IA

Le problème : un GPU coûte surtout quand il ne fait rien

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.

Le veilleur

Architecture

Un veilleur à ~10 € par mois tient l’interrupteur d’un GPU à 1,50 € de l’heure

Votre posteAgent de codeopencode, T3 Code ou tout client compatible OpenAI, avec une clé personnelle.Garde l’historique en local
Veilleur · toujours alluméCaddy + veilleur.py
  1. Vérifie la clé (sinon 401, GPU jamais réveillé)
  2. Relaie en flux, sans écrire les corps
  3. Réveille le GPU : 503 + Retry-After
  4. L’éteint après 10 min de silence
Écrit : 1 ligne de métadonnées par requête
VM GPU · éteinte par défautvLLM · Qwen3.8-27BLe moteur n’écoute que sur l’adresse privée. Seul SSH est ouvert, aux adresses d’administration.Journaux du moteur : sans prompts ni réponses
API Scaleway le veilleur appelle poweron et poweroff
Le veilleur est une DEV1-S (~7 €/mois, ~10 € avec son adresse IP). Le GPU est une L40S ou deux L4, facturées à la minute.

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.

  1. Il authentifie. Une clé par personne, reconnue par son empreinte SHA-256. Sans clé valide, il répond 401 et 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.

  2. 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.

  3. 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."}}
  1. 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

  1. 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.
  2. 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. 3 min 35Première réponse du modèle, en flux. Aucune intervention humaine. ✓ 200
  4. +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.
Observation du 9 novembre 2026, client T3 Code via sa configuration opencode (délai d’attente de 600 s). La politique de reprise se vérifie pour chaque client.

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é.

L’interrupteur n’appartient pas à l’infra-as-code

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 apply met à 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.

Ce que ça coûte vraiment

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

Allumé en permanence : ~1 120 €
24 €
~100 €
~300 €
~430 €
Coût mensuel HT selon l’usage quotidien
Usage par jour ouvréCoût mensuel HT
0 h24 €
1 h~65 €
2 h~100 €
4 h~165 €
6 h~230 €
8 h~300 €
12 h~430 €
Allumé en permanence~1 120 €
Sans réveil : 24 € par mois. Pour h heures par jour ouvré : 24 € + 1,50 € × (h + 0,25) × 22. Hypothèses : une session par jour sans extinction intermédiaire, 5 min de démarrage et 10 min d’attente avant extinction ; tarifs publics Scaleway (Paris) ; installation et exploitation exclues.
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 permanence730 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.

Ce qu’on attend, en secondes

MomentMesuré, 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êt2 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.

Les angles morts

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.

Quand ne pas le faire

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

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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.

  6. 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.

  7. 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.

  8. 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.

  9. 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).

  10. 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.

  11. 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.

  12. vLLM Docs — Automatic Prefix Caching

    docs.vllm.ai · non daté · consulté le · Documentation stable (v0.33.0), section Introduction.

  13. 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.

Le scan gratuit

Et chez vous,
qu’est-ce qui est exposé ?

Nous examinons ce que vos équipes et prestataires livrent avec l’IA : code, infrastructure et accès aux données. Un humain relit chaque constat.

Demander le scan gratuit

Scan gratuit. Des failles détectées ? Le rapport détaillé est payant.