background=true and AgentOS answers immediately with a run_id. The run executes on the server while your client polls, streams, or disconnects. Add QueueConfig(durable=True) and that acceptance becomes a committed database row that survives crashes and deploys.
Your database is where truth lives, queue.redis is how replicas talk to each other, and durable=True turns acceptance into a promise.
Quickstart
durable_queue.py
202 is returned after the queue row commits. Poll for the result:
status (PENDING, RUNNING, PAUSED, COMPLETED, CANCELLED, or ERROR) and, once finished, content.
The 202 contract
Every background submission, durable or not, returns the same shape:
The
background and stream form fields select the execution mode:
Teams and workflows use the same fields under
/teams/{team_id}/runs and /workflows/{workflow_id}/runs. See Background Execution for the SDK-level arun(background=True) API and the SSE resume protocol.
Background execution requires a
db on the agent, team, or workflow. Submissions without one are refused with 400.The AgentOS Control Plane submits every chat run with
background=true. Runs started from the UI go through the same path as any other background submission: the concurrency cap applies, and the queue applies if your AgentOS is configured with QueueConfig(durable=True).Without durability
The run lives in the memory of the replica that accepted it. If that process dies, every waiting and in-flight run on it is lost, and nothing marks them as failed. In a multi-replica deployment,
/resume and /cancel only work on the replica that holds the run.
With durability
QueueConfig(durable=True) writes each accepted run as a row in the queue table before the 202 is sent. A worker on every replica claims rows and executes them. If a replica dies, its runs are either reclaimed by another replica or marked failed, depending on max_attempts.
See Durable queue for the exact guarantee, retry policy, idempotency keys, and configuration.
With more than one replica
SetQueueConfig(redis=...) as soon as you run two or more replicas behind a load balancer. One setting installs both the event stream and the cancellation manager on each replica, backed by a shared Redis, so a run started on one replica can be watched, resumed, and cancelled from any other. No set_cancellation_manager() or set_event_stream() call is needed.
See Multi-replica deployments for what Redis does here, and why queue.redis is a different job from db=RedisDb.
Upgrading from v2
Background runs are capped at 32 per replica in v3. In v2 each submission spawned an unboundedasyncio.create_task; now runs beyond the cap wait as PENDING. Raise or disable the cap with QueueConfig(max_concurrency=...) or AGNO_BACKGROUND_MAX_CONCURRENCY. Durability, Redis coordination, idempotency keys, session ordering, and the /queue endpoints are opt-in through QueueConfig.
Guides
Durable queue
Acceptance as a committed row. Crash semantics, retries, idempotency, session ordering.
Multi-replica deployments
Wire events out and cancels in through Redis. Coordination versus job storage.
Human-in-the-loop continuations
Continue a paused durable run through the queue under the same run_id.
Operations and monitoring
Dead-letter listing, requeue, queue stats, retention, admin gating.