Skip to main content
Railway is a great fit for Output deployments — it handles Docker builds automatically and scales horizontally out of the box. 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.

Step 1: Set up Railway project

  1. Go to Railway’s dashboard and click New Project
  2. Select Deploy from GitHub repo and connect your repository
  3. Railway will detect your project — don’t deploy yet, we need to configure services first

Step 2: Deploy the Output API

The Output API is published as a Docker image. Deploy it first so you can verify the connection to Temporal before adding the worker.
  1. Click + NewDocker Image
  2. Enter: docker.io/outputai/api:0.1
  3. Configure variables:
  1. Go to SettingsNetworking and generate a Railway domain (or add your custom domain)
  2. Configure scaling:
  1. Deploy the service and verify it’s running:
You should get a 200 OK response.
Use the same OUTPUT_API_AUTH_TOKEN value when calling the API from your application. Railway can auto-generate secure values — click the dice icon next to the variable value.

Step 3: Create the worker Dockerfile

With the API running, we’ll prepare the worker. First, add the ops/ directory and a Dockerfile to your repository. Create ops/Dockerfile:
ops/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 Railway plan and workflow memory requirements.
Commit the new ops/ directory and push to GitHub before continuing:

Step 4: Configure and deploy the worker

  1. Click on the service Railway created from your repo (or create a new one pointing to your repo)
  2. Go to Settings and configure:
  1. Go to Variables and add:
Use Railway’s Raw Editor to paste multiple variables at once. For sensitive values, Railway encrypts them automatically.
  1. Configure Scaling (in Settings → Deploy):
  1. Deploy the worker service

Step 5: Verify

Now that the worker is deployed, verify it has connected to the API and your workflows are registered.
  1. Check that the API can see your workflows 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 Railway and try again after a moment.
  1. Run a workflow end-to-end:

Config as code (optional)

Railway supports configuration in a railway.json file. This is useful for reproducible deployments:
railway.json
Railway’s config-as-code only covers build/deploy settings for a single service, not full project scaffolding. Environment variables must still be set in the dashboard.

Environment-specific configuration

Use Railway’s environments for staging vs production:
railway.json

Tuning worker concurrency

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

Monitoring

Railway dashboard

Railway provides built-in metrics for:
  • CPU and memory usage
  • Network traffic
  • Deployment 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 Railway 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
  2. Upgrade Railway plan for more resources
  3. Check for memory leaks in workflow code (large payloads, unbounded arrays)

Credentials not found

  1. Verify config/credentials.yml.enc (or the environment-scoped equivalent) exists in your repo and is committed
  2. Verify OUTPUT_CREDENTIALS_KEY (or the environment-scoped variant) is set in Railway with the correct master key
  3. Verify the Dockerfile includes COPY config/ ./config/ — without it, the encrypted file never reaches the container

Build failures

  1. Check Dockerfile path is correct
  2. Verify all dependencies are in package.json
  3. Review build logs for specific errors