SSD Nodes Learn Hosting plans →
Guide Matt ConnorDi Matt Connor · Aggiornato 2026-09-14

Ollama: risolvere l’errore context deadline exceeded

Scopri perché Ollama mostra `context deadline exceeded`: verifica timeout del client, caricamento del modello, keep_alive e nginx per trovare il livello che interrompe la richiesta.

Che cosa significa realmente "context deadline exceeded"

L’errore Ollama context deadline exceeded indica un timeout. Una parte del codice Go ha impostato una scadenza per la richiesta, il modello non ha terminato entro tale limite e la scadenza è trascorsa. Non si è verificato alcun crash e nessun file è danneggiato. L’elaborazione era ancora in corso quando il tempo è terminato.

La dicitura proviene dal package standard context di Go, e questo è già un indizio utile. Un client Python basato su httpx genera invece httpx.ReadTimeout. Un browser mostra un semplice errore di rete. Se stai leggendo esattamente queste parole, un programma Go ha smesso di attendere: lo strumento da riga di comando Ollama, il server Ollama stesso oppure un’applicazione Go che chiama l’API (application programming interface).

Cinque livelli possono impostare quella scadenza. Operano in punti diversi e richiedono correzioni differenti. Il compito consiste quindi nell’individuare quale livello è intervenuto.

  1. Il client HTTP, che ha assegnato alla richiesta un tempo massimo fisso.
  2. Il timeout di caricamento del modello del server Ollama, che scatta mentre un modello di grandi dimensioni viene letto dal disco per la prima volta.
  3. keep_alive, che scarica il modello tra una richiesta e l’altra, costringendo la chiamata successiva a sostenere nuovamente il costo del caricamento.
  4. Un num_ctx abbastanza grande da far durare per minuti la sola elaborazione del prompt su un host che usa esclusivamente la CPU.
  5. Un reverse proxy come nginx o Traefik, che interrompe la connessione prima che Ollama abbia risposto.

Procedi nell’ordine indicato. Ogni passaggio seguente elimina un livello dall’analisi, così non devi procedere per tentativi.

Riprodurre la richiesta direttamente all’API per escludere il proxy

Eseguire la richiesta direttamente sul server, verso Ollama, senza proxy intermedi.

time curl -s http://127.0.0.1:11434/api/generate -d '{
  "model": "llama3.1:8b",
  "prompt": "Why is the sky blue?",
  "stream": false
}' | head -c 400

curl non imposta un limite di tempo complessivo, ma solo un timeout di connessione. Il comando quindi attende il tempo necessario a Ollama. In questo modo si divide il problema in due. Se viene restituito un corpo JSON, Ollama ha risposto e il timeout dipende da un componente a monte. Se invece questa chiamata resta in attesa per diversi minuti, il ritardo si verifica all’interno di Ollama e il proxy non è la causa.

Inviare ora la stessa richiesta tramite l’URL pubblico e misurarne la durata.

curl -s -o /dev/null -w '%{http_code} %{time_total}\n' \
  -X POST https://llm.example.com/api/generate \
  -d '{"model": "llama3.1:8b", "prompt": "hi", "stream": false}'

Uno stato 504 visualizzato dopo un numero di secondi sospettosamente preciso, come 60.0 o 30.0, indica un timeout del proxy. I proxy usano valori predefiniti arrotondati. Un modello non termina due volte consecutive esattamente dopo 60.000 secondi. Se la chiamata diretta viene rifiutata immediatamente invece di rallentare, il problema riguarda il listener e non il timeout. In questo caso, vedere quale indirizzo usa Ollama per mettersi in ascolto sulla porta 11434.

Monitora il log del server mentre viene eseguita la richiesta

Apri una seconda sessione e segui il log del servizio, quindi invia di nuovo la richiesta.

journalctl -u ollama --no-pager --follow --pager-end

Un avvio a freddo completato correttamente registra il caricamento del modello, quindi l'avvio di un runner e infine la gestione della richiesta. Un caricamento non riuscito appare invece così. Questa è la stringa che identifica il timeout di caricamento interno del server:

Error: timed out waiting for llama runner to start - progress 0.00 -

Il messaggio indica che il processo del modello non ha completato l'avvio entro il tempo previsto dal server. Il valore di avanzamento indica a che punto è arrivato. Il valore 0.00 significa che il runner non ha segnalato alcun avanzamento prima della scadenza. In genere, il file è ancora in fase di lettura oppure la macchina sta usando lo swap. Per ottenere maggiori dettagli durante il caricamento, riavvia il servizio impostando OLLAMA_DEBUG=1 e ripeti l'operazione.

Misurare se il ritardo dipende dal caricamento o dalla generazione

Ollama restituisce i propri tempi, quindi non è necessario procedere per ipotesi.

