Skip to main content
This section covers deploying Output workflows to a production environment. Whether you’re running a single worker or scaling across multiple instances, the deployment architecture stays the same.

What you’re deploying

An Output deployment consists of two core services, with an optional third for remote tracing: The API is a lightweight HTTP server that accepts workflow execution requests, routes them to the Temporal backend, and returns results. It ships as a pre-built Docker image so there’s no custom code to maintain. The Worker is the core of your deployment — it contains your workflow code and connects to the Temporal backend for orchestration. Workers scale horizontally; you can add more instances to handle increased load without changing your workflow code.
These guides assume you’re using Temporal Cloud for workflow orchestration. If you need help setting up Temporal Cloud, see the Temporal Cloud documentation.

Prerequisites

Before deploying to any platform, ensure you have:
  • A Temporal backend with a dedicated namespace (e.g. Temporal Cloud)
  • Your workflow repository on GitHub
  • API keys for any services your workflows use (Anthropic, OpenAI, etc.)
  • Any search attributes your callers send, registered on that namespace

Search attributes

Callers can attach Temporal search attributes to a run by sending a searchAttributes map alongside input on /workflow/run or /workflow/start. Search attributes make runs queryable in Temporal (for example, all runs for one customer) without knowing individual workflow IDs:
From the CLI, pass the same map with --search-attributes: output workflow run lead_enrichment --input input.json --search-attributes '{"ClientId":"acme"}'. Each attribute must be registered on the namespace before any caller sends it. This happens once per namespace, done by whoever administers it. On Temporal Cloud, use tcld:
On a self-hosted Temporal server, use the Temporal CLI:
Re-running the self-hosted command with the same name and type is a no-op. Before any caller sends searchAttributes, upgrade the API and every worker to a version that supports them. An older API ignores the field, and an older worker doesn’t pass the attributes to hooks or child workflows. The type you register determines the JSON value callers send: Validation is fail-fast. If an attribute isn’t registered on the namespace, or its value doesn’t match the registered type, the API returns 400 and the workflow is not started. Temporal’s server-side limits on attribute count and size also apply; see the Temporal search attribute docs for current values. Child workflows, including detached ones, inherit their parent’s search attributes, and runs started with continueAsNew keep them, so every run in the tree is queryable by the same value. Temporal’s own system attributes (names starting with Temporal, plus BuildIds) are not copied to children, so don’t use the Temporal prefix for your own attributes. ./run.sh dev registers a demo WorkspaceId (Keyword) attribute on the local Temporal server so you can try this locally. Projects created with output init don’t register any attributes.
Search attribute values are stored in Temporal’s visibility store as plain values, not encoded or encrypted like workflow payloads. Don’t put secrets or other sensitive data in them.

Reading search attributes in hooks

Hooks receive a run’s search attributes in workflowDetails.searchAttributes, with each value as an array (Datetime values as ISO strings). When exporting them to a metrics system, pick specific approved keys rather than forwarding the whole map, because every distinct value becomes a tag and unbounded tag cardinality gets expensive. Search attributes are asserted by the caller: use them for attribution, not for authorization decisions.

Platform guides

Choose your deployment platform:

Railway

Railway. Simple Docker-based deployments with automatic scaling.

Render

Render. Infrastructure-as-code deployments with a single render.yaml Blueprint.

Advanced

Advanced. Remote tracing with Redis and S3 for production debugging.

Next steps

Tracing

Tracing. Configure production tracing and S3 storage.

Error Handling

Error Handling. Handle failures gracefully in production.