ANTIGRAVITY LABJP
Articles/Agents & Manager
Agents & Manager/2026-06-16Advanced

Bundling Nightly Tasks With agy Async Jobs — A fan-out, poll, join Design

The Go-based Antigravity CLI (agy) can detach jobs and run them asynchronously. Here is a fan-out, poll, join design for firing many long-running tasks at once, collecting their job IDs, and waiting for completion — drawn from an actual nightly batch.

antigravity361CLIagy3asyncjob-managementorchestration18operations11

Premium Article

When I ran the nightly batch serially, the single slowest job set the pace for everything. Article generation, link audits, an AdMob mediation comparison report, multilingual screenshot swaps — all independent work, yet nothing started until the previous job finished. Added up, it sometimes ran until morning.

When Gemini CLI shut down on June 18 and I moved to the Go-based Antigravity CLI (agy), I took the chance to rethink that serial structure itself. agy can detach a job and run it asynchronously. That means you can build a flow of "fire it, remember the ID, join on it later."

This is how I designed that fan-out (firing all at once), poll (checking state), and join (waiting) so it holds up for solo operations. No heavy parallel framework — just the job IDs agy returns and a small shell that bundles them.

First, put numbers on the serial bottleneck

I started by quantifying what I was fixing. The nightly batch is 12 jobs. Run serially, the plain sum of each job's wall time becomes the total.

In my setup, the sum of all 12 averaged about 214 minutes. Yet each job's CPU and network utilization was low; waiting dominated. Waiting on LLM responses, sitting between API rate-limit windows, waiting for a git push to complete — all time where the machine is idle but cannot move on.

Fire them asynchronously in parallel and the total approaches "the slowest single job plus a little overhead." In practice 214 minutes became about 79 minutes — roughly a 63% reduction. The key point is that I did not make any job faster; I only overlapped the waiting.

What an agy async job returns

agy run has a normal mode that runs in the foreground, and a --detach mode that returns control immediately. When detached, it prints a single job ID to stdout.

# Foreground (the old way): blocks until done
agy run --task "generate article: antigravity cli async jobs" --model gemini-3.5-flash
 
# Detached: returns a job ID at once, continues in the background
JOB_ID=$(agy run --detach --json \
  --task "generate article: antigravity cli async jobs" \
  --model gemini-3.5-flash | jq -r '.job_id')
echo "submitted: $JOB_ID"

With --json, you get one machine-readable object instead of human-friendly decoration. Always pass --json when scripting. A version that scrapes the decorated output with grep breaks the moment the CLI's display changes slightly.

You read job state with agy jobs.

# State of one job
agy jobs get "$JOB_ID" --json
# => {"job_id":"j_8f3a","state":"running","exit_code":null,"started_at":"..."}
 
# List every job
agy jobs list --json

state returns one of queued / running / succeeded / failed / cancelled. exit_code carries a number only after the job ends. The join is built around these two fields.

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
Get a full shell implementation of fan-out -> poll -> join that bundles the job IDs returned by agy run --detach and reads state via agy jobs
Learn a wait loop that backs off polling exponentially and treats timeout and partial failure as distinct outcomes, plus the production gotchas I hit
See the operating rules that cut total wall-clock time for 12 nightly jobs by about 63% by moving from serial to async parallel execution
Secure payment via Stripe · Cancel anytime

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Antigravity Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

Related Articles

Agents & Manager2026-06-15
Containing Failure in Antigravity Multi-Agent Systems: Three Boundaries That Stop Cascades
Antigravity multi-agent setups run beautifully in isolation but cascade in production, where one small failure drags the whole orchestration down. These notes organize the fix around three boundaries—layered control, trust separation, and observability with idempotency—down to the TOML and the correlation-ID wrapper.
Agents & Manager2026-06-02
Rehearsing an Agent's Actions Before They Touch Production — Designing a Zero-Side-Effect Dry-Run Layer
Some accidents survive shadow mode and canaries: the very first time an agent touches an external API. This is the design and TypeScript implementation of a zero-side-effect dry-run layer you can bolt onto Antigravity's parallel agents, with the real numbers from running six sites autonomously.
Agents & Manager2026-06-01
Capping Parallel Agents With a Token Budget — Designing a Guard That Stops Runaway Cost
Running many agents in parallel quietly inflates your token bill. This is not about shrinking prompts — it is about a governance layer that meters spend in real time and cuts it off at a budget. Full design and TypeScript implementation, drawn from running six sites autonomously.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →