Render Tutorials
Localhost Part 2: Run AI agents as Render Workflows

Deploy the workflow agents

⏱ 9 min

Pattern 3 deploys as two services. A gateway web service receives PR submissions and dispatches workflow runs. A workflow service registers and runs the tasks. The Blueprint creates the gateway; the workflow service is a separate Dashboard step because Blueprints do not yet create or manage Workflows.

flowchart LR
  pr(["PR URL"])
  gw["Gateway<br/>web service"]
  wf["Workflow service<br/>runs the tasks"]

  pr --> gw
  gw -->|dispatch run| wf
  wf --> cr["code-review task"]

Inside the run, the built-in code-review task runs prepare diff and filter diff as plain functions, then fans out security, performance, and ux (frontend only) as their own tasks, and ends with judge.

1. Deploy the gateway Blueprint

The Pattern 3 Blueprint provisions the gateway web service and a Postgres database.

Use packages/workflow-agents/render.yaml.

packages/workflow-agents/render.yaml
projects:
- name: <YOUR_USERNAME>-agents-workshop-workflows
environments:
- name: production
databases:
- name: <YOUR_USERNAME>-workflow-agents-db
plan: basic-256mb
region: oregon
postgresMajorVersion: "18"
services:
- type: web
name: <YOUR_USERNAME>-agents-gateway
runtime: node
region: oregon
plan: starter
buildCommand: npm ci
startCommand: npm run start --workspace @workshop/workflow-agents
healthCheckPath: /healthz
envVars:
- key: DATABASE_URL
fromDatabase:
name: <YOUR_USERNAME>-workflow-agents-db
property: connectionString
- fromGroup: workflow-shared-keys
- key: NODE_ENV
value: production

Use packages/workflow_agents/render.yaml.

packages/workflow_agents/render.yaml
projects:
- name: <YOUR_USERNAME>-agents-workshop-workflows
environments:
- name: production
databases:
- name: <YOUR_USERNAME>-workflow-agents-db
plan: basic-256mb
region: oregon
postgresMajorVersion: "18"
services:
- type: web
name: <YOUR_USERNAME>-agents-gateway
runtime: python
region: oregon
plan: starter
buildCommand: pip install uv && uv sync --frozen --no-dev --package workshop-workflow-agents
startCommand: uv run python -m workflow_agents.server
healthCheckPath: /healthz
envVars:
- key: DATABASE_URL
fromDatabase:
name: <YOUR_USERNAME>-workflow-agents-db
property: connectionString
- fromGroup: workflow-shared-keys
- key: NODE_ENV
value: production
- key: PYTHON_VERSION
value: "3.12"

The gateway writes review rows to Postgres and dispatches real Render Workflow runs. DATABASE_URL comes from <YOUR_USERNAME>-workflow-agents-db. Shared secrets such as RENDER_API_KEY and OPENAI_API_KEY come from the workflow-shared-keys environment group.

  1. Start a new Blueprint In the Render Dashboard, click + New, then Blueprint. If you haven’t connected GitHub yet, click Connect GitHub and authorize the Render app for your fork.
  2. Select your fork Pick your workflow workshop fork from your connected repos.
  3. Set the Blueprint Path Set it to your track’s Pattern 3 path, exactly: packages/workflow-agents/render.yaml (TypeScript) or packages/workflow_agents/render.yaml (Python). Mind the hyphen vs underscore. There’s no root render.yaml.
  4. Create all as new services

    Then click Deploy Blueprint. You get the gateway web service and Postgres.

    The Render Dashboard Blueprint setup page showing the workflow agents Blueprint path and Deploy Blueprint button.
    Deploy the Pattern 3 Blueprint to create the gateway web service and Postgres.
A failed Render deploy showing the gateway exiting with status 1 and the error RENDER_WORKFLOW_SLUG is required for production Workflow dispatch.
The gateway's first deploy fails until you set RENDER_WORKFLOW_SLUG. This is expected.

2. Create the workflow service

