Production setup

Add AgentCore sandboxes, S3 checkpoints, and Redis coordination to your Render deployment.

Start with your platform deployed to Render. This chapter adds a separate environment for coding agents, saves their work in S3, and coordinates live runs across API replicas with Redis.

Work with your coding agent from the same agent-platform checkout. Configure and verify each part before moving to the next.

PartWhat it adds
SandboxesRun coding agents in AgentCore, separate from the API container.
CheckpointsSave workspace and native-session state to S3 for recovery.
Redis and replicasShare live run events and cancellation across API instances.

Sandboxes and checkpoints

Run Claude and Codex engineers in a separate AgentCore environment, with S3 storing their workspace and native-session checkpoints. Your API stays on Render and uses PostgreSQL for conversations and platform records.

Complete the Render deployment first. You'll also need an AWS account, permissions to create an ECR repository, an AgentCore runtime and execution role, and a private S3 bucket. These resources incur AWS charges.

Understand what is saved

ComponentResponsibility
PostgreSQLSaved conversations, Company work, and the durable execution queue.
AgentCoreSeparate compute where the engineers check out a repository and run commands.
S3Saved workspace and native-session checkpoints for recovery after compute replacement.

A saved conversation does not recreate an engineer's working directory. Recovery starts from the last successfully saved checkpoint. Unfinished edits, live processes, and external actions are outside that checkpoint.

Build the sandbox image

From your template checkout, build its sandbox target for ARM64. Replace the image URL with your ECR repository URI and a tag you will retain:

SANDBOX_ECR_IMAGE=YOUR-ECR-URI:YOUR-TAG
docker build --target sandbox --platform linux/arm64 --load -t "${SANDBOX_ECR_IMAGE}" .

Authenticate Docker to your ECR registry and push the image using ECR's push instructions.

Create an AgentCore Runtime from this image with its execution role. Use the image's existing entrypoint, which serves Agno's sandbox protocol on port 8080. Configure the runtime for HTTP and IAM-authenticated invocation, and wait for it to become ready. See AgentCore Runtime deployment for AWS provisioning.

Keep the runtime ARN and image tag with your deployment configuration. The template does not create these AWS resources for you.

Configure the repository and checkpoint store

Create a private S3 bucket for checkpoints. Choose a prefix for this platform, such as my-platform/checkpoints/.

In app/sandbox.py, set the repository and branch to your own code:

REPOSITORY = Repository("https://github.com/YOUR-ORG/YOUR-REPO", branch="my-agent-platform")

Replace sandbox_provider() with:

def sandbox_provider() -> Sandbox | None:
    return agentcore_sandbox(
        "arn:aws:bedrock-agentcore:REGION:ACCOUNT:runtime/YOUR-RUNTIME",
        "your-checkpoint-bucket",
        checkpoint_prefix="my-platform/checkpoints/",
    )

The template's agentcore_sandbox() helper constructs AgentCoreSandbox with S3CheckpointStore. Both engineers use the selected provider. Keep the existing imports and helper functions.

Use the same bucket and prefix across this platform's API replicas, and distinct prefixes for separate platforms.

Give the API and sandbox their credentials

Configure the Render API service's AWS credentials through its environment settings or your credential provider. Set AWS_DEFAULT_REGION to the S3 bucket's region. The runtime ARN supplies the AgentCore region.

The API identity needs permission to invoke and stop the configured runtime, and to read, write, delete, and abort multipart uploads under the checkpoint prefix. Configure bucket-list permissions as needed for missing-object handling. Customer-managed KMS encryption also requires key permissions. Keep active checkpoint objects out of expiration rules.

Agno forwards the configured engineer model credentials into the sandbox. The API's AWS credentials are not automatically forwarded. Code in the sandbox can use the AgentCore execution role; grant that role the access required for the engineering work.

For a private Git repository, supply GITHUB_READ_TOKEN in the provider's env mapping. For example, add this argument to AgentCoreSandbox(...) inside agentcore_sandbox(), after importing getenv from os:

env={"GITHUB_READ_TOKEN": getenv("GITHUB_READ_TOKEN", "")},

Read the value from your environment or secret store. Configure push or pull-request permissions separately if the engineer will publish changes. The template's sandbox guide also covers Claude through Bedrock and local Docker sandboxes.

Redeploy and check recovery

Commit and push the provider configuration to the branch Render deploys. Apply any changed production environment settings with ./scripts/render/env-sync.sh.

Use a disposable repository or branch for the recovery check:

  1. Start a conversation with one engineer and ask it to create a small file in its workspace containing a unique marker.
  2. Wait for the turn to complete. Inspect logs and S3 to confirm a checkpoint was saved.
  3. Replace the API instance and stop that test sandbox session using your provider tooling.
  4. Continue the same AgentOS conversation as the same user with the same engineer. Ask it to read the marker file and continue the prior task.
  5. Inspect the restored file, native-session continuity, and run outcome. Repeat for the other engineer.

