Migrating production infrastructure? Get up to $10K in migration credits.

Apply now

Host your own background coding agent on Render

A coding agent on your laptop stops when the laptop sleeps. It also keeps your API keys, Git tokens, and half-finished working trees on one machine. When you move the agent to Render, it keeps running while you're away, and you control the infrastructure it runs on.

This guide walks you through deploying two templates:

It then covers four decisions that work differently for coding agents than for typical web apps:

  • Which service type to use
  • Where repo checkouts live
  • How to store API keys
  • How to keep long runs alive

Scope: This guide covers coding agents that clone a repo and write code. It doesn't cover hosting LangChain or CrewAI agents, and it doesn't cover generic workflow triggering.

Prerequisites:

  • A Render account.
  • A Git repo you want the agent to work on

Choose a service type for your coding agent

When you create a service on Render, you first pick a service type based on what your code does. Render offers six service types for running code. Your choice comes down to one question: does anything need to reach the agent over the network?

  • Web service: Choose this if you want to open the agent in a browser, call it from your terminal, or send it webhooks. A web service gets a public onrender.com subdomain for receiving HTTP traffic.
  • Private service: Choose this if only your other Render services should reach the agent. A private service hosts a dynamic application that isn't reachable from the internet.
  • Background worker: Choose this if the agent runs continuously and only makes outbound connections. Background workers run continuously but don't receive incoming network traffic.

The two templates make different choices, and that difference shapes everything that follows:

  • OpenCode on Render deploys a single web service running opencode web. The service starts opencode's web UI and API on the same Render URL. You interact with the agent directly.

  • The self-hosted Cursor template deploys two services:

    • cursor-trigger-api, a public web service for incoming triggers
    • cursor-self-hosted-worker, a long-lived background worker for Cursor sessions

    The worker connects outbound over HTTPS, so it needs no inbound ports or VPN tunnels. That makes a background worker the natural fit, and it limits the public surface to the small trigger API.

Deploy the OpenCode on Render template

The opencode-on-render template runs opencode as a hosted AI coding agent. You can use it through the browser UI or connect to it with opencode attach.

The template deploys the following:

  • A single Docker-based web service on the standard plan
  • A 1 GB persistent disk for opencode state and your working tree
  • The Render OpenCode plugin, installed by default

Treat the template repo's README as the source of truth for the latest steps.

  1. Click Deploy to Render in the template README.
  2. Set REPO_URL to the repo you want cloned into the workspace. Optionally, set REPO_BRANCH. For a private GitHub repo, also set GITHUB_TOKEN to a token that can read the repo.
  3. Set ANTHROPIC_API_KEY, OPENROUTER_API_KEY, or both. Leave RENDER_API_KEY unset unless you want the agent to manage Render resources (see How API keys are stored).
  4. Finish the deploy, then open the Render service URL.
  5. Log in with the username opencode. For the password, use the generated OPENCODE_SERVER_PASSWORD value, which you'll find in the Render Dashboard.
  6. Optionally, connect from your terminal. Install the CLI with npm install -g opencode-ai, then run opencode attach https://your-service.onrender.com. Enter the generated password when prompted, or pass --username opencode --password "$OPENCODE_SERVER_PASSWORD".

The following excerpt from the template's render.yaml shows the shape of the Blueprint. Check the repo for the full file before you change it:

When the deploy succeeds, the web UI opens a project at /root/project-data/workspace. If you didn't set REPO_URL, the service creates a small default Git project there instead.

If opencode attach returns HTML instead of API responses, set OPENCODE_SERVER_COMMAND=serve to switch to the headless server. It serves the API without the browser UI, so opencode attach gets API responses.

This template gives you a remote coding agent, not a hardened sandbox. It's single-tenant, so don't share one deployment with multiple users.

Deploy the self-hosted Cursor agent template

The cursor-self-hosted-agent template runs Cursor self-hosted cloud agents on Render without Kubernetes. Code and tool execution stay in your infrastructure, while Cursor handles orchestration and model access.