This is the step that is easy to miss. The workflow service runs the workflow entrypoint, which registers and executes the tasks. The Blueprint does not create it.

Two things to get right, or the rest of the tutorial fights you: attach the service to your project, and name it with your username first.

First, get to the New Workflow form:

  1. Open your project Click into the project the Blueprint just created.
  2. Add a new service From inside the project, click + New service and choose Workflow. Starting from inside the project pre-fills the Project field, so the service lands next to the gateway and database. If you start from the top nav instead, the field is empty and you must pick your project from the Project dropdown before you deploy, or the services split apart.
  3. Select your fork

    Choose your connected workflow workshop repo.

    The Render Dashboard Workflow service setup form showing language, root directory, build command, start command, and database URL.
    The New Workflow form. Set each field to the value in the table for your track.

Then set every field. Type each value exactly, character for character. Root Directory, Build Command, and Start Command are where attendees slip, and a wrong value here is what fails the build later.

FieldValue
Name<your-username>-workflow-agents
RegionOregon (match the gateway and database)
LanguageNode
Root Directorypackages/workflow-agents
Build Commandcd ../.. && npm ci
Start Commandcd ../.. && npm run start:workflow --workspace @workshop/workflow-agents

The cd ../.. on both commands is not optional. The service builds from packages/workflow-agents, but npm ci has to run from the monorepo root to read the root lockfile and workspaces.

FieldValue
Name<your-username>-workflow-agents
RegionOregon (match the gateway and database)
LanguagePython
Root Directorypackages/workflow_agents
Build Commandpip install uv && uv sync --frozen --no-dev
Start Commanduv run python -m workflow_agents.workflow

Keep the uv run on the start command. Bare python can’t see the uv workspace packages, and the service crash-loops with ModuleNotFoundError.

With the fields set, finish the service:

  1. Wire DATABASE_URL On the Environment tab, set DATABASE_URL to the internal connection string for <your-username>-workflow-agents-db, the same database the gateway uses.
  2. Link the environment group

    On the same Environment tab, scroll to Linked Environment Groups, pick workflow-shared-keys from Link Environment Group, and click Link, rebuild, and register. This is how the workflow service receives the workshop OPENAI_API_KEY without pasting it by hand.

    The Linked Environment Groups section with workflow-shared-keys selected and the Link, rebuild, and register action.
    Link the workflow-shared-keys group so the service receives OPENAI_API_KEY.
  3. Deploy the workflow service Click Deploy workflow. The first deploy takes a couple of minutes. Wait for the service to show as live before proceeding — the gateway can’t dispatch runs until the workflow service has registered its tasks.

Confirm the workflow service landed in the same project as the gateway. If the two services split apart, you started the + New flow from outside the project.

Prefer the CLI? Create the service with one command

Make sure you’re logged in and pointed at the workshop workspace (see the CLI setup note in Section 3), then have your repo URL, branch, and the internal connection string for <your-username>-workflow-agents-db ready.

Terminal
render workflows create \
--name <your-username>-workflow-agents \
--repo <your-repo-url> \
--branch <your-branch> \
--root-directory packages/workflow-agents \
--runtime node \
--region oregon \
--build-command "cd ../.. && npm ci" \
--run-command "cd ../.. && npm run start:workflow --workspace @workshop/workflow-agents" \
--output json \
--confirm

The cd ../.. on both commands is not optional. The service builds from packages/workflow-agents, but npm ci has to run from the monorepo root to read the root lockfile and workspaces. Drop it and the build fails.

Terminal
render workflows create \
--name <your-username>-workflow-agents \
--repo <your-repo-url> \
--branch <your-branch> \
--root-directory packages/workflow_agents \
--runtime python \
--region oregon \
--build-command "pip install uv && uv sync --frozen --no-dev" \
--run-command "uv run python -m workflow_agents.workflow" \
--output json \
--confirm

Keep the uv run on the start command. Bare python can’t see the uv workspace packages, and the service crash-loops with ModuleNotFoundError.

