Every engineering team I talk to right now is running coding agents. Cursor, Windsurf, Claude Code, Copilot. Engineers are faster. PRs are flying in. And yet, when I zoom out and look at cycle time, DORA metrics, or just the size of the backlog at these organizations, nothing has moved.
I keep seeing the same pattern. We automated the typing, but we didn’t automate the system.
The fix is to get agents off the laptop. Let them run in the background, triggered by events in your workflow, producing PRs that get deployed and validated automatically. The tooling to do this exists today across GitHub, GitLab, and standalone agents like Claude Code. And if you’re deploying to Upsun, you already have the deployment infrastructure these agents need: git-native deployments, preview environments on every PR, and infrastructure defined as code in your repo.
This article walks through how to set it up.
The localhost ceiling
An engineer fires up a coding agent on their laptop. The agent writes code, runs tests, maybe opens a PR. That engineer is genuinely 2-3x faster on individual tasks.
Now multiply that by a team of twenty. PRs pile up in review queues. CI pipelines back up. Merge conflicts stack. The bottleneck just shifted downstream, and the agent that created the PR can’t help with any of it. It’s tethered to one developer’s machine, running in one session, working on one thing at a time.
Violet = faster with agents. Dark = downstream bottlenecks untouched. The speed gains never reach the end of the pipeline.
Ona calls this “the false summit.” Individual speed gains that never compound into organizational velocity. Teams adopt coding agents, individual output goes up, and DORA metrics stay flat. The backlog grows. It doesn’t shrink.
Background agents break this pattern. They run in isolated cloud environments, get triggered by events (an issue labeled, a test failing, a schedule firing), produce pull requests, and let Upsun deploy those PRs into preview environments for validation. The human reviews a running application, not just a diff.
What a background agent actually is
A coding agent (Cursor, Claude Code in your terminal, etc.) needs your machine and your attention. You’re in the loop: watching, steering, intervening.
A background agent needs neither. It runs in its own environment in the cloud, with a full toolchain, test suite, database access. You kick it off and walk away. Check the result from your phone. When it’s done, it submits a pull request. Your job is to review and decide whether to merge.
The mental model that sticks: think of it as a junior engineer. Capable, can handle many tasks, but needs guardrails. You’d scope their access, define what good output looks like, and review their work before it ships.
Setting up background agents on GitHub
GitHub gives you two paths to background agents: Copilot coding agent (built into GitHub) and Claude Code Action (open-source, runs on GitHub Actions).
GitHub Copilot coding agent
Copilot’s coding agent is the simplest entry point. You assign a GitHub issue to Copilot the same way you’d assign it to a teammate, and it goes to work. It plans, writes code, runs tests, self-reviews with Copilot code review, and opens a pull request.
The agent runs in a GitHub Actions-powered environment. To customize that environment (install dependencies, set up databases, configure tooling), you create a copilot-setup-steps.yml file in .github/workflows/. This file must contain a single job named copilot-setup-steps:
name: Copilot Setup Steps
on: workflow_dispatch
jobs:
copilot-setup-steps:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'npm'
- run: npm ci
- name: Install system dependencies
run: sudo apt-get update && sudo apt-get install -y sqlite3
The job name is strict. If it’s not called copilot-setup-steps, Copilot won’t pick it up. If any setup step fails, Copilot skips the rest and starts working with whatever’s available.
To trigger the agent, you assign an issue to Copilot. It reads the issue, creates a branch, works through the implementation, runs your test suite, self-reviews, and opens a PR. The PR then triggers your normal CI pipeline and, on Upsun, spins up a preview environment where the changes are deployed and running.
Claude Code Action
For more control, or if you’re not on a Copilot plan, Claude Code Action is an open-source GitHub Action that runs Claude Code in your CI. You can trigger it from issue comments, issue assignments, PR events, or on a schedule.
The fastest setup path: open Claude Code in your terminal and run /install-github-app. That walks you through the GitHub app installation and secrets configuration.
For issue-to-PR automation, you’d set up a workflow like this:
name: Claude Background Agent
on:
issues:
types: [assigned]
jobs:
handle_issue:
if: github.event.assignee.login == 'claude[bot]'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: anthropics/claude-code-action@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
Assign an issue to the Claude bot, and the workflow kicks off. Claude reads the issue, works on the code, and opens a PR.
You can also set up scheduled maintenance agents that run on a cron:
name: Weekly Dependency Check
on:
schedule:
- cron: '0 9 * * MON'
jobs:
maintenance:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: anthropics/claude-code-action@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
mode: automation
prompt: |
Check for outdated dependencies.
If any have new stable releases, open a PR
updating each one individually with a clear
description of what changed.
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
Both approaches produce PRs. Both trigger Upsun preview deployments automatically.
Setting up background agents on GitLab
GitLab’s approach is the Duo Agent Platform, which hit general availability in January 2026. The core flow for background agents is “Issue to Merge Request”: you point Duo at a well-scoped issue, and it builds a draft MR with the implementation.
Prerequisites
You need a few things enabled. In your project settings, go to Settings > General > GitLab Duo and enable the “Allow flow execution” toggle. The feature flags duo_workflow and duo_workflow_in_ci need to be active on your instance. You need Developer permissions or higher on the project.
Using the Issue to MR flow
Once enabled, the workflow is straightforward. Open an issue with clear requirements and acceptance criteria. Below the issue header, select “Generate MR with Duo.” You can monitor progress under Automate > Sessions.
The agent reads the issue, plans an implementation, creates a branch, writes the code, and opens a draft merge request. From there, your normal CI/CD pipeline takes over, and if you’re deploying to Upsun, the MR triggers a preview environment deployment.
Writing good issues for agents
This matters more than most teams realize. The quality of the agent’s output maps directly to the quality of the issue description. Break complex tasks into smaller, focused issues. Write specific acceptance criteria. Include enough context about your codebase conventions that the agent can follow them.
A bad issue: “Fix the login bug.” A good issue: “The login form on /auth/login returns a 500 when the email field contains a + character. The validation in src/auth/validator.ts doesn’t handle RFC 5321 addr-spec encoding. Fix the regex in validateEmail() and add a test case for plus-addressing.”
The same principle applies to all three agent platforms. The more structured your input, the better the output.
Deploying agent PRs to Upsun
Here’s where Upsun connects to all of the above. Regardless of which agent platform you use (Copilot, Claude Code, GitLab Duo), the output is the same: a pull request or merge request against your repository.
Upsun is fully git-native. Every deployment is a git push. Every preview environment is a git branch. There’s no separate control plane to authenticate against, no dashboard-only settings that agents can’t reach. When an agent pushes a branch and opens a PR, Upsun sees it and deploys it automatically.
Dark = human steps. Violet = agent steps. Lime = Upsun. Green = verification and delivery.
Each preview environment is an isolated, production-parity deployment with its own services, data, and URL. The agent’s PR doesn’t just pass tests in CI. It gets deployed, and you can click through the running application before merging. Tests verify logic. Preview environments verify that the thing actually works when deployed.
For background agents, this is a meaningful difference. You’re not reviewing a diff and hoping the deployment works. You’re reviewing a running application.
Infrastructure as code: agents can change more than application code
Most background agent discussions focus on code changes. Fix a bug. Address an issue. Patch a CVE. But there’s a much bigger surface area that almost nobody is talking about yet.
On Upsun, infrastructure is defined as code. YAML configuration files committed alongside your application code in the same repository. Services, databases, runtimes, routes, cron jobs. All of it version-controlled, all of it deployed through git.
That means an agent can change infrastructure, not just application code.
Think about what that looks like in practice. An agent branches your repository, bumps your PostgreSQL version from 15 to 16 in the config, and opens a PR. Upsun sees that PR, spins up a preview environment with PostgreSQL 16 running, deploys your application against it, and runs your test suite. You’re not reading a config diff and hoping it works. You’re looking at a running deployment with the upgraded database actually serving requests.
The same applies to adding a Redis cache, swapping a search backend, resizing containers, testing a new PHP or Python runtime version, or splitting a monolith service into two. Because Upsun treats infrastructure configuration as part of the repository, an agent can propose architectural changes the same way it proposes code changes. And because every PR gets a preview environment, those architectural changes get deployed and validated automatically.
The agent proposes infrastructure changes. Upsun deploys and validates them. The human only sees PRs that are ready, with a running environment to prove it.
Imagine a scheduled agent that runs weekly, checks your stack against current stable releases, and opens PRs to test upgrades. Each PR deploys a full environment. Your CI runs against the upgraded stack. If the tests pass, the PR sits there waiting for a human to review. If they fail, the agent can read the logs, try a fix, and push again.
I haven’t seen many teams doing this yet. But the pieces are all there. The constraint was never the agent’s ability to edit a YAML file. It was the lack of a platform that would actually deploy the result and let you validate it. That constraint doesn’t exist on Upsun.
Git as the universal interface
There’s a reason Upsun maps well to background agents, and it’s worth stating plainly: everything runs through git.
Every deployment is a git push. Every preview environment is a git branch. Infrastructure config, application code, routes, services, cron jobs: all committed to the repository. There’s no separate control plane, no dashboard-only settings that agents can’t reach, no imperative API calls to manage infrastructure state.
Everything lives in the repo. Everything deploys through git. Agents don’t need a separate interface.
For background agents, this is exactly the right interface. Agents already know how to work with git. They clone repos, create branches, make commits, open pull requests. When your entire platform operates through that same mechanism, there’s no translation layer. An agent that can open a PR can deploy infrastructure. An agent that can push a branch can spin up an environment.
A lot of the friction in getting background agents into production comes from integration complexity: custom API clients, separate auth flows, imperative provisioning scripts. When the platform’s interface is git, most of that goes away. The agent doesn’t need special tooling to interact with Upsun. It needs the same git access it already has.
Governance: don’t skip this
Governance is the one teams skip, and it’s the one that matters most. It means three things: identity, permissions, and audit trails.
The agent needs a real identity in your systems. Not a shared service account. Permissions need to be scoped to what the agent needs for the task at hand. And you need to trace back what the agent did, when, and on whose authority.
On GitHub, Copilot coding agent runs under its own identity with scoped permissions. Claude Code Action runs on your GitHub Actions runner with whatever secrets and permissions you configure in the workflow file. On GitLab, Duo agents operate within the project’s permission model.
The principle of least privilege matters more here than anywhere else. Models hallucinate. Prompts can get injected. Design the governance model assuming the agent will sometimes do the wrong thing, and make sure the blast radius stays small.
Governance enforced by a system prompt (“please don’t delete files”) is a suggestion. Governance enforced at the execution layer (deny lists, scoped credentials, deterministic command blocking) is actual governance. Without that distinction, your security team will veto autonomous agents. And they’d be right to.
Where to start
Start with one workflow. Something well-defined, with a clear start and end. When a specific issue gets labeled, create a PR that addresses it. That’s a tight closed loop where you can measure whether the agent did the right thing.
Pick your agent platform based on what you already use. On GitHub, try Copilot coding agent by assigning an issue, or set up Claude Code Action for more control. On GitLab, enable Duo Agent Platform and use the Issue to MR flow. Both integrate with Upsun through the same mechanism: git.
Don’t skip governance, even for a pilot. The habits you build early define the system you end up with.
And if your agents are still running on localhost, that’s the first thing to change. The false summit doesn’t clear itself. Last modified on April 14, 2026