ollama run --verbose llama3.1:8b "Why is the sky blue?"

Dopo la risposta stampa total duration, load duration, prompt eval count, prompt eval rate, eval count e eval rate. Eseguire il comando due volte. Alla seconda esecuzione, load duration dovrebbe ridursi quasi a zero, perché il modello è già residente. Se non diminuisce, il modello viene scaricato tra le due esecuzioni. Questo è il caso keep_alive descritto più avanti.

Gli stessi valori vengono restituiti dall'API nell'oggetto JSON finale, come load_duration, prompt_eval_duration e eval_duration. La documentazione specifica che tutte le durate sono espresse in nanosecondi. Dividere quindi per 10^9 per ottenere i secondi.

curl -s http://127.0.0.1:11434/api/generate -d '{
  "model": "llama3.1:8b",
  "prompt": "Why is the sky blue?",
  "stream": false
}' | python3 -c 'import json,sys; d=json.load(sys.stdin); print({k: round(v/1e9, 2) for k, v in d.items() if k.endswith("_duration")})'

Considerare il valore più alto. Se prevale load_duration, il problema riguarda il caricamento del modello. Passare quindi alle due sezioni successive. Se prevale prompt_eval_duration, il costo è dovuto all'elaborazione del prompt. Passare alla sezione num_ctx. Se prevale eval_duration, il modello sta semplicemente generando lentamente su questo hardware e nessuna impostazione di timeout può cambiare il risultato. Ridurre la lunghezza dell'output con num_predict oppure usare un modello più piccolo.

Aumentare OLLAMA_LOAD_TIMEOUT dopo aver verificato la versione

La variabile del server che determina per quanto tempo attende l'avvio di un modello è OLLAMA_LOAD_TIMEOUT. Il valore predefinito è cambiato tra le diverse release. Leggilo quindi per la build in uso, anziché ricavarlo da un articolo, incluso questo. Stampa prima la versione.

ollama --version

Apri quindi il sorgente del tag esatto, https://github.com/ollama/ollama/blob/<your version>/envconfig/config.go, e cerca OLLAMA_LOAD_TIMEOUT. Il valore presente in quel file è il valore predefinito incorporato nel binario durante la compilazione. Imposta il valore personalizzato tramite un drop-in di systemd.

sudo systemctl edit ollama.service

Aggiungi le variabili in una sezione [Service]. È il metodo indicato dalla documentazione di Ollama per Linux:

[Service]
Environment="OLLAMA_LOAD_TIMEOUT=15m"
Environment="OLLAMA_KEEP_ALIVE=-1"
sudo systemctl daemon-reload
sudo systemctl restart ollama
systemctl show ollama --property=Environment

L'ultimo comando stampa l'ambiente effettivamente ricevuto dal servizio. Un risultato vuoto indica che il drop-in è stato salvato fuori dai marcatori dell'editor oppure nella sezione sbagliata. In questo caso nessuna delle impostazioni definite è attiva. È importante chiarire il risultato: un timeout di caricamento più lungo impedisce al server di interrompere l'operazione, ma non la rende più veloce. Se il modello non entra in memoria, la macchina userà lo swap, il caricamento rallenterà notevolmente e un valore maggiore sposterà soltanto il momento del fallimento.

Perché la prima richiesta dopo una pausa è lenta

Ollama scarica dalla memoria un modello inattivo per liberare risorse. L'impostazione keep_alive determina quando avviene questa operazione. La documentazione di Ollama indica 5 minuti come valore predefinito, verificato a settembre 2026. Di conseguenza, un'applicazione di chat usata una volta all'ora ricarica il modello a ogni messaggio, e ogni messaggio sostiene l'intero tempo di avvio a freddo. La richiesta che va in timeout è la prima dopo un periodo di inattività. È esattamente il comportamento che viene descritto come casuale.

Controlla cosa è attualmente residente in memoria:

ollama ps
curl -s http://127.0.0.1:11434/api/ps

Un elenco vuoto oppure una scadenza tra pochi minuti lo conferma. keep_alive accetta una stringa di durata come "10m" o "24h", un semplice numero di secondi, 0 per scaricare il modello immediatamente e un numero negativo per mantenerlo indefinitamente in memoria. Impostalo per ogni richiesta oppure configura OLLAMA_KEEP_ALIVE sul servizio, in modo che valga per tutte le richieste.

curl -s http://127.0.0.1:11434/api/generate -d '{
  "model": "llama3.1:8b",
  "keep_alive": -1
}'

Una richiesta con un modello ma senza prompt carica il modello e termina. Questo è il metodo documentato per precaricare un server dopo un riavvio. Va inserito in una piccola unità systemd, così nessuno deve attendere un avvio a freddo. Il costo è concreto: un modello mantenuto in memoria occupa le relative risorse indefinitamente. Su un server con poca memoria puoi mantenerne uno, non quattro. Mantenere un modello residente tra le richieste illustra il calcolo della memoria e l'unità di warm-up.

