> How async coding agents queue tasks, run in sandboxes, open draft PRs and pass CI. Provider limits, cost controls, review design and failure modes.
>
> Web page: https://balazscsorba.com/blog/background-agents-async-pr-workflow · Language: English · Also available in: [Deutsch](https://balazscsorba.com/de/blog/background-agents-async-pr-workflow.md) · [Magyar](https://balazscsorba.com/hu/blog/background-agents-async-pr-workflow.md)
> Author: Balázs Csorba · Published: 2026-10-17 · Keywords: background coding agent, async coding agent, cloud coding agent pull request, copilot coding agent limits, codex cloud tasks, claude code cloud sessions, jules coding agent limits, agent pull request review, coding agent sandbox, agent CI gating, cost per merged pull request

[Blog](https://balazscsorba.com/blog)/AI agents

# Background coding agents that open PRs: a practical async workflow

How async coding agents queue tasks, run in sandboxes, open draft PRs and pass CI. Provider limits, cost controls, review design and failure modes.

[Balázs Csorba](https://balazscsorba.com/about)·October 17, 2026·12 min read

-   Coding agents
-   Pull requests
-   CI
-   Code review
-   Automation

![One card in a tray fanning out to five pads, all arrows leading to one page behind a gate.](https://balazscsorba.com/images/blog/background-agents-async-pr-workflow/cover.webp?v=3ffd1f8c72)

## Key takeaways

-   An async coding agent moves the bottleneck from writing code to defining the task, running CI and reviewing the result.
-   The queue entry is the specification: one observable goal, a test command, allowed paths and explicit non-goals.
-   Sandbox, branch protection, workflow approval and required checks are separate controls; a sandbox alone protects the host, not the repository.
-   Time-box every run and budget every task; the useful cost metric is cost per merged pull request, not cost per session.
-   Most rejected agent PRs fail on coordination, CI and review capacity rather than on model capability.

On this page

1.  [Why asynchronous changes the unit of work](https://balazscsorba.com/#why-async-agents)
2.  [Anatomy of an async PR pipeline](https://balazscsorba.com/#anatomy)
3.  [The queue is the product](https://balazscsorba.com/#task-queue)
4.  [Sandboxes: what the agent can touch](https://balazscsorba.com/#sandbox)
5.  [Long runs, timeouts and resumability](https://balazscsorba.com/#long-runs)
6.  [CI is the first reviewer](https://balazscsorba.com/#ci-gating)
7.  [Human review is the bottleneck](https://balazscsorba.com/#human-review)
8.  [Cost control per task, not per token](https://balazscsorba.com/#cost-control)
9.  [Failure modes and the guardrail for each](https://balazscsorba.com/#failure-modes)
10.  [Rolling it out without drowning in PRs](https://balazscsorba.com/#rollout)
11.  [Sources](https://balazscsorba.com/#sources)

Listen to this article

0:000:00

A coding agent used to be something you watched. You typed a request, approved each command, and waited for the diff. The current generation of cloud agents changed that interaction: you hand a task to a queue, close the laptop, and come back to a branch or a pull request. OpenAI Codex cloud, GitHub Copilot cloud agent, Claude Code cloud sessions and Google Jules all follow the same pattern, with different limits and different ideas about what the agent may touch.

That sounds like a convenience feature. It is really a change in the unit of work. An asynchronous agent produces artefacts that other people have to review, and every weak point in your repository workflow becomes visible at machine speed: vague issues, slow CI, missing branch protection, an unreviewed backlog. This post is about the workflow around the agent — the queue, the sandbox, the CI gate, the human review, the cost meter and the failure modes I design for.

## Why asynchronous changes the unit of work

A synchronous agent waits for you, so its throughput is your attention. An asynchronous agent runs unattended, consumes a budget and produces work that enters the same review pipeline as a colleague's branch. DORA's 2025 survey found that 90% of technology professionals use AI at work and 30% report little or no trust in AI-generated code, with higher adoption linked to both throughput and instability. The trade is parallel attempts in exchange for verification work — and only tasks with a machine-checkable definition of done belong in that trade.

## Anatomy of an async PR pipeline

Strip away the branding and the pipeline is the same everywhere. A task enters a queue; a worker provisions an environment; the agent edits and runs commands; the result becomes a branch and a pull request; CI runs; a human reviews; the merge either happens or sends the task back. The interesting differences are in the limits at each stage, not in the diagram.

The loop is the important part. A pipeline that cannot send a failed run back with context turns every CI failure into a new task.

Two properties separate a task from a chat: the agent needs a definition of done it can check, and the environment must be reproducible enough that a green run means something. An agent that cannot run your tests is guessing, and a PR full of guesses is worse than no PR. The loop mechanics are covered in [the agent loop, explained](https://balazscsorba.com/blog/agent-loop-explained).

System

How a task enters

Isolation and network

Published limits

GitHub Copilot cloud agent

Assign an issue, mention `@copilot`, or start from the agents panel

Ephemeral environment powered by GitHub Actions; firewall on by default

59-minute session; one branch and one pull request per task; cannot approve or merge

OpenAI Codex cloud

Task in Codex cloud, GitHub, Linear or Slack

Per-task container; agent internet off by default; setup secrets removed

Container cached up to 12 hours; PR opened on request

Claude Code cloud

`claude.ai/code`, `claude --cloud`, or a routine

Anthropic-managed VM; limited network; git credentials outside the sandbox

Counts toward plan limits; idle sessions expire

Google Jules

Prompt, `jules` label, or API session

Google Cloud VM with internet access

15, 100 or 300 tasks per day; 3, 15 or 60 concurrent

These are defaults, not ceilings. Self-hosted runners, custom environments and larger runners move some of them. What does not move is the shape: a queue, a scoped execution environment, a branch, a gate and a reviewer.

## The queue is the product

An async agent cannot ask what you meant, or the answer arrives hours later. The queue entry is the specification: one observable goal, the command that proves it, the paths in scope and the non-goals. If the issue template cannot express that, the task is not ready.

Duplicates are the clearest sign of a queue problem. In a manually coded sample of 600 rejected agent pull requests, 142 — 23% — were closed because the work already existed elsewhere. The agent did not write bad code; it wrote code nobody needed. Deduplicate before enqueueing, not after the pull request opens.

```
type AgentTask = {
  id: string;                 // dedupe key: repo + issue + base commit
  repo: string;
  base: string;
  goal: string;               // one sentence, testable
  acceptance: string[];       // observable outcomes
  testCommand: string;        // the agent must run this
  allowedPaths: string[];     // everything else is out of scope
  maxMinutes: number;
  maxCiRetries: number;
};
```

Store the envelope with the task and make the id the dedupe key: repository, issue and base commit. When the base branch moves, re-run against it instead of opening a second pull request. A queue without a work-in-progress limit is a pull request generator; I cap tasks per reviewer, not per agent.

## Sandboxes: what the agent can touch

Three boundaries decide the blast radius: what the agent can write, what it can reach on the network, and which credentials it can spend. The hosted products make different choices, and the differences matter more than the model name in the task envelope.

GitHub's Copilot cloud agent runs in an ephemeral GitHub Actions environment with a firewall enabled by default, can push only to a single branch, and cannot run `git push` directly. Codex cloud runs setup scripts with internet access, then turns agent internet off by default; secrets are available only during setup and removed before the agent phase. Claude Code cloud keeps git credentials and signing keys outside the sandbox and attaches them through a proxy.

The mistake is treating the sandbox as the whole security model. A branch that CI runs with repository secrets is an execution path, and an agent that can edit `.github/workflows` can change that path. Copilot's default is instructive: workflows from its pull requests do not run until a write-access user approves them. That is separate from the firewall, and you need both.

**A sandbox protects the host, not the repository**

Isolation stops an agent from reading your laptop or your neighbours' data. It does not stop a bad commit, a weakened test, or an edited workflow that later receives secrets. Treat every agent branch as untrusted: protect the default branch, require checks and review, restrict who approves workflow runs, and put `CODEOWNERS` on CI and test files. The checklist in [AI agent sandbox checklist](https://balazscsorba.com/blog/sandboxing-coding-agents-ci-checklist) goes through the layers in order.

## Long runs, timeouts and resumability

Async does not mean unbounded. Copilot caps each session at 59 minutes and does not let you extend it. Claude Code caches a setup script only when it finishes in roughly five minutes, and idle cloud sessions are reclaimed. Codex caches container state for up to 12 hours, a performance feature rather than a promise that a task can run that long.

Design for interruption: commit checkpoints to the branch, write the plan to a file in the repository, and start the next run from the last green commit. A task that cannot survive a timeout leaves a half-finished PR and a second task to clean it up.

```
// Lease longer than the longest allowed run; heartbeat while the agent works.
const lease = await queue.claim({ visibilityTimeout: 90 * 60 });
try {
  const run = await sandbox.start({
    task: lease.task,
    network: "allowlist",
  });
  const result = await run.wait({ timeoutMs: lease.task.maxMinutes * 60_000 });
  if (result.exitCode !== 0) throw new Error(result.summary);
  await git.pushBranch(result.branch);
  await github.openDraftPr({ branch: result.branch, task: lease.task });
  await queue.ack(lease.id);
} catch (error) {
  await queue.nack(lease.id, { reason: String(error) });
}
```

The queue semantics matter more than the product: a visibility timeout longer than the maximum run, a heartbeat, an acknowledgement only after the PR exists, and a dead-letter path. GitHub Actions, SQS or Temporal can express that; a cron job without a lease cannot.

## CI is the first reviewer

Branch protection turns the pull request into a gate. Required checks can be strict (the branch must be up to date) or loose (merge now, risk a broken base). A merge queue tests the PR against the latest base and the PRs ahead of it, so green means green on what will actually merge.

```
name: ci
on:
  pull_request:
  merge_group:

concurrency:
  group: ci-${{ github.ref }}
  cancel-in-progress: true

permissions:
  contents: read

jobs:
  test:
    runs-on: ubuntu-latest
    timeout-minutes: 20
    steps:
      - uses: actions/checkout@v5
      - uses: actions/setup-node@v4
        with: { node-version: 22, cache: npm }
      - run: npm ci
      - run: npm test -- --run
```

An agent pull request is an untrusted contribution with a trusted-looking author name. That is why workflow approval, least-privilege `permissions` and branch protection belong in the design, not in a cleanup task afterwards. The same principle is the subject of [harness engineering for coding agents](https://balazscsorba.com/blog/harness-engineering-coding-agents): guides tell the agent what good looks like, sensors tell it — and you — when it missed.

The cost of a red pipeline is not only the re-run. In the 33,596-PR study, each additional failed CI check was associated with roughly 15% lower odds of merge. A failing check is a rejection signal that compounds. Make the suite fast and deterministic before scaling agents; otherwise you are buying retries, not throughput.

## Human review is the bottleneck

The empirical picture is more interesting than the anecdote. Ehsani and colleagues analysed 33,596 agent-authored pull requests from five coding agents: 71.48% were merged. In a manually coded sample of 600 rejected PRs, reviewer abandonment was the largest category at 38%, followed by duplicate PRs at 23% and CI or test failure at 17%. Only 2% were classified as agent-level issues. Peralta and colleagues looked at 11,048 closed agent PRs and found that only 35.7% of rejections were clear agent failures; 31.2% were workflow constraints and 33.1% had no observable rationale.

The conclusion is not that agents are good or bad. It is that merge outcomes measure the workflow as much as the model. A duplicate PR and an abandoned PR are queue failures. A red CI run is often an environment failure. If you instrument only the agent's code, you will misread all three as model quality.

-   Open the pull request as a draft, with the task, the test command and a short summary of what changed. Do not make the reviewer reconstruct the request from the diff.
-   Require green required checks before the PR can be marked ready. A draft that turns green is a signal; a draft that is green because CI never ran is a trap.
-   Review the tests as a separate change. Ask whether a test would fail without the production change, and whether any assertion was weakened.
-   Keep one reviewer accountable per task, cap that person's drafts, and never let the requester be the only approver. Copilot enforces the last rule; branch protection can enforce it for every other agent.

This is the same capacity problem described in [AI code review is the bottleneck now](https://balazscsorba.com/blog/ai-generated-pr-review-bottleneck), and the same design question as [human in the loop for AI agents](https://balazscsorba.com/blog/human-in-the-loop-ai-agents): where does a person have to look, and what are they accountable for? For an agent PR the answer is the diff, the tests and the rollout risk — not the agent's summary.

## Cost control per task, not per token

An async agent has four meters: model tokens, CI minutes, sandbox time and human review. The first three are visible on an invoice. The fourth is the one that decides whether the workflow pays for itself.

Meter

What consumes it

Lever

Model tokens

Input context, thinking, tool calls and output on every turn

Tighter task scope, smaller model where it holds, max turns

CI minutes

Every push, every re-run and the merge queue

Fail fast, cancel superseded runs, fix flaky tests

Sandbox time

VM or container minutes, including setup

Cache dependencies, cap wall clock, stop idle sessions

Human review

The scarcest and least instrumented resource

Small diffs, WIP limit per reviewer, draft first

The vendors meter differently. GitHub moved Copilot to usage-based billing on 1 June 2026: model usage is billed in AI credits and the agent's infrastructure consumes Actions minutes. Codex cloud tasks share the plan allowance with local messages, and OpenAI estimates a typical GPT-5.6 Sol task at 2 to 15 credits. Claude Code cloud sessions count toward plan limits with no separate VM charge. Jules sells task counts and concurrency: 15/3 on entry, 100/15 on Pro, 300/60 on Ultra.

Track cost per merged pull request, not per session: tokens plus CI plus sandbox plus review minutes, divided by merged PRs. A cheap task that never merges is expensive; a costly task that removes a week of work is cheap. Cap concurrency before optimising prompts.

## Failure modes and the guardrail for each

The failure modes are predictable enough to design against. The percentages below come from the manually coded sample of rejected agent PRs, so they describe what rejection looks like, not the base rate across all tasks.

Failure

Symptom

Guardrail

Duplicate work

Two PRs for the same issue; one is closed as superseded (23% of the rejected sample)

Dedupe key, claim label, search open and recently closed PRs before enqueueing

Red on arrival

The agent opens a PR that fails CI immediately (17%)

Run the test command in the sandbox; block ready-for-review until checks pass

Reviewer abandonment

The PR receives no meaningful human review and is closed stale (38%)

Assign a reviewer at open, set an SLA, close stale drafts automatically

Test weakening

The diff makes the test pass by deleting or loosening assertions

CODEOWNERS on tests, review the test diff separately, require a failing test first

Prompt injection

Hidden instructions in an issue, README or dependency page steer the agent

Treat issue text as untrusted, strip hidden characters, no secrets in the agent phase, network allowlist

Scope creep

A small task becomes a multi-file rewrite that nobody can review

Path allowlist and a diff budget; split the task instead of expanding it

One more failure is easy to miss because it looks like success: the agent fixes the CI failure by changing the test. A green pipeline is evidence only if the test would have caught the bug. Review the test diff before the production diff, and require a failing test that reproduces the issue when the task is a bug fix.

## Rolling it out without drowning in PRs

Start with work where success is machine-checkable and the blast radius is small. The 33k-PR study found the highest merge rates for documentation (84%), CI (79%) and build (74%) tasks, and the lowest for performance (55%) and bug fixes (64%). That ordering is a sensible rollout order.

1.  Pick one repository and two task types: documentation and test coverage are the safest start.
2.  Write the task template with a goal, acceptance criteria, a test command, allowed paths and non-goals.
3.  Require a draft PR, green checks and one human approval before merge. Turn on branch protection first.
4.  Cap work in progress per reviewer and per agent. Measure the queue, not the agent's token usage.
5.  Track merge rate, time to review, CI failure rate and cost per merged PR for four weeks before expanding.
6.  Add bug fixes only after the test suite is trustworthy enough that a green run means something.

An async agent is a multiplier on whatever workflow it enters. With fast CI, clear ownership and small PRs, it removes routine work. With flaky tests and no reviewer capacity, it manufactures a backlog with better commit messages.

## Sources

1.  [GitHub Docs: About GitHub Copilot cloud agent](https://docs.github.com/en/copilot/concepts/agents/coding-agent/about-coding-agent)
2.  [GitHub Docs: Risks and mitigations for Copilot cloud agent](https://docs.github.com/en/copilot/concepts/agents/cloud-agent/risks-and-mitigations)
3.  [OpenAI Developers: Codex cloud environments](https://developers.openai.com/codex/cloud/environments)
4.  [Anthropic: Use Claude Code in the cloud](https://code.claude.com/docs/en/claude-code-on-the-web)
5.  [Google Jules: Limits and plans](https://jules.google/docs/usage-limits/)
6.  [Google Jules: Getting started](https://jules.google/docs/)
7.  [GitHub Docs: About protected branches](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/about-protected-branches)
8.  [GitHub Docs: Models and pricing for GitHub Copilot](https://docs.github.com/en/copilot/reference/copilot-billing/models-and-pricing)
9.  [OpenAI Developers: Codex pricing](https://developers.openai.com/codex/pricing)
10.  [Ehsani et al.: Where Do AI Coding Agents Fail? An Empirical Study of Failed Agentic Pull Requests in GitHub (MSR 2026, arXiv 2601.15195)](https://arxiv.org/abs/2601.15195)
11.  [Peralta et al.: Why Are Agentic Pull Requests Merged or Rejected? An Empirical Study (MSR 2026, arXiv 2605.22534)](https://arxiv.org/abs/2605.22534)
12.  [DORA: State of AI-assisted Software Development 2025](https://dora.dev/dora-report-2025)

## Frequently asked questions

What is a background coding agent?

A coding agent that runs asynchronously on remote infrastructure instead of in your editor. You submit a task, it works in its own sandbox, pushes a branch and usually opens a pull request. Codex cloud, Copilot cloud agent, Claude Code cloud sessions and Jules all work this way.

Can an agent merge its own pull request?

Not on the hosted products described here. Copilot cloud agent cannot mark a pull request ready for review, approve it or merge it, and the person who asked for the change cannot approve it either. Branch protection should enforce the same rule for any other agent.

How long should a background task run?

Short enough that a failed run is cheap. Copilot enforces a hard 59-minute session limit. Claude Code reclaims idle cloud sessions and caches a setup script only when it finishes in roughly five minutes. If a task needs longer than an hour, split it into stages with a commit or a plan file between them.

How do I prevent duplicate agent pull requests?

Deduplicate before enqueueing. Use a key built from repository, issue and base commit, search open and recently closed pull requests for the same change, and give the task a claim label. In one sample of rejected agent PRs, 23% were duplicates of existing work.

Do I need self-hosted runners for background agents?

Not necessarily. The hosted products provide managed VMs or GitHub Actions environments. Self-hosted runners and self-hosted environments matter when the agent needs private network access, a specific hardware profile, or a data boundary your compliance team requires.

Why do so many agent pull requests get closed without review?

Because review capacity, not agent capacity, is the constraint. In a study of 600 rejected agent PRs, 38% were abandoned without meaningful human engagement. Assigning a reviewer when the PR opens and limiting work in progress matters more than another prompt tweak.

Written by Balázs Csorba

Senior fullstack & AI engineer in Styria, Austria – 10+ years of Vue, Nuxt, Node.js and PHP, now building tooling for AI agents.

[AI engineering & MCP servers →](https://balazscsorba.com/expertise/ai-engineer)[About me →](https://balazscsorba.com/about)

## More articles

-   [Designing tools for AI agents: names, descriptions, schemas and error messages](https://balazscsorba.com/blog/agent-tool-design-descriptions-errors)
-   [Migrating a legacy codebase with coding agents: a strangler fig playbook](https://balazscsorba.com/blog/coding-agents-legacy-codebase-migration)
-   [Context rot in long-running agents: clearing, compaction, memory and sub-agents](https://balazscsorba.com/blog/context-rot-compaction-long-running-agents)
-   [Browser agents for E2E testing: let agents write Playwright tests, not run them](https://balazscsorba.com/blog/browser-agents-e2e-testing-playwright)

## Sounds like what you need?

Tell me about your project or role – I’d love to hear from you.

[Get in touch](mailto:contact@balazscsorba.com) [Connect on LinkedIn](https://www.linkedin.com/in/balazs-csorba)
