Switching clouds? Get up to $10K in credits + hands-on help.

Apply now

Preview environments as agent sandboxes

The sandbox problem for agent-generated code

AI coding agents change the economics of pull requests. Your team can now receive dozens of agent-generated pull requests per day, each written by a system that never ran the code on real infrastructure. Diff review and unit tests catch some errors, but they can't fully verify runtime behavior: whether a migration applies, whether the service boots, whether configuration resolves correctly. Preview environments are the natural sandbox for this problem because they already solve per-PR isolation: every pull request gets its own running copy of the application stack.

This article explains why full-stack isolation is structurally suited to verifying agent output, how to configure it, how to keep it affordable at agent volume, and how your review process changes when the review artifact is a running environment rather than a diff. If you want background on the underlying continuous deployment and preview mechanics this pattern builds on, see how to implement continuous deployment in your development workflow.

Why agent PRs need full-stack verification

A preview environment is an ephemeral, isolated deployment of your application stack that spins up automatically when a pull request opens (when previews.generation is set to automatic). Its verification value comes from a specific property: it exercises the integrated system, not just the changed lines.

Static review and CI unit tests catch logic errors, style violations, and regressions in tested paths. What they catch less reliably is the class of integration-level failures agents commonly introduce:

  • Broken migrations: a schema change that fails to apply, or applies in an order incompatible with the application code deployed alongside it.
  • Missing or incorrect environment variables: an agent references a config key that exists in its training context but not in your environment. Diff review shows the reference, not the boot failure.
  • Dependency version drift: a lockfile change that resolves differently in a clean build than the agent assumed.
  • Misconfigured build or start commands: changes to build tooling that pass linting but fail during an actual deploy.

Some of these surface in a clean CI build with a throwaway test database. But a per-PR isolated stack (application instance, database, and scoped environment variables together) verifies them the way production would: through a real deploy lifecycle, a real boot sequence, and a real health check. For human PRs, this is a convenience. For agent PRs, where no human ever ran the code locally, it's the primary evidence that the change works.

Anatomy of a per-PR isolated stack

A per-PR isolated environment consists of three provisioned components:

  1. An isolated application instance. Each pull request deploys its own service instance with a unique URL, built from the PR branch. Deploy status and health checks apply to this instance exactly as they would in production.
  2. An isolated database instance. You can provision a dedicated database per PR, so agent-written migrations execute against a database that no other PR or environment touches. A failed migration breaks one preview, not shared staging. Note the limitation: a freshly provisioned preview database does not copy data from your existing services, so it verifies that a migration applies cleanly, not how it behaves against production data volumes, lock contention, or multi-step upgrade paths. Those risks require separate load or staging validation. (If you need initial setup such as seeding, use Preview Environment Initialization.) For how an agent or Blueprint can provision that database, see provisioning Postgres from a coding agent.
  3. Scoped environment variables. Environment variables resolve per-environment, so preview instances receive preview-specific values, such as the connection string of their own database, rather than shared or production credentials. You can also set a previewValue on any environment variable to override a production API key with a test key, so agent code running in a preview never touches production credentials; note that sync: false placeholder secrets are not copied to preview environments. See environment variable configuration for scoping mechanics.

You define this stack declaratively in a render.yaml Blueprint. This simplified render.yaml snippet illustrates how to configure a preview environment with its own database:

For production, add secret management, connection pooling settings, and access controls appropriate to your team's security requirements. This snippet is illustrative and requires adaptation to your specific stack before use.

The fromDatabase reference is the key relationship. In a preview environment, it resolves to the preview's own database copy, so your application and data layer are isolated together.

Cost controls for high-volume agent PRs

Cost is the primary scaling constraint for agent-driven previews. Preview resources are billed just like regular Render services and are prorated by the second. If an agent opens twenty PRs per day and each preview runs a production-sized instance indefinitely, your spend grows linearly with agent activity. Four configuration levers make this sustainable.

Instance sizing. Preview environments don't need production capacity. They need enough capacity to boot, migrate, and serve a reviewer's traffic. You can specify a smaller plan for preview instances than for your production service. For most service types, set the previews.plan field. For Render Postgres and Key Value instances, set the previewPlan field. If you don't specify a preview instance type, Render uses the same instance type you use in production.

