Background workers are long-running processes with no HTTP port — queue consumers, stream processors, or any workload that does useful work without serving traffic. They share the same deploy, secrets, and lifecycle machinery as web services. Use a cron job when the process should start on a schedule and exit after finishing.
Declare a worker
In render.yaml — the worker is a sibling of the web service, often sharing the same
repo and image but branching on an env var:
# render.yaml — from examples/stack-demo/render.yaml
services:
- name: web
type: web
runtime: docker
repo: https://github.com/bex-co/bex
rootDir: examples/stack-demo
plan: free
healthCheckPath: /healthz
envVars:
- key: DATABASE_URL
fromDatabase:
name: db
property: connectionString
- name: worker
type: worker
runtime: docker
repo: https://github.com/bex-co/bex
rootDir: examples/stack-demo
envVars:
- key: ROLE
value: worker # the shared image branches on ROLE (web is the default)
- key: DATABASE_URL
fromDatabase:
name: db
property: connectionString
databases:
- name: db
plan: freeThe example creates a database, web service, and worker. From a clone of the Bex
repository, follow the Blueprint authentication and validation steps,
then validate and apply examples/stack-demo/render.yaml. Review all three resources
and their plans before deploying. The type: worker service gets a Deployment with no
Service or Ingress — no port, no readiness probe, no public URL.
Lifecycle and secrets
Workers use the same verbs as web services — restart, suspend, and resume are operational fields that reconcile without a new build. Configure credentials through environment variables and secrets. The database reference in this example supplies the worker connection string without committing the credential to Git.
Use the dashboard lifecycle controls or the authenticated API commands in the lifecycle guide.
Verify that the worker is doing work
A running worker has no HTTP readiness check. Inspect its logs and verify the application-level outcome: a consumed queue message, updated row, or completed task. A live deployment does not prove that a queue connection works or that useful work is being processed.
Design consumers to handle interrupted processing and duplicate delivery. A deploy, restart, or machine failure can stop a process while it owns a job. Acknowledge work after it is safely completed, and handle termination so the worker can stop accepting new work before it exits.
For a downloadable Postgres producer/worker with SKIP LOCKED claims, leases,
and inspectable results, see Durable job workers.
Scaling a worker adds concurrent consumers. Confirm that the queue and task implementation support that concurrency before increasing the instance count. If a worker exits immediately, check that its command starts a long-running consumer rather than a one-off script. If it remains running but idle, check queue credentials, network access, and the queue name.
Related pages
- Which service type to use? — compare all service types
- Cron jobs — for scheduled, run-to-completion work
- Secrets — give workers their credentials
- App lifecycle: restart, suspend, resume — restart or suspend a worker without redeploying