The template deploys the following:

  • A worker that runs agent worker start
  • A small Node.js trigger API that launches Cursor Cloud Agents through the Cursor API
  • Optional Slack and Linear entrypoints for kickoffs and completion updates

Before you start, make sure you have the following:

  • A Cursor team plan with self-hosted agents enabled
  • A Cursor API key
  • A target repo
  • Git credentials, if the repo is private

Treat the template repo's README as the source of truth for the latest steps.

Secure the trigger API's task route before you apply the Blueprint. The Blueprint creates cursor-trigger-api as a public web service, so its routes are reachable from the internet as soon as the deploy finishes. The template's POST /v1/tasks route doesn't check authentication. Slack slash commands require SLACK_SIGNING_SECRET, Linear webhooks require LINEAR_WEBHOOK_SECRET, and Cursor webhook callbacks are verified with CURSOR_WEBHOOK_SECRET. Anyone who finds the trigger service URL can launch agents against your repo with your Cursor API key, and the Blueprint sets DEFAULT_AUTO_CREATE_PR to true. Do this in your copy of the repo: add an auth check to the POST /v1/tasks handler in apps/trigger/src/index.ts, such as a shared-secret header, or remove the route if you only trigger runs from Slack or Linear.

  1. Fork or copy the template repository to GitHub.
  2. Add an auth check to POST /v1/tasks, or remove the route (see above).
  3. In Cursor, enable self-hosted agents in the Cloud Agents dashboard.
  4. In Render, create a new Blueprint and point it at your copy of the repo.
  5. Fill in the required environment variables:
    • CURSOR_API_KEY
    • CURSOR_TARGET_REPOSITORY
    • CURSOR_WEBHOOK_SECRET
    • CURSOR_GIT_TOKEN, for private repos
    • You don't need to enter TRIGGER_HOST by hand. The Blueprint fills it from the cursor-trigger-api service's host.
  6. Check the model setting. The Blueprint defaults DEFAULT_CURSOR_MODEL to gpt-5.4-high-fast. If your account doesn't support that model, query GET /v0/models and replace the default with a supported ID.
  7. Apply the Blueprint.
  8. Open the trigger service and confirm that GET /healthz returns ok: true.
  9. Open the Cursor Cloud Agents dashboard and confirm that the worker appears as connected.

To start a run, send a task to the trigger API. This example from the README shows the request shape. Adapt the URL and the notify block for your setup:

If you added a shared-secret header, include it in this request.

You can also kick off runs from tools your team already uses. The trigger API receives Slack slash commands at POST /providers/slack/commands and Linear webhooks at POST /providers/linear/webhooks.

How the two templates compare

Use this table to see how each template handles the four decisions covered in the rest of this guide:

OpenCode on Render
Self-hosted Cursor
Service type
One web service on standard
Web service (starter) plus background worker (standard)
Repo checkout location
/root/project-data/workspace on a persistent disk
/workspace/repo, cloned at worker startup
API key storage
Render environment variables. The startup script also copies ANTHROPIC_API_KEY and OPENROUTER_API_KEY to /root/project-data/opencode/auth.json on the persistent disk
Render environment variables
Long-run behavior
Sessions and state persist on disk
Long-lived worker keeps capacity warm between runs

Where repo checkouts live

A coding agent's working tree is state, and by default Render services have an ephemeral filesystem. You lose any changes to local files every time a service redeploys or restarts. For a coding agent, that means uncommitted edits disappear unless the checkout sits somewhere durable. To store files long term, attach a persistent disk. Render snapshots persistent disks once every 24 hours, so treat snapshots as a recovery net rather than a replacement for pushing your work.

OpenCode keeps the checkout on its disk

OpenCode mounts its disk at /root/project-data. The template uses two directories on that disk:

  • /root/project-data/opencode for opencode auth, sessions, and SQLite state
  • /root/project-data/workspace for the repo the agent edits

The startup script clones only when the workspace is empty. As a result, uncommitted edits survive restarts and deploys. You should still commit and push important work back to your repo. If your repo and session history outgrow the default disk, set sizeGB to 5 for the opencode-data disk in render.yaml and deploy the updated Blueprint.

Cursor starts from a fresh clone

