11

Queues, Not Loops

The viral "agentic loop" is really a task queue with away-from-keyboard workers. Borrow the vocabulary computer science already had — it maps straight onto the system you already run.

The word "loop" is hiding the useful idea

Everyone talks about "the agentic loop" — one agent, spinning, doing a thing over and over. That picture is small, and it's wrong about what makes the pattern powerful. A loop is one worker repeating the same step in sequence. Useful, but limited: one thing at a time, and if it trips, the whole thing stops.

The thing actually worth building is a queue: a list of tasks on one side, and workers that pull tasks off it on the other. That one swap — from "a worker looping" to "tasks waiting for whichever worker is free" — is what unlocks parallelism, retries, and walking away.

The pattern has a name, and it's older than you are

This is the producer–consumer pattern, and the plumbing under it — job queues, message queues — has run banks, airlines, and every large website for decades. You are not inventing anything when you point an AI agent at a backlog. You're reusing a well-understood idea. That's good news: the vocabulary, the failure modes, and the fixes are all already documented.

Four words that carry the whole idea

Picture a busy kitchen. Orders come in and get clipped to a rail. Line cooks grab the next ticket when they're free. Nobody assigns each cook a specific order in advance — the tickets wait, and whoever has a free hand takes the next one. Four moving parts, four words:

1
Producer — puts work on the queue

The person (or the schedule) that decides "this task needs doing" and writes it down. In the kitchen, the waiter clipping a ticket to the rail. It does not do the work; it just enqueues it and moves on.

2
Queue — the backlog of tasks waiting

The rail of tickets. It holds work that's been defined but not yet done. Its depth tells you at a glance whether you're keeping up or falling behind.

3
Worker (consumer) — pulls a task and does it

The line cook. Grabs the next ticket (dequeue), cooks it, plates it. You can have one worker or ten; the queue doesn't care.

4
Result — checked, then it leaves

The expo who verifies the plate before it goes out. A task isn't "done" because a worker touched it — it's done when the output passes a check. Same rule you learned in the loop modules.

What "queue" lets you see that "loop" hides

The word matters because it changes what feels possible. Say "loop" and you imagine one agent, one track. Say "queue" and four capabilities appear that were always there:

Parallelism

Ten tasks on the queue, three workers free — they run three at a time. A loop does one. The bottleneck stops being "the agent" and becomes "how many workers you can afford to run."

Decoupling

The producer defines work and walks away — it never waits for the worker. Defining the task and doing the task become two separate jobs, done at two separate times, by two separate things.

Retry and dead-letter

A task that fails goes back on the queue to try again, or onto a "dead-letter" shelf for a human to look at. One bad task doesn't kill the run — it's isolated, not fatal.

Backpressure

A gate in front of the workers can refuse to hand out tasks when conditions are wrong — no budget left, machine on battery, network down. The queue waits instead of burning resources on a doomed run.

Why this is the strategic version of the loop lesson

The loop modules taught you to build one good loop. Thinking in queues is the level up: instead of asking "how do I make this agent repeat well?", you ask "what's my backlog, who are my workers, and what's my gate?" That question scales from one machine to a fleet without changing shape.

You already run one: the ~/loops system

The system you run on Prometheus is named "loops," but read it as a queue and every part snaps into a role you now have a word for:

P
cron — the producer/scheduler

At a set time, cron enqueues a job by firing run.sh. It defines "this task needs doing now" and immediately returns. It never waits for the work to finish.

G
guard — admission control / backpressure

Before any real work starts, guard checks pause-state, battery, mesh, and the budget ledger. If a condition is wrong it skips the run cleanly. That's backpressure: the gate that refuses a task instead of running it into the ground.

W
headless claude -p — the AFK worker

Once admitted, the headless agent is the consumer that actually does the task, away from your keyboard. Swap it, run more of them, or point them at different backlogs — the shape doesn't change.

D
ledger + failure ping + watchdog — accounting and dead-letter

The ledger accounts for every run's cost against the daily cap. The immediate failure ping and the daily watchdog make a failed or stale task loud — the dead-letter shelf, so nothing fails silently.

The reframe in one sentence

"My loops" is a scheduled task queue with guarded, away-from-keyboard workers and a dead-letter alarm — which is exactly the producer–consumer pattern, wearing a friendlier name.

How thinking in queues changes what you build

Once you see the queue, you design tasks that fit it. Four properties make a task safe to hand a worker you're not watching:

1
Idempotent — safe to run twice

If a retry runs the task again, the result should be the same and nothing should double up. "Add a row if it's missing" is safe to repeat; "append a row" is not. Idempotency is what makes retry safe instead of scary.

2
Small and independent

One task should not depend on another finishing first. Independent tasks can run in any order, in parallel, on any worker. That's what turns a queue from a fancy loop into real throughput.

3
Guarded at the front

Put admission control before the work, not inside it. A gate that refuses bad conditions up front is cheaper and clearer than a worker that starts, gets halfway, and has to unwind.

4
Loud on failure

A silent failure looks identical to success from across the room. Give every task a way to alarm — a dead-letter path — so the queue never quietly rots.

Honest footnote

"Queues, not loops" comes from the agentic-engineering interview that started this academy — a framing, not a law. Treat it as a lens: most day-to-day work is still one small loop, and that's fine. Reach for the full queue vocabulary when you have a real backlog, more than one worker, or failures you can't afford to lose track of.

Check yourself

Three questions on the reframe and the system it maps to.

Scenario

A teammate says "why do you keep calling it a queue? It's just a loop that runs the agent over and over."

What's the actual reason "queue" is the better mental model?

Scenario

In the ~/loops system, one component decides whether a scheduled task is even allowed to run — checking pause-state, battery, mesh, and remaining budget first.

Which component is that — the admission control / backpressure?

Scenario

You're writing a task for an AFK worker. The queue may retry it automatically if the first attempt fails partway through.

Which property matters most so the retry can't cause damage?

Your move

Open loops status and name each part out loud: cron is my producer, guard is my admission control, claude -p is my worker, the ledger and watchdog are my accounting and dead-letter. Then ask the real question — is any task on my backlog not idempotent? Fix that one first.