Expiry policies. Automatic expiry tears down a preview environment after a defined number of days without any new commits. This bounds the cost of abandoned or stalled agent PRs (the ones an agent opened but no human ever triaged). The expiration time is reset with every push to the preview environment, and the default is no expiry.

Instance count. If your production service runs multiple instances, set previews.numInstances so previews run fewer, since a preview doesn't need production-level horizontal scale.

Disk size. For services with attached disks, set previewDiskSizeGB to provision a smaller disk for previews than production uses.

This illustrates a minimal pattern for setting instance size and expiry on preview environments:

For production, add monitoring to track preview environment spend and alerting for environments approaching expiry. This snippet is illustrative and requires adaptation to your specific stack before use.

Use this sizing heuristic: preview cost per PR ≈ (preview instance hourly cost + preview database hourly cost) × average PR lifetime. Expiry caps the lifetime term, and plan selection caps the hourly term. Tune both against your team's actual review cadence: a three-day expiry suits teams that triage agent PRs daily, while a shorter window suits higher-volume pipelines.

How review changes when the author is an agent

Reviewing agent output shifts your central question from "is this code correct?" to "does this system behave correctly?" The diff remains necessary. But the running preview becomes your primary review artifact, because it encodes evidence the diff can't.

Run these infrastructure-focused checks against the live preview:

  • Deploy status: Did the deploy reach live, or did it fail during build or pre-deploy? A failed deploy is an immediate, unambiguous rejection signal.
  • Migration application: Did the schema migration run cleanly against the preview database? Check deploy logs for the pre-deploy command output. (Note: the pre-deploy command requires a paid instance type.)
  • Health checks: Does the configured health check path return success after boot? A health check succeeds on a 2xx or 3xx response, confirming the app started with resolvable configuration.
  • Environment variable resolution: Does the app connect to its own preview database, confirming the agent didn't hardcode a connection string or reference a nonexistent key?
  • Behavioral spot-check: Exercise the changed feature at the preview URL directly.

These checks are fast (minutes, not hours), and no diff can substitute for them.

If you want to block agent PRs from merging until a human explicitly signs off, you can extend this with a human-in-the-loop approval gate that pauses the workflow until someone approves.

Full workflow: PR open to teardown

The lifecycle is a closed loop with five stages:

  1. PR opens. The agent pushes a branch and opens a pull request, and automatic preview generation triggers.
  2. Environment provisions. Render creates the app instance, the isolated database, and scoped environment variables, then runs the deploy, including any pre-deploy migration command.
  3. CI verifies against the live stack. Automated checks run against the preview URL, testing the deployed system rather than a local build.
  4. Reviewer inspects. You perform the infrastructure-focused checks described above.
  5. Teardown on merge or close. When the PR merges or closes, or the expiry window elapses, the environment and its database tear down automatically, leaving no orphaned resources.

A minimal example showing how a CI step might reference the preview environment URL for verification:

For production, add retry logic, timeout handling, and failure notifications back to the PR. This snippet is illustrative and requires adaptation to your specific stack before use.

Common mistakes

  • Migrations not scoped to the preview database. If a migration command reads a hardcoded or shared connection string instead of the preview-scoped DATABASE_URL, an agent PR can mutate shared staging data. Always resolve the database connection from the environment.
  • No expiry policy. Without previews.expireAfterDays, preview environments are retained until their associated pull request is closed, so abandoned agent PRs accumulate running infrastructure. Cost creep from long-lived previews is a common operational failure at agent volume.
  • Production-sized preview instances. Defaulting previews to the production plan multiplies cost with zero verification benefit.
  • Treating preview verification as optional for agent PRs. For human PRs, skipping the preview is a shortcut. For agent PRs, it removes the only runtime evidence that exists.
  • Assuming an empty preview database validates data-scale behavior. It validates schema application, not performance or locking under production load.

Isolation is the trust mechanism

Agent-generated code becomes safe to merge when it has demonstrably run: deployed, migrated, booted, and health-checked in an isolated, disposable stack that tears itself down when the PR closes. Preview environments require a Pro workspace or higher.

Frequently asked questions