After the command completes, set DATABASE_URL and link the environment group from the service’s Environment tab in the Dashboard. Then deploy:

Terminal
render workflows deploy --name <your-username>-workflow-agents

Confirm the service exists and read back its slug:

Terminal
render workflows list

It should list <your-username>-workflow-agents. That exact slug is what you wire into the gateway in Section 3. The first deploy takes a couple of minutes — wait for it to finish before proceeding.

3. Set the workflow slug on the gateway

The gateway needs one value from you: RENDER_WORKFLOW_SLUG, the name of the workflow service you just created. It’s your personal slug, so it can’t live in the shared group. Everything else is already wired:

VariableWhere it comes from
RENDER_WORKFLOW_SLUGYou set it on the gateway, below
RENDER_API_KEYThe shared workflow-shared-keys group
OPENAI_API_KEYThe same group
DATABASE_URLThe gateway from its Blueprint database, the workflow service from the connection string you set in Section 2

Set the slug:

  1. Copy the workflow slug

    Open your workflow service’s page. Next to Workflow Slug, click the copy icon. It should read <your-username>-workflow-agents.

    Copying the Workflow Slug from the Render Dashboard workflow service page.
    Copy the Workflow Slug from your workflow service's page.
  2. Add the env var on the gateway Open the <your-username>-agents-gateway web service, go to the Environment tab, and click + Add variable.
  3. Type the key and paste the slug

    In the KEY field, type RENDER_WORKFLOW_SLUG exactly. In the VALUE field, paste the slug you copied. Don’t type it from memory: a typo dispatches to a slug that doesn’t exist.

    The gateway web service Environment tab with a RENDER_WORKFLOW_SLUG variable added alongside DATABASE_URL and NODE_ENV, and the Save, rebuild, and deploy button.
    On the gateway, add RENDER_WORKFLOW_SLUG and paste the slug as its value.
  4. Save and redeploy Click Save, rebuild, and deploy.

After the Workflow service deploys, confirm the task is registered:

Terminal
render workflows tasks list

In the interactive CLI, this opens a short wizard: pick your workflow (for example <your-username>-workflow-agents), then pick the ready version, then read the Tasks table. The first screen looks like a workflow list; that is expected. Success means you reach Tasks and see names such as code-review, security, performance, ux, judge, my-reviewer, and your-review.

In a non-interactive terminal (some IDE shells), pass the version id explicitly:

Terminal
render workflows versions list <your-username>-workflow-agents -o text
render workflows tasks list <wfv-id> -o text

These commands hit the Render API, not localhost: do not pass --local.

You don’t open a pull request here. You paste the URL of an existing PR into the gateway dashboard, and the gateway reviews it for you.

Open the gateway’s *.onrender.com URL. You’ll see the localhost Workshop: Workflow Agents dashboard. Copy the link to the LlamaIndex baseline PR and paste it into the dashboard. The gateway dispatches the hosted code-review workflow and creates a review row immediately.

  1. Paste the PR link Paste the PR URL into the field in the gateway dashboard and click Review. The gateway returns quickly and creates a review row instead of blocking on the whole run.
  2. Open the run trace In the Render Dashboard, open the workflow service and find the run.
  3. Read the fan-out Each reviewer is its own task. The parallel reviewers fan out, each in its own isolated container, then judge merges their findings.

The Workflow Agents gateway dashboard showing a submitted LlamaIndex baseline PR review row with status, verdict, token count, and spans.

The gateway dashboard is useful for the review record: status, verdict, tokens, run time, reason, findings, and spans. The Render Dashboard is where you inspect the Workflow run trace itself.

flowchart TB
  cr["code-review<br/>task"]
  cr --> sec["security<br/>task"]
  cr --> perf["performance<br/>task"]
  cr --> ux["ux<br/>task (frontend only)"]
  sec --> judge["judge<br/>task"]
  perf --> judge
  ux --> judge

