BOLLETTINO OPERATIVO · DOM 17 MAG 2026 · 14:34 CET EN / IT / RSS / NEWSLETTER

Background tasks in Claude Code: lavori lunghi senza bloccare la sessione

Background tasks in Claude Code: come lanciare build, test e sub-agent lunghi senza bloccare la sessione. Pattern corretti e anti-pattern da evitare.

Un build che dura otto minuti, una test suite da quattro, uno scraping che ciucca mezz’ora: in sessione interattiva sono tutti momenti in cui l’assistente resta fermo a guardare lo schermo. Claude Code gestisce questo scenario con i background tasks, una modalità che scollega l’esecuzione dal flusso principale e libera la sessione per lavorare su altro. Non è una feature cosmetica: usata male brucia cache e tempo, usata bene dimezza il tempo di un batch.

Cosa sono i background tasks

Due modalità coprono la quasi totalità dei casi: Bash con run_in_background: true lancia un processo shell che resta vivo in background, mentre Agent (vedi https://www.smartworkers.cloud/?p=3427) con lo stesso flag spawna un sub-agent asincrono. La differenza non è solo tecnica: Bash è per comandi deterministici, Agent per lavoro “cognitivo” che dura minuti — code generation agentica, analisi multi-file, scraping con estrazione.

In entrambi i casi la harness notifica automaticamente alla chiusura del task. Non serve pollare, non serve loop di sleep: la sessione riceve una notification quando il processo finisce o quando il sub-agent chiude il turno.

Quando ha senso usarli

  • Build lunghi (webpack, gradle, cargo release) oltre i 60 secondi
  • Test suite complete su progetti grandi
  • Scraping o chiamate API batch che hanno tempi di rete imprevedibili
  • Code generation agentica distribuita su più file
  • Deploy che includono push remoto, migration, health check

Il criterio pratico: se durante l’attesa esiste almeno un altro task indipendente su cui si può avanzare, conviene il background. Se il risultato blocca ogni step successivo, tenerlo in foreground è più onesto — un background task con la sessione ferma ad aspettare non serve a nulla.

Esempio di invocazione

Lancio di un test suite lunga con Bash in background, mentre la sessione prosegue su altro file:

Bash(
  command="npm run test:e2e -- --reporter=json > /tmp/e2e.log 2>&1",
  description="Run full e2e test suite",
  run_in_background=true,
  timeout=600000
)
# sessione libera: continuo a editare src/ in parallelo
# alla fine arriva notification -> leggo /tmp/e2e.log con Read

Stesso pattern per un sub-agent lungo: si passa il prompt di ricerca e si riceve il risultato a chiusura, senza occupare il turno corrente.

Monitor vs TaskOutput

Due strumenti complementari, usi diversi. Monitor streamma l’output riga per riga come notification: utile per un tail in tempo reale di build verbosi, dove serve vedere progress senza aprire lo stdout finale. TaskOutput legge lo stdout completo del task in un colpo solo: va bene per Bash, dove il log è delimitato, ma è pericoloso su Agent — il transcript di un sub-agent può essere enorme e saturare il contesto.

Regola: Monitor quando interessa il progress, TaskOutput per Bash al termine, mai TaskOutput su Agent a freddo.

Gli anti-pattern più frequenti

Il primo e peggiore è il sleep in loop per “controllare se ha finito”. Oltre a essere inutile — la notification arriva comunque — brucia il prompt cache. Claude Code usa una cache con TTL di 5 minuti: uno sleep 300 cade esattamente sul limite e garantisce cache miss al risveglio. Se proprio serve una pausa deliberata, o si sta sotto i 270 secondi oppure sopra i 1200, mai in mezzo.

Il secondo è pollare con Bash ogni 30 secondi “per sicurezza”. Ogni poll è un tool call, ogni tool call consuma turno e token. Un background task ben impostato non richiede zero poll: è fire-and-forget fino alla notification.

Pattern: batch paralleli

Il caso più interessante è il loop di N task in parallelo. Immagina di dover processare 20 file con uno script pesante: lanciarli sequenziali significa 20 attese, lanciarli tutti in background significa una sola attesa (la più lunga) più le notification che arrivano a scalare. La sessione nel frattempo può coordinare, leggere risultati parziali, preparare il report finale.

for file in batch/*.csv:
  lancio processing in background (run_in_background=true)
→ continuo con aggregation logic
→ raccolgo i risultati man mano che arrivano notification

Questo pattern si combina bene con gli hook (vedi https://www.smartworkers.cloud/?p=3421) se servono side-effect deterministici a chiusura di ogni task — ad esempio scrivere log strutturati o triggerare un notify esterno.

Quando restare in foreground

Non tutto deve andare in background. Se il comando dura 15 secondi, il setup mentale del background costa più del tempo risparmiato. Se il risultato è l’unico input dello step successivo e non c’è altro da fare, idem. Il background è uno strumento per spezzare parallelismo reale, non per far sembrare veloce una sessione che invece è bloccata.

La domanda vera da farsi prima di aggiungere run_in_background: true: c’è davvero un altro task indipendente su cui lavorare nel frattempo? Se la risposta è no, il flag è solo rumore.