Perché un valore elevato di num_ctx causa un timeout prima del primo token

Prima di generare qualsiasi output, il modello deve leggere l’intero prompt. Questa fase è il prefill ed è ciò che misura prompt eval. num_ctx imposta la lunghezza del contesto e svolge due funzioni contemporaneamente. Limita il numero di token che il modello può considerare e determina le dimensioni della KV cache (key value cache) che il server alloca in anticipo. Entrambe le operazioni aumentano il carico di lavoro.

Su un server che usa soltanto la CPU, il prefill è lento e il tempo cresce in modo lineare con il numero di token del prompt. Un documento lungo incollato in una chat può richiedere minuti per il prefill, mentre il client non visualizza nulla perché lo streaming non è ancora iniziato. Il client raggiunge la propria scadenza e segnala context deadline exceeded, mentre il server ha continuato a lavorare per tutto il tempo. Verificalo usando i numeri della sezione precedente: esegui lo stesso prompt prima con "options": {"num_ctx": 2048} e poi con 32768, quindi confronta prompt_eval_duration.

Il valore predefinito del server proviene da OLLAMA_CONTEXT_LENGTH, mentre un num_ctx per singola richiesta nell’oggetto options lo sovrascrive. Aumentare questo valore fino al massimo dichiarato dal modello solo perché tale massimo è disponibile è l’errore più comune: l’allocazione della KV cache può infatti esaurire la RAM disponibile e trasformare una configurazione funzionante in una configurazione che usa lo swapping. Scegliere num_ctx in base alla memoria effettivamente disponibile contiene i dettagli per il dimensionamento.

Perché nginx restituisce 504 Gateway Time-out

nginx documenta proxy_read_timeout con un valore predefinito di 60s e il relativo log degli errori indica chiaramente il problema:

upstream timed out (110: Connection timed out) while reading response header from upstream

Il dettaglio importante è nella documentazione di nginx: il timeout «viene applicato solo tra due operazioni di lettura consecutive, non alla trasmissione dell’intera risposta». Una risposta in streaming reimposta il timer a ogni chunk, quindi le chat in streaming continuano a funzionare. Una richiesta con "stream": false non invia nulla finché la risposta non è completa, quindi l’intera generazione deve terminare entro quella finestra. Per questo lo stesso modello funziona nella finestra della chat, ma va in timeout quando viene chiamato da uno script.

location / {
    proxy_pass http://127.0.0.1:11434;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_read_timeout 600s;
    proxy_send_timeout 600s;
    proxy_buffering off;
}
sudo nginx -t && sudo systemctl reload nginx

proxy_buffering off è importante per lo streaming. Con il buffering attivo, nginx può raccogliere la risposta e inoltrarla al termine. I token quindi non compaiono più uno alla volta e uno streaming funzionante può sembrare bloccato.

Traefik applica lo stesso controllo a ServersTransport utilizzato dal router.

http:
  serversTransports:
    ollama:
      forwardingTimeouts:
        dialTimeout: "30s"
        responseHeaderTimeout: "0s"
        idleConnTimeout: "60s"

responseHeaderTimeout copre l’attesa degli header della risposta dopo l’invio della richiesta e il valore zero indica l’assenza di timeout. Il servizio deve fare riferimento al transport tramite il nome usando serversTransport: ollama, altrimenti hai modificato un blocco che non viene utilizzato.

Una quantizzazione più compatta si carica più velocemente perché richiede meno dati da leggere

La quantizzazione indica la precisione con cui vengono memorizzati i pesi. Una precisione inferiore produce un file più piccolo e il caricamento di un modello consiste soprattutto nella lettura di quel file dal disco e nel suo trasferimento in memoria.

ChartPublished download sizes for llama3.1 8B on the ollama.com library, September 2026
The data behind this chart
[
  {
    "label": "q4_K_M",
    "download_size_gb": 4.9
  },
  {
    "label": "q8_0",
    "download_size_gb": 8.5
  },
  {
    "label": "fp16",
    "download_size_gb": 16
  }
]

Queste sono le dimensioni pubblicate nella pagina del modello, non misurazioni eseguite su un server di test. La build predefinita 8B occupa 4.9 GB. La build dello stesso modello a piena precisione occupa 16 GB: richiede la lettura di oltre tre volte tanti byte e oltre tre volte la memoria per essere mantenuta. Su un server a noleggio con storage condiviso, questa differenza può determinare se il caricamento termina correttamente o supera il timeout. Verificare quale modello è compatibile con la RAM è il controllo da eseguire prima di scaricare file di grandi dimensioni.