Cursor's worker clones CURSOR_TARGET_REPOSITORY at startup and optionally checks out CURSOR_TARGET_REF. The worker's Blueprint entry includes no disk key. Expect a fresh clone after each restart or deploy, and push work to branches or pull requests rather than leaving it on the worker.

How API keys are stored

A coding agent typically holds at least two kinds of credentials: a model provider key and a Git token that can write to your repo. On Render, you can declare placeholder environment variables for secret values and populate them from the Render Dashboard instead of committing them to render.yaml. Environment variables keep secrets such as API keys out of your application source. To set them, open your service in the Render Dashboard and click Environment. For more detail, read how Render handles secrets and environment variables.

Render also offers two other ways to provide secrets:

  • Secret files, which your service reads from its filesystem at runtime.
  • Environment groups, which share variables and secret files across services.

The combined size of all secret files for a service or environment group can't exceed 1 MB.

OpenCode copies keys to disk

The template's startup script reads ANTHROPIC_API_KEY and OPENROUTER_API_KEY from the service's environment variables and writes them into /root/project-data/opencode/auth.json in opencode's API-key auth format. RENDER_API_KEY stays in the environment. That means your keys also live on the persistent disk, alongside the workspace the agent can read. Be careful with RENDER_API_KEY. It gives the agent Render MCP access with whatever permissions that key has, so leave it unset unless you need that access.

Cursor keeps keys in the environment

Cursor's README says to set secrets as Render environment variables rather than committing them to the repo. For private repos, give the worker a dedicated Git token. For production, prefer a Cursor service account API key when your plan supports it. Both practices limit the damage if a token leaks.

Keeping long runs alive

Coding agent runs can take a long time, so where the work executes matters. Background workers run continuously. They're designed to take long-running, asynchronous tasks out of the request path.

Web services allow HTTP responses to take up to 100 minutes. An agent that does all its work inside a single request has to finish within that window. The Cursor template avoids that constraint. Its trigger service launches an agent and returns the agent URL immediately. This follows the same async handoff described in how to trigger a long-running task from a web service on Render.

Pick a plan that stays up and has enough memory

  • Free web services spin down after 15 minutes without incoming traffic, which would stop an agent that's waiting between interactions. Paid compute plans don't spin down.
  • OpenCode defaults to standard because opencode can exceed the memory available on starter.
  • Cursor starts with a starter trigger API and a standard worker. If you run large repos or heavy test suites, upgrade the worker first.

If your agent keeps running short on memory, Render's memory-optimized compute plans target agent workloads like these.

Choose between warm and single-use Cursor workers

Cursor's default long-lived worker keeps capacity warm between runs. Single-use mode starts each run from a clean worker instead. The template's architecture doc lists the tradeoff: single-use workers give cleaner isolation but take more orchestration work, so switch only when you have a provisioning strategy around the worker lifecycle. The Blueprint already defines both variables on the worker, with CURSOR_WORKER_SINGLE_USE set to false and CURSOR_WORKER_IDLE_RELEASE_TIMEOUT set to 600. To switch, change CURSOR_WORKER_SINGLE_USE to true in the Render Dashboard:

Avoid deploying mid-task

Redeploys can interrupt active work, and how depends on whether the service has a disk. The Cursor worker has no disk, so it gets zero-downtime deploys: 60 seconds after the new instance is live, Render sends SIGTERM to the original instance, then SIGKILL if the process hasn't exited within the shutdown delay (30 seconds by default). OpenCode has a persistent disk, which disables zero-downtime deploys: Render shuts down the running instance before starting the new one, so the service is briefly unavailable. Avoid deploying while an agent is mid-task. For Cursor, a redeploy also resets the worker's checkout.

Where to go from here

To get your agent running in the cloud:

  1. Pick a template.
  2. Deploy it and point it at your repo.
  3. Confirm that your key storage and repo persistence match how you work.

For more templates, browse render.com/agents. For deeper reference, read about environment variables and secrets and background workers. When you're ready to grow past a single instance, see how to deploy an AI agent on Render with auto-scaling and monitoring.

Frequently asked questions