Quanta RAM serve a un VPS per un coding agent?
Un coding agent sempre attivo usa 4 GB e 2 vCPU. Sono build e language server a saturare il VPS e a causare blocchi, non l'agent stesso.
Quanta RAM richiede un VPS per un agente di programmazione?
Inizia con 4 GB di RAM e 2 vCPU per un solo agente di programmazione sempre attivo che lavora in un repository. Passa a 8 GB e 4 vCPU non appena nella sessione si aggiunge un language server o una build Docker; per la maggior parte dei repository questo avviene già dal primo giorno. Il processo dell'agente occupa poca memoria. A saturare le risorse è invece la toolchain che l'agente esegue per tuo conto.
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
}
]Ogni riga precedente presuppone che il modello venga eseguito altrove, tramite un'API che richiami sulla rete. Questa ipotesi determina l'intero dimensionamento. Verificala prima di procedere.
Esegui l’agent oppure il modello?
Un agent di coding che chiama un modello cloud è un client di rete con una shell collegata. Invia i file e un piano a un’API, attende la risposta, quindi modifica i file ed esegue i comandi localmente. Durante l’attesa utilizza quasi nulla della CPU. La memoria utilizzata direttamente dall’agent si misura in centinaia di megabyte. Per questo un server con CPU di fascia modesta è la macchina corretta.
Eseguire direttamente il modello richiede un prodotto diverso e hardware diverso. I pesi restano in memoria per tutta la durata del server. Un modello con 7 miliardi di parametri, quantizzato a 4 bit, richiede circa 5 GB soltanto per i pesi, prima di considerare la cache key/value, che cresce con la lunghezza del contesto. Usando soltanto la CPU, una vCPU condivisa genera pochi token al secondo. Una singola attività dell’agent può produrre migliaia di token. Di conseguenza, un lavoro che tramite un’API richiede meno di un minuto può richiedere quasi un’ora in locale. Se è questo ciò che ti serve, dimensiona il sistema in base alla VRAM (memoria video della GPU) e leggi cosa offre realmente un VPS con una GPU invece di questa pagina.
Tutto ciò che segue presuppone l’utilizzo di un modello cloud.
Cosa usa effettivamente la memoria
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
}
]Questi sono valori tipici pubblicati per progetti di dimensioni medie. Considerali come un ordine di grandezza, non come una garanzia per il tuo codice.
Il grafico contiene 6 righe e l'agent è il componente meno costoso. In condizioni di inattività usa circa 250 MB, perché mantiene una conversazione, una piccola cache dei file e nient'altro. Un language server TypeScript raggiunge circa 2000 MB durante l'indicizzazione, perché costruisce un grafo dei tipi per ogni file raggiungibile dal tuo tsconfig.json e mantiene quindi il grafo in memoria per rispondere più rapidamente alla richiesta successiva. In un workspace di grandi dimensioni, rust-analyzer supera comunemente 4000 MB per lo stesso motivo, considerando ogni crate del workspace.
Headless Chrome usa circa 350 MB per il browser e una scheda, mentre ogni scheda aggiuntiva corrisponde a un altro processo del sistema operativo. Un'esecuzione di test Node con quattro worker avvia quattro processi Node, quindi raggiunge un picco vicino a 3000 MB. La build di un'immagine Docker raggiunge un picco vicino a 2500 MB, perché la build esegue il compilatore del progetto all'interno del container mentre il daemon scrive i layer.
Misura questi valori nel tuo repository prima dell'acquisto
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.rusageIl risultato viene restituito come Maximum resident set size (kbytes): 1842160. Dividilo per 1024 per ottenere i MB. GNU time restituisce il processo singolo di cui ha atteso la terminazione e che ha raggiunto il valore massimo, quindi una build che avvia quattro worker può riportare un valore troppo basso. In questi casi, monitora l'intero host da una seconda shell con free -h o systemd-cgtop -m.
Leggi la colonna available di free -h, non la colonna free. Linux utilizza ogni pagina libera per la cache del disco, quindi free è basso anche su un host perfettamente integro e non fornisce informazioni utili. available indica la memoria che un nuovo processo può effettivamente ottenere.
Tre configurazioni operative
Configurazione minima: 4 GB di RAM, 2 vCPU, 50 GB di disco. Una sessione dell'agente, un repository, un language server e build per cui si è disposti ad attendere. Questo livello funziona, ma il processo OOM killer terminerà la prima sessione in cui un test di grandi dimensioni coincide con l'indicizzazione del language server. Aggiungete swap e limitate il numero di worker della build.
Configurazione confortevole: 8 GB di RAM, 4 vCPU, 100 GB di disco. Un agente, Docker e un browser headless per i test, con margine sufficiente per un picco della build. È il livello che la maggior parte degli sviluppatori singoli dovrebbe scegliere. Raddoppiare il numero di vCPU dimezza all'incirca anche il tempo di attesa della build, e questo si nota molto più spesso della memoria disponibile.
Configurazione per un team: 16 GB di RAM, 8 vCPU, 200 GB di disco. Quattro sessioni simultanee, ciascuna con il proprio checkout e la propria toolchain. Dimensionate il server per il carico di picco, perché quattro agenti inattivi hanno un costo quasi nullo, mentre quattro esecuzioni di test simultanee costano quattro volte il valore di picco della colonna precedente.
Ad agosto 2026, il passaggio dalla prima all'ultima riga corrisponde all'incirca a un prezzo mensile quattro volte superiore con la fatturazione annuale di un VPS: pochi dollari al mese per la configurazione minima, decine di dollari per quella massima. Verificate l'offerta corrente prima di pianificare, perché questi prezzi cambiano. Il server è raramente la voce di costo maggiore. Per chi usa un agente ogni giorno, il costo dell'API del modello supera rapidamente quello del server; quindi limitate la spesa consentita all'agente prima di ridurre le dimensioni del server. Per la build, la procedura per eseguire un agente di coding su un VPS descrive la configurazione dell'account e come mantenere attiva la sessione dopo la disconnessione.
Perché lo spazio su disco si esaurisce prima della 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
}
]Sommando queste righe, un disco da 50 GB è quasi pieno prima ancora di scrivere una riga di codice. L'elemento singolo più grande è Docker, con circa 20 GB, perché BuildKit conserva ogni layer intermedio di ogni build finché non gli si ordina di eliminarlo.
docker system df
docker builder prune --filter until=168hdocker system df mostra lo spazio recuperabile per categoria, quindi eseguilo prima e dopo la pulizia. Il filtro until=168h elimina la build cache più vecchia di una settimana e conserva quella della settimana corrente, che è ancora utile per ridurre i tempi. docker image prune -a va oltre e rimuove ogni immagine non utilizzata da alcun container; la build successiva dovrà quindi scaricarla di nuovo.
I progetti Node falliscono in modo meno evidente. npm install crea centinaia di migliaia di file piccoli, quindi il filesystem può esaurire gli inode mentre df -h segnala ancora gigabyte liberi. La scrittura fallisce quindi con No space left on device anche se il disco sembra utilizzato solo a metà.
df -h /
df -i /Se IUse% restituisce 100, elimina le directory node_modules dei branch su cui non lavori più oppure passa a pnpm, che memorizza ogni versione di un pacchetto una sola volta e crea hard link verso il pacchetto in ogni progetto.
I log sono il problema meno evidente. Un agent sempre attivo scrive le trascrizioni delle sessioni e il journal di systemd può occupare una parte significativa del disco con la configurazione predefinita.
sudo journalctl --disk-usage
sudo journalctl --vacuum-size=200M
du -xh --max-depth=1 / 2>/dev/null | sort -h | tailImposta SystemMaxUse=200M in /etc/systemd/journald.conf ed esegui sudo systemctl restart systemd-journald per rendere permanente questo limite, perché una pulizia una tantum recupera spazio solo temporaneamente.
Swap: cosa offre e cosa nasconde
Conviene aggiungere lo swap, perché trasforma un piccolo superamento della memoria disponibile in un'elaborazione lenta invece che in un processo terminato. Impostare una dimensione pari alla metà della RAM, fino a circa 4 GB. Su un server di build, di norma non serve andare oltre.
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 dovrebbe ora elencare /swapfile con la dimensione richiesta. Senza la riga /etc/fstab, lo swap scompare al riavvio successivo e il server torna silenziosamente al comportamento precedente. Se fallocate restituisce Operation not supported, creare il file con sudo dd if=/dev/zero of=/swapfile bs=1M count=4096 e procedere da chmod.
echo 'vm.swappiness = 10' | sudo tee /etc/sysctl.d/99-swappiness.conf
sudo sysctl --systemUn valore basso di swappiness indica al kernel di liberare prima la cache del disco, invece di spostare la memoria dei programmi sul disco. In questo modo il language server rimane reattivo.
Ora vediamo cosa nasconde lo swap. Quando un job richiede realmente più memoria di quella disponibile sul server, il kernel passa il tempo a spostare pagine tra RAM e disco invece di eseguire la build. Non si verifica alcun crash. Tutto rallenta e il load average aumenta mentre la CPU rimane inattiva.
vmstat 1 10Valori costantemente diversi da zero nelle colonne si e so indicano uno swapping continuo. La soluzione consiste nel ridurre la concorrenza o aumentare la RAM, mai nell'aggiungere altro swap. Su un server di piccole dimensioni, sudo apt install -y zram-tools fornisce swap compresso mantenuto in RAM, configurato in /etc/default/zramswap. È molto più veloce di un file di swap, ma usa RAM per risparmiare RAM. Aiuta quindi con le pagine fredde, non con una build che richiede memoria di lavoro effettiva.
Perché il coding agent sembra bloccarsi
Questo è il problema diagnosticato più spesso in modo errato su un piccolo server che esegue un agent. Un comando non restituisce nulla, l’agent resta in attesa e la sessione sembra bloccata. Il processo è stato terminato dal kernel tramite l’OOM killer per esaurimento della memoria. Ha ricevuto SIGKILL, quindi non ha potuto stampare un errore, scaricare un log o comunicare all’agent che cosa era successo. L’agent vede un risultato vuoto e nessun messaggio di uscita.
Il kernel registra comunque l’evento:
sudo dmesg -T | grep -iE "out of memory|killed process"
sudo journalctl -k -b | grep -i oomUna riga reale è simile alla seguente:
[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 indica la quantità di memoria detenuta dal processo quando è stato terminato. Osservare quale processo è stato scelto: il kernel assegna il punteggio principalmente in base alla memoria in uso, quindi spesso termina il language server o l’agent invece del processo di build che ha portato il server oltre il limite. Per questo il sintomo sembra indicare che “l’agent si è bloccato”.
All’interno di Docker, lo stesso evento lascia una traccia più chiara. Il container termina con il codice 137, cioè 128 più il segnale 9.
docker ps -a
docker inspect "$(docker ps -lq)" | grep -i oomkilled"OOMKilled": true conferma che il container ha raggiunto il proprio limite di memoria, invece di terminare a causa di un crash autonomo.
La soluzione consiste nell’imporre un limite separato al comando oneroso, in modo che venga terminata la build e non l’agent:
systemd-run --user --scope -p MemoryMax=4G -- npm run buildLa build viene ora terminata a 4 GB e l’agent rimane attivo. Un blocco apparentemente inspiegabile diventa così un normale comando non riuscito, con un codice di uscita leggibile. Questa configurazione richiede una sessione utente di systemd, quindi eseguire loginctl enable-linger $USER su un server accessibile soltanto tramite SSH. MemoryHigh= limita il processo al raggiungimento della soglia invece di terminarlo. Questa impostazione è spesso preferibile per una build che si vuole lasciare completare più lentamente.
Impostare una volta sola i limiti di memoria con Compose
Se gli strumenti dell'agente vengono eseguiti in container, impostare il limite superiore nel file Compose in modo che venga applicato a ogni esecuzione.
services:
agent:
image: node:22-bookworm
deploy:
resources:
limits:
memory: 2g
cpus: "1.5"Docker Compose v2 applica deploy.resources.limits con un semplice docker compose up, quindi la modalità swarm non è coinvolta. La chiave precedente mem_limit: 2g continua a funzionare. La guida completa ai limiti di memoria di Compose illustra le reservation e il comportamento del container quando raggiunge il limite superiore. Se Docker non è ancora installato sul server, eseguire prima installare Docker su un VPS.
Un errore comune può far perdere un pomeriggio. Un container limitato a 2 GB continua a leggere il valore /proc/meminfo dell'host e il numero di CPU dell'host, perché nessuno dei due è isolato tramite namespace. Un test runner che determina il numero di worker in base al numero di CPU avvierà otto worker dentro un container da 2 GB su un host con 8 vCPU, quindi terminerà con il codice 137. Impostare manualmente questi valori:
npx jest --maxWorkers=2
export NODE_OPTIONS=--max-old-space-size=1536--max-old-space-size è espresso in MB e limita l'heap V8. Impostarlo al di sotto del limite del container, così Node genera un errore leggibile invece di terminare senza messaggi:
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memoryQuesto messaggio è utile perché indica il limite raggiunto e il processo che lo ha raggiunto. L'OOM killer non fornisce queste informazioni.
Eseguire più sessioni di agent sulla stessa macchina
Pianifica per sessione, non per persona. Due sessioni sullo stesso repository significano comunque due language server, due serie di cache di build in memoria e due esecuzioni dei test se entrambi gli agent diventano attivi nello stesso momento. Per questo la riga relativa al team arriva a 16 GB.
Imposta per ogni utente un limite rigido, così una sessione fuori controllo non può bloccare l'intera macchina:
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 MemoryMaxSostituisci 1001 con l'UID visualizzato da id -u. systemctl show dovrebbe restituire MemoryMax=6442450944 dopo che l'utente ha effettuato l'accesso. Quando il consumo complessivo della sessione dell'utente supera 6 GB, il kernel termina un processo all'interno della slice dell'utente e tutte le altre sessioni continuano a funzionare. Per un agent eseguito come servizio anziché in un terminale, inserisci MemoryMax= nel relativo unit file. Questo è il modello da seguire quando ospiti autonomamente un agent come servizio sempre attivo.
FAQ
2 GB di RAM sono sufficienti per un coding agent?
Per il processo dell’agent, sì. Per il lavoro che svolge, raramente. L’agent usa circa 250 MB, ma un singolo language server TypeScript può raggiungere 2000 MB in un repository di medie dimensioni, e questo da solo porta un sistema da 2 GB a usare la swap. 2 GB sono sufficienti per modificare file di configurazione e script piccoli. Usa 4 GB come valore minimo per qualsiasi attività che compili il codice o esegua una suite di test.
Serve una GPU per eseguire un coding agent su un VPS?
No, se l’agent chiama un modello cloud tramite un’API. Questo carico dipende dalla rete, quindi un VPS con una normale CPU è la scelta corretta e una GPU resta inattiva a un prezzo molto più elevato. Serve una GPU solo quando il modello viene eseguito sullo stesso sistema. In quel caso, il problema non riguarda più la RAM, ma la VRAM e le dimensioni del modello.
Quanta swap devo aggiungere a un VPS per un agent?
Metà della RAM, fino a circa 4 GB. La swap protegge da un superamento temporaneo, perché il kernel può spostare su disco le pagine non utilizzate invece di terminare un processo. Non aggiunge memoria utilizzabile. Se vmstat 1 mostra traffico costante nelle colonne si e so, il sistema sta eseguendo thrashing. In questo caso, riduci il numero di worker paralleli oppure scegli un piano più grande.
Perché il mio coding agent si blocca durante una build?
La build è quasi certamente stata terminata dall’OOM killer del kernel, che invia SIGKILL. Di conseguenza, non viene stampato nulla e l’agent resta in attesa su una pipe che non riceverà mai dati. Esegui sudo dmesg -T | grep -i "killed process" e controlla il nome del processo e il relativo valore anon-rss. Risolvi il problema limitando la build con systemd-run --user --scope -p MemoryMax=4G e riducendo il numero di worker, oppure passando al livello RAM successivo.