Cosa modificare su un server noleggiato

Applica queste modifiche nell’ordine indicato dalle misurazioni, una alla volta, ed esegui nuovamente il comando di misurazione dopo ciascuna modifica.

  1. Fissa il modello con OLLAMA_KEEP_ALIVE=-1 oppure precaricalo all’avvio, in modo che nessuna richiesta utente debba sostenere il costo del caricamento.
  2. Riduci num_ctx al valore realmente necessario per i prompt. In questo modo accorci il prefill e liberi la memoria occupata dalla cache KV.
  3. Usa una quantizzazione più compatta, così il caricamento legge meno byte e il modello lascia più spazio alla cache.
  4. Aumenta proxy_read_timeout in nginx oppure responseHeaderTimeout in Traefik e disabilita il buffering, in modo che i token generati in streaming raggiungano il client.
  5. Aumenta il timeout nel client che usi, perché un programma Go o Python con un limite di 30 secondi fallirà con qualsiasi modello la cui elaborazione duri più a lungo.

Esiste un’ulteriore causa comune a tutti questi casi. Ollama gestisce contemporaneamente un numero limitato di richieste e accoda le altre. Di conseguenza, una seconda richiesta può restare in coda fino alla scadenza del proprio timeout, anche quando non c’è alcun modello lento. Il log del server mostra che la richiesta viene gestita in ritardo, non che fallisce. Cosa succede quando più persone condividono un server Ollama descrive le impostazioni relative al parallelismo, mentre l’installazione di base su un VPS descrive la configurazione del servizio presupposta da queste impostazioni.

FAQ

Che cosa significa "context deadline exceeded" in Ollama?

Significa che la scadenza della richiesta è stata raggiunta prima che il modello rispondesse. La frase proviene dal package context di Go, quindi è stata stampata da un programma Go: lo strumento a riga di comando di Ollama, il server Ollama oppure un'applicazione Go che chiama l'API. Si tratta di un timeout, quindi non indica che qualcosa sia guasto o corrotto. Il passo successivo consiste nell'individuare quale livello ha impostato la scadenza, perché il client, il caricamento del modello, keep_alive, num_ctx e il reverse proxy impostano ciascuno il proprio limite.

Devo aumentare il timeout del client o quello di Ollama?

Prima esegui una misurazione. Invia la richiesta con curl direttamente dal server, verso http://127.0.0.1:11434, perché curl non impone alcun limite di tempo complessivo. Se la chiamata restituisce un corpo JSON, Ollama sta rispondendo e la scadenza riguarda il client o il proxy: aumenta quindi il timeout a quel livello. Se anche questa chiamata resta bloccata, il ritardo si verifica all'interno di Ollama e i campi load_duration e prompt_eval_duration della risposta indicano se il modello è in fase di caricamento oppure se sta leggendo il prompt.

Perché la prima richiesta va in timeout e la successiva funziona?

Ollama scarica dalla memoria un modello inattivo per liberare risorse, secondo una pianificazione impostata da keep_alive. Il valore predefinito documentato è 5 minuti, verificato a settembre 2026. La prima richiesta dopo un periodo di inattività ricarica il modello dal disco e sostiene interamente il costo dell'avvio a freddo; una richiesta inviata subito dopo trova invece il modello già residente e risponde rapidamente. Esegui ollama ps per vedere quali modelli sono caricati e quando scadono. Imposta OLLAMA_KEEP_ALIVE=-1 per mantenerli in memoria, tenendo conto che la memoria resterà occupata.

Perché il problema si verifica soltanto quando passo attraverso nginx?

La documentazione di nginx indica proxy_read_timeout con un valore predefinito di 60s. Questo timeout si applica all'intervallo tra due letture successive, non all'intera risposta. Una risposta in streaming reimposta il timeout a ogni chunk, mentre una richiesta inviata con "stream": false deve completarsi all'interno di una singola finestra. Per questo la finestra di chat funziona, mentre uno script non funziona. Cerca upstream timed out (110: Connection timed out) while reading response header from upstream nel log degli errori di nginx, quindi aumenta proxy_read_timeout e imposta proxy_buffering off.

Aumentare OLLAMA_LOAD_TIMEOUT rende più veloce il caricamento?

No. Modifica soltanto il tempo per cui il server attende prima di rinunciare e registrare timed out waiting for llama runner to start. Se il modello non entra nella memoria disponibile, la macchina usa lo swap, il caricamento rallenta notevolmente e un timeout più lungo posticipa l'errore senza risolvere il problema. Controlla il valore predefinito della tua build eseguendo ollama --version e leggendo envconfig/config.go in corrispondenza di quel tag, quindi considera un caricamento che richiede minuti come un segnale per scegliere una quantizzazione più piccola.