The LlamaIndex baseline touches backend files, so security and performance run but ux is skipped. Paste the Mastra frontend PR link into the dashboard, or pick it from the dashboard picker, to watch the ux task join the fan-out.

Everything you see in that trace, the queueing, the per-task retries and timeouts, the isolation, the parallel fan-out, is what you hand-wrote in the queue helper for Pattern 2. Here it’s the platform.

Why do you create the workflow service by hand in the Dashboard instead of in the Blueprint?
Troubleshooting

Find the symptom that matches what you’re seeing, then apply the fix.

Reviews fail with a GitHub 403. GitHub’s API allows only 60 unauthenticated requests per hour per IP. A room full of attendees behind one network exhausts that fast, and prepare-diff returns 403 rate limit exceeded. Create a fine-grained GitHub PAT with public-repo read access and set it as GITHUB_TOKEN on the gateway web service and the workflow service. That raises the limit to 5,000 requests per hour.


The review row never advances and no run trace appears. You deployed the Blueprint but skipped Section 2. Pattern 3 is two services: the Blueprint creates only the gateway and Postgres. Without the separate Workflow service, the gateway dispatches to a slug that doesn’t exist. Go into the project, + New serviceWorkflow, configure it, deploy, then re-run the review.


Gateway crashes with RENDER_WORKFLOW_SLUG is required. Both Blueprints set NODE_ENV=production, which makes the gateway require this value. You have to set it: on the gateway service, set RENDER_WORKFLOW_SLUG to your Workflow service’s slug. If you namespaced, that’s <your-username>-workflow-agents, not bare workflow-agents.

The slug is the most common shared-workspace trap. Setup prefixes the gateway and database, but not the hand-created Workflow service. Use that exact slug in every later render workflows tasks start command too. Bare workflow-agents collides with other attendees or dispatches to a stranger’s service. Confirm your real slug with render workflows list.


Dispatch returns unauthorized or 401. The gateway’s RENDER_API_KEY comes from the workflow-shared-keys group, so this is rare. If you hit it, confirm the gateway is linked to that group. The key itself is workshop-managed, so you don’t set your own.


A run executes in the trace but the gateway shows no findings. The gateway and Workflow service are reading different databases. Wire the Workflow service’s DATABASE_URL to the internal connection string of your <username>-workflow-agents-db (the same DB the gateway uses), and make sure the Workflow service is in the Oregon region so the internal host resolves.


The Workflow service landed in a different project. You started + New from the top nav instead of + New service from inside the project, so the Project field wasn’t pre-filled. Delete it and recreate from inside the project the Blueprint made.


Blueprint step won’t proceed. Set the Blueprint Path explicitly: packages/workflow-agents/render.yaml (TypeScript) or packages/workflow_agents/render.yaml (Python). There’s no root render.yaml.


render workflows list returns nothing or unknown command. Unlike --local commands, this hits the API: run render login, then render workspace set and pick the workshop workspace. If render workflows is unknown, your CLI is older than 2.11; reinstall from the releases page.

unknown flag: --env-var on workflows create. Your CLI is older than 2.20. Run brew upgrade render, confirm render --version, and check which render is not a stale install earlier on your PATH.


Build fails with a lockfile or workspace error. Keep the cd ../.. on both commands. The Root Directory scopes to the package, but npm ci must run from the repo root to read the root lockfile and workspaces.

Build and Start Commands
# Build Command
cd ../.. && npm ci
# Start Command
cd ../.. && npm run start:workflow --workspace @workshop/workflow-agents

Workflow service crash-loops with ModuleNotFoundError. The Start Command needs uv run: set it to uv run python -m workflow_agents.workflow. Bare python can’t see the uv workspace packages.

What you learned

  • Deployed the Pattern 3 Blueprint: the gateway web service and Postgres
  • Created the workflow service by hand because Blueprints do not manage Workflows yet
  • Set `DATABASE_URL` from Postgres and added service-specific secrets only where needed
  • Submitted a public PR and read the run trace: each reviewer is its own task, fanned out in parallel