Skip to main content
One of the most underused building blocks in Duvo is the Queue between two Agents. Most teams start with one Agent that does everything — find the work, process it, deliver the results — and only discover Queues when that Agent becomes impossible to debug. This guide covers when to split a process across Agents connected by a Queue, and what the boundary actually buys you. For the organizational criteria (different owners, different SLAs, reusable steps), see Multi-Agent Decomposition; for the design rules inside a single Queue (settling every Case, postpone vs. fail), see Designing Work Around Queues and Cases. This page focuses on the mechanics and payoff of the Queue connection itself.

The One-Agent Trap

A single Agent that finds twelve items and processes them in one Run works fine — until it doesn’t:
  • The Run fails on item 9, and items 1–8 are done but items 9–12 are not. There is no way to retry just the failures.
  • One risky step (posting publicly, paying, deleting) forces you to babysit the whole Run, even though most of it is safe read-only work.
  • Every improvement to one part of the procedure risks breaking the rest, because it is all one AOP.
  • When the Run is slow, you can’t tell which part is slow.
Each of these is the same root problem: the process has stages with different failure modes, risk levels, and speeds, but they share one Run.

The Mental Model: a Queue Is a Contract Between Agents

A Queue is not a to-do list. It is the interface between two Agents:
  • The producer Agent finds work and creates one Case per item, writing a fixed set of fields into the Case data. Its responsibility ends there.
  • The consumer Agent has a Case trigger on the Queue. Each new Case starts a Run that claims it, reads those fields as its input, does one item’s worth of work, and settles the Case.
The Case data is the contract. If both AOPs name the same fields, the two Agents compose like functions — and each side can be tested, fixed, and improved without touching the other.

A Real Pipeline

The pipeline below is a real production setup of an e-commerce team that answers customer reviews across a dozen marketplace platforms; the process is three Agents connected by two Queues:
  1. Review Orchestrator (scheduled, daily). Reads the list of active platforms from a spreadsheet and creates one Case per platform in the Platform Reviews Queue — title “Platform name – date”, data: platform name, URL, platform type, and the date to collect. That is its whole job.
  2. Platform Collector (Case trigger on Platform Reviews, Cases processed in parallel). Claims one Case, logs into that platform in the browser, extracts yesterday’s negative reviews, and updates the Case with the structured list — including the reviews it filtered out, so there is an audit trail. If reviews were found, it creates a Case in the Review Responses Queue carrying the original fields plus the reviews. This stage is deliberately read-only.
  3. Review Responder (Case trigger on Review Responses, one Case at a time). Categorizes each review, drafts a localized reply from the matching template in Files, posts it on the platform, and logs the outcome.
The team’s favorite property of this design: the list of platforms lives in the spreadsheet, not in any Agent. Add a row, and tomorrow there is simply one more Case; switch a platform off, and it quietly drops out of the day’s work. Nothing else changes — no AOP edits, no rewiring, no risk to the platforms already running.

What the Queue Boundary Buys You

These are properties of the boundary itself, not of this example — every Queue-connected process gets them, and none are available to a single Agent:
  • Volume doesn’t dilute quality. Every Case is processed by its own Run, with the Agent’s full attention — the two-hundredth item is handled exactly like the first. Growth adds Cases, not risk: an Agent looping over an ever-growing list inside a single Run gets slower and sloppier as the batch grows; a Queue does not.
  • Fan-out without batch loops. One short producer Run can become dozens — or thousands — of independent Cases for the platform to work through. No “go through all pending items” step hiding failures inside a single Run.
  • Sequential or parallel, per stage. A stage that only reads can safely process many Cases at once; a stage that acts outward — sending, posting, paying — can take them one at a time. Each stage gets the processing mode its work calls for. In one Agent, the riskiest step sets the pace for everything.
  • Failures stay the size of one item. One blocked item postpones or fails one Case while the rest of the batch proceeds. Recovery means reprocessing that Case — not re-running the whole batch.
  • Stages iterate independently. Each stage is its own Agent with its own AOP, so an improvement to one stage is drafted, tested, and promoted without touching the others. With one Agent, every tweak to the final step forces you to re-test everything before it.
  • State passes between stages explicitly. Each stage records what it read, produced, and decided on the Case it is working, and copies forward the fields the next stage needs. A downstream Case starts its own timeline, so include a stable identifier in the Case data — that is what lets you trace one item across the whole pipeline when someone asks why it was handled the way it was.
  • Work only flows where it exists. When a stage finds nothing to act on for an item, it ends cleanly — no downstream Case is created, and the next stage never wakes up for it.
  • You can see where the process is slow. A growing Pending backlog on one Queue points at exactly one stage.

Wiring Checklist

Create the Queue

Create a Queue per stage boundary and give it a name that describes the work items in it, not the Agent (see Queue).

Connect the producer

Give the upstream Agent the Queue (Producer) Connection, and write the Case creation into its AOP: one Case per item, with the exact fields listed by name.

Connect the consumer and enable its Case trigger

Give the downstream Agent the Queue (Consumer) Connection and enable a Case trigger on the Queue. An Agent has one Case trigger, and a Queue should have exactly one consuming Agent — two consumers competing for the same Cases is a conflict, not extra capacity.

Choose sequential or parallel processing

Decide how the stage works through its Cases: in parallel for independent, read-only work; one at a time when the stage writes somewhere that must not race, or acts publicly.

Design Rules for the Boundary

  • Agree on the Case fields before writing either AOP. Consumers break when producers freestyle the data. List the exact field names in both AOPs, and keep them stable — a field rename is an interface change.
  • One Case = the unit you would want to retry. A freight team audits thousands of shipments; they create one Case per shipment, not one per weekly invoice file. When an audit is disputed, they reprocess one shipment. Pick the granularity by asking “what would I want to redo in isolation?”
  • Deduplicate in the producer. The platform does not deduplicate Cases for you. Before creating, the producer checks whether a Case for that item already exists.
  • Carry upstream fields forward. When a stage creates the next Case, it copies the original fields and adds its own output. Downstream Agents and humans should never have to walk back up the pipeline to find the platform name.
  • Give every item a stable identifier. Include an ID (order number, review URL, shipment number) in the Case data, and use it in everything the pipeline writes to external systems, so results can be traced back to the originating Case.
Inside each stage, the usual Case discipline applies — claim one Case per Run and settle it explicitly (complete, fail with a reason, postpone, or hand over). See Queue for the Case lifecycle.

When Not to Use a Queue

  • The process is one coherent flow a single person would do end-to-end in a few minutes, with no per-item tracking need — keep one Agent. A Queue you don’t need is pure overhead.
  • A Run needs to route work onward immediately — an intake Agent escalating a hard Case to a specialist mid-process. That is Agent Handover: the Case moves to the target Agent directly, no intermediate Queue required.
  • The stages always run together and share context that is expensive to serialize into Case data. If stage B constantly needs “everything stage A saw”, the boundary is in the wrong place.

Signs You Got the Shape Wrong

Multi-Agent Decomposition

When to split a process across Agents — ownership, SLAs, and reusable steps.

Queue

Cases, statuses, triggers, and the full Case lifecycle.

Agent Handover

Route a Case to another Agent immediately, without a stage boundary.

AOP

Write each stage’s AOP around processing a single Case.