Investigate missing or inaccessible checkpoints before treating a fresh workspace as successful recovery. No persistent disk is attached to the Render API; it uses temporary files while transferring checkpoint archives.

Before using the sandbox for Company Tasks, verify the Product's saved Git Source matches REPOSITORY.url and keep the local source so Company can read the files. Test a Task through its final persisted result as well as a direct engineer run.

Redis and replicas

Keep PostgreSQL as the durable queue store and add Redis for shared live run events and cancellation. Configure shared credentials and MCP transport behavior before increasing the number of API instances.

Start from a working Render deployment. Complete sandboxes and checkpoints if your platform runs engineers, so their work is independent of API containers.

What each service does

ServiceResponsibility
PostgreSQLSaved platform data, schedule claims, and durable queued work.
RedisLive run events and cancellation shared across API instances.
AgentCore and S3Separate engineer execution and saved workspace recovery.
API replicasAccept requests and execute queued work using the same configuration.

A request can reach one API instance while another instance executes the run. Redis lets the instances coordinate that live activity. Adding replicas increases execution capacity; it does not create a separate queue for every agent.

Add a Redis-compatible service

Create a paid Render Key Value instance in the same workspace and region as the API. Use its internal connection URL and keep external access disabled unless you have a specific need for it. Choose a persistence policy appropriate for retaining live coordination data and monitor memory use.

Save the internal URL as REDIS_URL in .env.production. The URL must be reachable by every API instance.

Add redis to the dependencies in pyproject.toml, then regenerate the template's requirements:

./scripts/generate_requirements.sh

Commit both dependency files with the application changes below. Rebuild the API from the updated requirements.

Share queue coordination

In app/main.py, replace the existing queue argument with:

queue=QueueConfig(durable=True, db=db, redis=getenv("REDIS_URL")),

Keep the other AgentOS arguments. getenv, QueueConfig, and db already exist in this file. Confirm REDIS_URL is set in the production environment; leaving it unset keeps coordination local to each process.

The redis setting wires both the live event stream and distributed cancellation. PostgreSQL remains the durable queue store in this configuration.

Share internal credentials

Generate a random value once:

openssl rand -hex 32

Save it as AGENTOS_INTERNAL_SERVICE_TOKEN in .env.production, and add this argument to the existing AgentOS(...) call:

internal_service_token=getenv("AGENTOS_INTERNAL_SERVICE_TOKEN"),

AGENTOS_INTERNAL_SERVICE_TOKEN is the environment name introduced by this guide; the constructor argument above reads it. Use the same value on every replica. Otherwise, automatically generated scheduler credentials can differ between instances.

Also keep JWT verification settings, MCP_CONNECT_SECRET, AGENTOS_URL, database connections, and sandbox checkpoint settings consistent across replicas. Keep queue timing and retry settings uniform during deployment.

Configure MCP for your clients

For this guide, use stateless MCP transport so legacy transport sessions do not depend on reaching the same API instance. In app/interfaces.py, add stateless=True to the existing MCPConfig(...) inside attach_interfaces():

         default_tools=True,
+        stateless=True,
     )

Keep the existing tools list, which exposes OS Manager, and the authentication configuration in app/main.py. attach_interfaces() supplies the final MCP configuration, so changing only mcp=True in app/main.py would be overwritten.

Modern MCP requests are already sessionless. For legacy clients, stateless mode gives up server-initiated requests and transport-stream resumability; saved AgentOS conversations and runs remain separate from transport sessions. Test the clients you intend to support.

If you need legacy transport sessions, use an affinity strategy compatible with those clients and validate it through your load balancer. Affinity alone does not share live run events or cancellation.

Deploy coordination before adding replicas

Commit and push the code and dependency changes while the API still has one instance. Upload the new settings:

./scripts/render/env-sync.sh

Check startup logs, a background run, streaming, and cancellation. Once the shared configuration works, change the API service's numInstances in render.yaml from 1 to 2, commit, push, and apply the Blueprint update. See Render's Blueprint reference for instance configuration.

Keep one Uvicorn worker per instance for this guide. Account for database connections and model usage as you add instances.

Check behavior across instances

Use disposable work and inspect per-instance logs to confirm requests and execution reach different instances. Sending several requests through the public URL alone does not prove this.

CheckEvidence to retain
Submit a background run and follow it through another instanceThe same run ID and live events remain visible.
Cancel an active run from another instanceThe executing worker receives cancellation and the run reaches the expected final status.
Continue a saved conversationThe same authorized user can retrieve the saved history.
Run scheduled workClaims and authenticated execution work across instances.
Replace an API instance during disposable workThe durable queue records the outcome according to its retry policy.
Replace an engineer sandbox after a completed turnThe saved checkpoint restores as verified in the sandbox chapter.

With the default max_attempts=1, a crashed run can end as a visible failure. Enabling retries re-executes a run from its original input and can repeat external actions. Choose retry policies deliberately for tools that change external state.

Check file downloads separately: checkpoint storage is not a public artifact-delivery service.

Continue to Improve your agent.