Skip to main content
Render is a cloud platform that supports infrastructure-as-code via a render.yaml Blueprint. You define your services in a single file, connect your GitHub repo, and Render handles the rest. Here’s what we’ll do:

Project structure

After running output init, your repository looks like this:
This is the default structure — it doesn’t include any deployment configuration yet. During this guide, we’ll add an ops/ directory containing a Dockerfile for the worker, and a render.yaml Blueprint at the root.

Step 1: Create the worker Dockerfile

Create the ops/ directory and add ops/render.Dockerfile for your worker:
ops/render.Dockerfile
The NODE_OPTIONS setting allocates 80% of container memory to the V8 heap, leaving room for the Temporal Rust runtime and OS overhead. Adjust the percentage based on your Render plan and workflow memory requirements.
Don’t commit yet — we’ll add the render.yaml Blueprint next and commit everything together.

Step 2: Create the Render Blueprint

Render’s Blueprint Spec lets you define your entire infrastructure in a single render.yaml file. When you connect your repo, Render reads this file and provisions all services automatically. Create render.yaml at the root of your repository:
render.yaml

Adding Redis for remote tracing

For production debugging, you can add Redis as a Render service and reference it using fromService. This keeps everything in one Blueprint and Render handles the connection string automatically:
render.yaml
Then add these env vars to your worker service to enable remote tracing:
The fromService reference automatically injects the Redis connection string — no need to manage it manually. See Advanced configuration for more on remote tracing.

Blueprint key concepts

Service types:
  • type: web — The API. Render assigns it a public URL and routes HTTP traffic to it.
  • type: worker — The worker. No public URL, just runs your Dockerfile.
Secret handling with sync: false: Variables marked sync: false are secrets. Render prompts you to enter their values when you first deploy the Blueprint. They won’t be committed to your repo.
Auto-generated values: Use generateValue: true for tokens that just need to be a random secure string. Render generates and stores the value for you.

API keys and credentials in production

Your workflows need API keys (Anthropic, OpenAI, etc.) to run. Instead of pasting each key into Render as a separate secret, Output lets you store all your keys in one encrypted file that lives in your repo. Render only needs one secret — the master key that unlocks the file. Here’s how it works:

1. Put all your API keys into encrypted credentials

If you haven’t already, initialize credentials and add your keys:
This opens an editor. Add all the API keys your workflows need:
Save and close. This creates two files:
  • config/credentials/production.yml.enc — the encrypted file. Commit this to your repo. It’s encrypted and safe to push.
  • config/credentials/production.key — the master key. Never commit this. It’s already in .gitignore.

2. Add the master key to Render

Copy the contents of config/credentials/production.key and add it to your worker service in Render as a secret env var:
This is the only secret you need to manage in Render. Everything else comes from the encrypted file.

3. Reference keys in your Blueprint with credential:

In render.yaml, instead of setting each API key as a separate secret, pass a credential: reference as a plain string. The SDK resolves these automatically when the worker starts:
When the worker starts, the SDK reads these env vars, sees they start with credential:, decrypts the credentials file using the master key, and replaces the values with the real API keys — before any workflow code runs.
The credential: pattern works for any env var the AI SDK or your code reads from process.env. Just add the key to your encrypted credentials and reference it in render.yaml.

Rotating a key

To change an API key in production:
Render redeploys automatically. No env var changes needed — the master key stays the same. Commit the new files and push to GitHub before continuing:

Step 3: Deploy

  1. Go to Render’s dashboard and click NewBlueprint
  2. Connect your GitHub repository
  3. Render detects render.yaml and shows the services it will create
  4. Enter values for any sync: false secrets when prompted
  5. Click Apply to provision all services
Render assigns a .onrender.com subdomain to web services automatically. You can add a custom domain in the service settings.

Step 4: Verify

Once both services are running, verify the API is up and the worker has registered your workflows.
  1. Check the API is healthy:
You should get a 200 OK response.
  1. Confirm the worker has connected and your workflows are registered via the catalog endpoint:
You should see a JSON response listing your registered workflows. If the list is empty, the worker may still be starting up — check the worker logs in Render and try again after a moment.
  1. Run a workflow end-to-end:

Tuning worker concurrency

For high-throughput workloads, you can tune how aggressively the worker pulls and executes tasks from Temporal. Add these to your worker’s envVars:
The defaults work for most workloads. Only tune these if you’re seeing task queue backlog in the Temporal UI.

Monitoring

Render dashboard

Render provides built-in metrics for:
  • CPU and memory usage per service
  • Deploy history and logs

Temporal Cloud

Monitor workflow executions in the Temporal Cloud UI:
  • Active workflows
  • Failed executions
  • Workflow history

Traces

If you’ve enabled remote tracing, traces are stored in Redis and optionally uploaded to S3.

Scaling considerations

Workers scale independently from the API. If workflows are queuing up in Temporal, add more workers. If API response times are slow, add more API instances.

Troubleshooting

Worker not picking up jobs

  1. Check the Temporal UI for pending workflows
  2. Verify TEMPORAL_ADDRESS, TEMPORAL_NAMESPACE, and TEMPORAL_API_KEY are correct
  3. Check worker logs in Render for connection errors

Trace files not appearing

  1. Verify OUTPUT_REDIS_URL is set and Redis is running
  2. Check OUTPUT_TRACE_REMOTE_ON=true is set
  3. For S3, verify AWS credentials have write access to the bucket

Out of memory errors

  1. Increase NODE_OPTIONS memory allocation in the Dockerfile
  2. Upgrade Render plan for more resources
  3. Check for memory leaks in workflow code (large payloads, unbounded arrays)

Credentials not found (MissingCredentialError)

  1. Verify config/credentials/production.yml.enc exists in your repo (not just config/credentials.yml.enc — the Dockerfile sets NODE_ENV=production, which makes the SDK look for the scoped path)
  2. Verify OUTPUT_CREDENTIALS_KEY_PRODUCTION is set in Render with the correct master key
  3. Verify the Dockerfile includes COPY config/ ./config/ — without it, the encrypted file never reaches the container
  4. If using credential: references for API keys (e.g. ANTHROPIC_API_KEY=credential:anthropic.api_key), make sure the encrypted credentials file actually contains that key path

Build failures

  1. Check Dockerfile path matches dockerfilePath in render.yaml
  2. Verify all dependencies are in package.json
  3. Review build logs in the Render dashboard