Quelle RAM pour un VPS avec un agent de programmation ?
Un agent toujours actif tient sur 4 Go et 2 vCPU. Ce sont les builds et language servers lancés qui saturent le VPS et le font se bloquer.
De quelle quantité de RAM un VPS pour agent de programmation a-t-il besoin ?
Commencez avec 4 Go de RAM et 2 vCPU pour un agent de programmation toujours actif qui travaille dans un dépôt. Passez à 8 Go et 4 vCPU dès qu’un language server ou un build Docker rejoint la session. Dans la plupart des dépôts, cela arrive dès le premier jour. Le processus de l’agent lui-même consomme peu de ressources. C’est la toolchain qu’il pilote pour vous qui remplit la machine.
The data behind this chart
[
{
"plan": "Minimum viable",
"ram_gb": 4,
"vcpu": 2,
"disk_gb": 50
},
{
"plan": "Comfortable",
"ram_gb": 8,
"vcpu": 4,
"disk_gb": 100
},
{
"plan": "Team, 4 sessions",
"ram_gb": 16,
"vcpu": 8,
"disk_gb": 200
}
]Chaque ligne ci-dessus suppose que le modèle s’exécute ailleurs, derrière une API appelée sur le réseau. Cette hypothèse détermine toute la question du dimensionnement. Il faut donc commencer par la vérifier.
Vous exécutez l’agent ou le modèle ?
Un agent de codage qui appelle un modèle cloud est un client réseau auquel est attaché un shell. Il envoie des fichiers et un plan à une API, attend la réponse, puis modifie les fichiers et exécute des commandes localement. Pendant cette attente, il utilise presque aucun CPU. Sa propre consommation mémoire se mesure en centaines de mégaoctets. C’est pourquoi une machine dotée d’un CPU modeste convient.
Exécuter vous-même le modèle correspond à un autre produit, sur un autre matériel. Les poids restent en mémoire tant que le serveur fonctionne. Un modèle de 7 milliards de paramètres, quantifié sur 4 bits, nécessite environ 5 GB rien que pour les poids, avant de prendre en compte le cache clé/valeur, qui augmente avec la longueur du contexte. En mode CPU uniquement, un vCPU partagé produit quelques tokens par seconde. Une seule tâche d’agent peut générer des milliers de tokens. Un travail qui prend moins d’une minute via une API nécessite donc presque une heure en local. Si c’est ce que vous recherchez, dimensionnez la mémoire VRAM (mémoire vidéo du GPU) et consultez ce qu’un VPS avec un GPU fournit réellement plutôt que cette page.
Tout ce qui suit suppose que vous utilisez un modèle cloud.
Ce qui utilise réellement la mémoire
The data behind this chart
[
{
"label": "Agent CLI process, idle",
"typical_mb": 250,
"peak_mb": 600
},
{
"label": "TypeScript language server",
"typical_mb": 700,
"peak_mb": 2000
},
{
"label": "rust-analyzer, large workspace",
"typical_mb": 1200,
"peak_mb": 4000
},
{
"label": "Headless Chrome, one tab",
"typical_mb": 350,
"peak_mb": 900
},
{
"label": "Node test run, 4 workers",
"typical_mb": 1600,
"peak_mb": 3000
},
{
"label": "Docker image build",
"typical_mb": 800,
"peak_mb": 2500
}
]Il s’agit de valeurs typiques publiées pour des projets de taille moyenne. Considérez-les comme un ordre de grandeur, pas comme une garantie pour votre code.
Le graphique contient 6 lignes et l’agent est le moins coûteux. Il utilise environ 250 Mo au repos, car il conserve une conversation et un petit cache de fichiers, sans rien d’autre. Un language server TypeScript atteint environ 2000 Mo pendant l’indexation, car il construit un graphe de types pour chaque fichier accessible depuis votre tsconfig.json, puis conserve ce graphe en mémoire pour répondre plus rapidement à la requête suivante. Sur un workspace volumineux, rust-analyzer dépasse généralement 4000 Mo pour la même raison, sur l’ensemble des crates du workspace.
Headless Chrome utilise environ 350 Mo pour le navigateur et un onglet. Chaque onglet supplémentaire correspond à un autre processus du système d’exploitation. Une exécution de tests Node avec quatre workers utilise quatre processus Node et atteint donc environ 3000 Mo. Un build d’image Docker atteint environ 2500 Mo, car le build exécute le compilateur de votre projet dans le conteneur tandis que le daemon écrit les layers.
Mesurez ces valeurs sur votre propre dépôt avant d’acheter
sudo apt update && sudo apt install -y time
/usr/bin/time -v -o /tmp/build.rusage npm run build
grep "Maximum resident set size" /tmp/build.rusageLa réponse renvoyée est Maximum resident set size (kbytes): 1842160. Divisez cette valeur par 1024 pour obtenir des Mo. GNU time indique la taille maximale du processus unique qu’il a attendu. Un build qui lance quatre workers peut donc afficher une valeur faible. Dans ce cas, surveillez l’ensemble de la machine depuis un deuxième shell avec free -h ou systemd-cgtop -m.
Lisez la colonne available de free -h, et non la colonne free. Linux utilise chaque page libre pour le cache disque. Ainsi, free reste faible sur une machine parfaitement saine et ne vous apprend rien. available indique la mémoire qu’un nouveau processus peut réellement obtenir.
Trois configurations qui fonctionnent
Configuration minimale viable : 4 Go de RAM, 2 vCPU, 50 Go de disque. Une session d’agent, un dépôt, un language server et des builds pour lesquels vous acceptez d’attendre. Cette configuration fonctionne, mais elle déclenchera l’out-of-memory killer dès qu’une grosse série de tests s’exécutera en même temps qu’un language server qui indexe le code. Ajoutez du swap et limitez le nombre de workers de build.
Configuration confortable : 8 Go de RAM, 4 vCPU, 100 Go de disque. Un agent, Docker et un navigateur headless pour les tests, avec suffisamment de marge pour un pic de build. C’est la configuration que la plupart des développeurs seuls devraient choisir. Doubler le nombre de vCPU réduit aussi environ de moitié l’attente des builds, et vous le remarquerez bien plus souvent que la mémoire disponible.
Configuration pour une équipe : 16 Go de RAM, 8 vCPU, 200 Go de disque. Quatre sessions simultanées, chacune avec son propre checkout et sa propre toolchain. Dimensionnez le serveur pour le pic de charge : quatre agents inactifs coûtent presque rien, tandis que quatre séries de tests exécutées au même moment coûtent quatre fois le montant indiqué dans la colonne de pic ci-dessus.
En août 2026, le passage de la première ligne à la dernière représente environ quatre fois le prix mensuel avec une facturation annuelle d’un VPS : quelques dollars par mois pour la configuration minimale, plusieurs dizaines pour la configuration maximale. Consultez l’offre actuelle avant de planifier votre budget, car ces montants évoluent. Le serveur est rarement le poste le plus coûteux. Pour les utilisateurs qui pilotent un agent chaque jour, la facture de l’API du modèle dépasse rapidement celle du serveur. Limitez donc les dépenses autorisées pour l’agent avant de réduire la taille du serveur. Pour le build lui-même, le guide pour exécuter un coding agent sur un VPS explique la configuration du compte et le maintien de la session après votre déconnexion.
Pourquoi vous manquez d’espace disque avant de manquer de RAM
The data behind this chart
[
{
"label": "Ubuntu 24.04 base and toolchain",
"typical_gb": 6
},
{
"label": "One JS monorepo checkout",
"typical_gb": 3
},
{
"label": "node_modules across 3 branches",
"typical_gb": 4
},
{
"label": "Docker images and build cache",
"typical_gb": 20
},
{
"label": "Agent logs and journal, 90 days",
"typical_gb": 2
}
]Additionnez ces lignes : un disque de 50 Go est presque plein avant même que vous ayez écrit une ligne de code. Le plus gros élément est Docker, avec environ 20 Go, car BuildKit conserve chaque couche intermédiaire de chaque build jusqu’à ce que vous lui demandiez de les supprimer.
docker system df
docker builder prune --filter until=168hdocker system df affiche l’espace récupérable par catégorie. Exécutez-le donc avant et après le nettoyage. Le filtre until=168h supprime le build cache de plus d’une semaine et conserve celui de la semaine en cours, qui vous fait encore gagner du temps. docker image prune -a va plus loin et supprime toutes les images qu’aucun conteneur n’utilise. Le prochain build devra donc les télécharger à nouveau.
Les projets Node posent un problème plus difficile à diagnostiquer. npm install crée des centaines de milliers de petits fichiers. Le filesystem peut donc manquer d’inodes alors que df -h indique toujours plusieurs gigaoctets libres. L’écriture échoue alors avec No space left on device sur un disque qui semble à moitié vide.
df -h /
df -i /Si IUse% renvoie 100, supprimez les répertoires node_modules des branches sur lesquelles vous ne travaillez plus, ou utilisez pnpm. Celui-ci ne stocke chaque version d’un package qu’une seule fois et crée des hard links vers cette version dans chaque projet.
Les logs sont le problème le plus discret. Un agent toujours actif écrit les transcriptions des sessions, et le journal systemd occupe par défaut une partie croissante du disque.
sudo journalctl --disk-usage
sudo journalctl --vacuum-size=200M
du -xh --max-depth=1 / 2>/dev/null | sort -h | tailDéfinissez SystemMaxUse=200M dans /etc/systemd/journald.conf, puis exécutez sudo systemctl restart systemd-journald pour rendre cette limite permanente. Un vacuum ponctuel ne libère en effet que l’espace du jour.
Swap : ce que cela apporte et ce que cela masque
Il est utile d’ajouter du swap, car un léger dépassement de capacité ralentit le processus au lieu de l’arrêter. Dimensionnez-le à la moitié de la RAM, avec un maximum d’environ 4 GB. Il y a peu de raisons d’aller au-delà sur un serveur de build.
sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
swapon --showswapon --show doit maintenant afficher /swapfile avec la taille demandée. Sans la ligne /etc/fstab, le swap disparaît au prochain redémarrage et le serveur reprend discrètement son ancien comportement. Si fallocate renvoie Operation not supported, créez le fichier avec sudo dd if=/dev/zero of=/swapfile bs=1M count=4096, puis poursuivez à partir de chmod.
echo 'vm.swappiness = 10' | sudo tee /etc/sysctl.d/99-swappiness.conf
sudo sysctl --systemUne valeur faible de swappiness indique au kernel de récupérer le cache disque avant de déplacer la mémoire des programmes vers le disque. Cela permet au language server de rester réactif.
C’est maintenant la partie que le swap masque. Lorsqu’un job a réellement besoin de plus de mémoire que le serveur n’en possède, le kernel passe son temps à déplacer des pages entre la RAM et le disque au lieu d’exécuter le build. Rien ne plante. Tout devient très lent et la load average augmente alors que le CPU reste inactif.
vmstat 1 10Des valeurs constamment différentes de zéro dans les colonnes si et so indiquent un swapping continu. La solution consiste donc à réduire la concurrence ou à ajouter de la RAM, et jamais à ajouter davantage de swap. Sur un petit serveur, sudo apt install -y zram-tools fournit un swap compressé conservé en RAM, configuré dans /etc/default/zramswap. Il est bien plus rapide qu’un fichier de swap. Il consomme toutefois de la RAM pour économiser de la RAM : il aide pour les pages froides, mais pas pour un build qui a réellement besoin de mémoire de travail.
Pourquoi votre agent de programmation semble bloqué
C’est l’échec le plus souvent mal diagnostiqué sur un petit serveur exécutant un agent. Une commande ne renvoie rien, l’agent attend et la session semble figée. Le processus a été tué par l’OOM killer du noyau. Il a reçu SIGKILL. Il n’a donc pas pu afficher d’erreur, vider un journal ni informer l’agent de ce qui s’était passé. L’agent ne voit qu’un résultat vide et aucun message de sortie.
Le noyau l’enregistre pourtant :
sudo dmesg -T | grep -iE "out of memory|killed process"
sudo journalctl -k -b | grep -i oomUne ligne réelle ressemble à ceci :
[Thu Aug 6 11:02:14 2026] Out of memory: Killed process 4711 (node) total-vm:4210880kB, anon-rss:3820104kB, file-rss:0kB, shmem-rss:0kB, UID:1000 pgtables:8236kB oom_score_adj:0anon-rss indique la quantité de mémoire détenue par ce processus lorsqu’il a été tué. Notez quel processus a été choisi : le noyau se base principalement sur la mémoire utilisée. Il tue donc souvent le language server ou l’agent plutôt que le build qui a fait dépasser la limite au serveur. C’est précisément pourquoi le symptôme donne l’impression que « l’agent est tombé en panne ».
Dans Docker, le même événement laisse une trace plus claire. Le conteneur se termine avec le code 137, soit 128 plus le signal 9.
docker ps -a
docker inspect "$(docker ps -lq)" | grep -i oomkilled"OOMKilled": true confirme que le conteneur a atteint sa limite de mémoire au lieu de planter de lui-même.
La solution consiste à imposer une limite propre à la commande coûteuse. Le build s’arrête alors avant l’agent :
systemd-run --user --scope -p MemoryMax=4G -- npm run buildLe build est maintenant tué à 4 GB et l’agent reste actif. Un blocage mystérieux devient ainsi une commande échouée ordinaire, avec un code de sortie lisible. Cela nécessite une session utilisateur systemd. Exécutez donc loginctl enable-linger $USER sur un serveur auquel vous accédez uniquement via SSH. MemoryHigh= limite le processus lorsqu’il atteint le seuil au lieu de le tuer. C’est souvent le réglage le plus adapté pour un build que vous préférez laisser se terminer lentement.
Plafonnez-le une fois avec les limites mémoire de Compose
Si les outils de l’agent s’exécutent dans des conteneurs, définissez la limite dans le fichier Compose pour qu’elle s’applique à chaque exécution.
services:
agent:
image: node:22-bookworm
deploy:
resources:
limits:
memory: 2g
cpus: "1.5"Docker Compose v2 applique deploy.resources.limits avec un simple docker compose up ; le mode swarm n’intervient donc pas. L’ancienne clé mem_limit: 2g fonctionne toujours. Le guide complet des limites mémoire de Compose explique les réservations et ce qui se produit lorsqu’un conteneur atteint sa limite. Si Docker n’est pas encore installé sur le serveur, installez Docker sur un VPS d’abord.
Un piège peut vous faire perdre une après-midi. Un conteneur limité à 2 GB lit toujours le /proc/meminfo de l’hôte et le nombre de CPU de l’hôte, car aucun des deux n’est isolé par un namespace. Un test runner qui choisit le nombre de workers à partir du nombre de CPU lancera huit workers dans un conteneur de 2 GB sur un hôte doté de huit vCPU, puis s’arrêtera avec le code 137. Définissez ces valeurs manuellement :
npx jest --maxWorkers=2
export NODE_OPTIONS=--max-old-space-size=1536--max-old-space-size est exprimé en MB et plafonne le heap V8. Définissez-le en dessous de la limite du conteneur afin que Node génère une erreur lisible au lieu de disparaître :
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memoryCe message est utile, car il indique la limite atteinte et le processus qui l’a atteinte. L’OOM killer ne fournit jamais ces informations.
Exécuter plusieurs sessions d’agent sur un même serveur
Dimensionnez par session, pas par personne. Deux sessions sur le même dépôt impliquent tout de même deux language servers, deux ensembles de caches de build en mémoire et deux exécutions de tests si les deux agents sont sollicités au même moment. C’est pourquoi la ligne de l’équipe passe à 16 GB.
Définissez une limite stricte pour chaque utilisateur afin qu’une session hors de contrôle ne puisse pas saturer le serveur :
id -u alice
sudo mkdir -p /etc/systemd/system/user-1001.slice.d
printf '[Slice]\nMemoryMax=6G\n' | sudo tee /etc/systemd/system/user-1001.slice.d/limit.conf
sudo systemctl daemon-reload
systemctl show user-1001.slice -p MemoryMaxRemplacez 1001 par l’UID affiché par id -u. systemctl show doit afficher MemoryMax=6442450944 une fois que l’utilisateur s’est connecté. Lorsque l’ensemble des processus de la session de cet utilisateur dépasse 6 GB, le kernel tue un processus dans son slice et toutes les autres sessions continuent de fonctionner. Pour un agent qui s’exécute comme un service plutôt que dans un terminal, placez MemoryMax= dans son unit file. C’est le modèle à suivre lorsque vous hébergez vous-même un agent comme service permanent.
FAQ
2 GB de RAM suffisent-ils pour un agent de codage ?
Pour le processus de l’agent, oui. Pour les tâches qu’il exécute, rarement. L’agent utilise environ 250 MB, mais un seul serveur de langage TypeScript peut atteindre 2000 MB sur un dépôt de taille moyenne. Cela suffit à faire passer une machine de 2 GB en swap. 2 GB conviennent pour modifier des fichiers de configuration et de petits scripts. Utilisez 4 GB comme minimum pour tout ce qui compile ou exécute une suite de tests.
Ai-je besoin d’un GPU pour exécuter un agent de codage sur un VPS ?
Non, si l’agent appelle un modèle cloud via une API. Cette charge dépend du réseau. Un VPS avec un simple CPU est donc adapté, tandis qu’un GPU reste inutilisé pour un prix beaucoup plus élevé. Vous avez besoin d’un GPU uniquement lorsque le modèle s’exécute sur la même machine. La question porte alors sur la VRAM et la taille du modèle, et non plus sur la RAM.
Quelle quantité de swap dois-je ajouter à un VPS qui héberge un agent ?
La moitié de la RAM, dans la limite d’environ 4 GB. Le swap vous protège contre un dépassement ponctuel. Le kernel peut déplacer des pages peu utilisées vers le disque au lieu de tuer un processus. Le swap n’ajoute pas de mémoire utilisable. Si vmstat 1 affiche un trafic constant dans les colonnes si et so, la machine est en thrashing. Réduisez le nombre de workers parallèles ou choisissez un plan plus grand.
Pourquoi mon agent de codage se bloque-t-il au milieu d’un build ?
Le build a presque certainement été tué par l’OOM killer du kernel, qui envoie SIGKILL. Aucun message ne s’affiche donc, et l’agent attend sur un pipe qui ne reçoit plus de données. Exécutez sudo dmesg -T | grep -i "killed process" et examinez le nom du processus ainsi que sa valeur anon-rss. Pour corriger le problème, limitez le build avec systemd-run --user --scope -p MemoryMax=4G et réduisez le nombre de workers, ou passez au niveau de RAM supérieur.