Deploy Hatchet
Task queue and workflow engine for background jobs
hatchet-dashboard
Just deployed
Just deployed
/var/lib/postgresql/data
hatchet-scheduler
Just deployed
hatchet-engine
Just deployed
hatchet-controllers
Just deployed
Deploy and Host Hatchet on Railway
Hatchet is an open-source task queue and durable workflow engine built on Postgres. It replaces the Celery-plus-Redis or BullMQ layer in a backend with a scheduler that keeps every task, retry, timeout and result in a database you can query, plus a dashboard to watch it happen. Teams reach for it when background jobs stop being fire-and-forget: payment settlement, document processing, multi-step AI agents, fan-out work that must finish exactly once. Workers stay in your codebase in Python, TypeScript or Go, and Hatchet queues, assigns, retries and records what they do.
Deploy Hatchet on Railway and the control plane arrives split into the roles its production documentation describes, rather than one container doing everything. The dashboard serves the React UI and the REST API. The engine exposes the gRPC endpoint your workers dial, published through a Railway TCP proxy because gRPC needs an end-to-end HTTP/2 connection. A controllers service runs tickers, retries and retention sweeps, and a scheduler assigns queued tasks to worker slots. All four share one managed Postgres database holding tenants, run history and the queue itself, so there is no broker to run.

Getting Started with Hatchet on Railway
Set ADMIN_EMAIL and ADMIN_PASSWORD before you deploy — the password needs 8 to 64 characters with at least one uppercase letter, one lowercase letter and one number. That account is created the first time the dashboard boots, along with a tenant named Default, and public signup is off so nobody else can register. Sign in at the dashboard URL and you land on the Runs page. Mint a worker token first: Settings, then the API Tokens tab. The token embeds the dashboard URL and the engine's public gRPC address, so a worker needs nothing beyond HATCHET_CLIENT_TOKEN and HATCHET_CLIENT_TLS_STRATEGY=none. Start a worker from any SDK quickstart and it appears on the Workers page within seconds, with its tasks and slots. Trigger one of those tasks — from your own code, or with the Trigger Run button — and the run should turn green in under a second, with input, output and a timestamped activity log on the run detail panel. That round trip proves the stack works.



About Hosting Hatchet
Hatchet sits between the code that requests work and the code that performs it. Your application calls a task by name; Hatchet queues it in Postgres, picks a worker with a free slot, streams the assignment over gRPC, and records the outcome. Because durability lives in Postgres rather than an in-memory broker, a worker crash or a redeploy costs nothing — the task is reassigned. Self-hosting also keeps task payloads, which often carry customer data, on your own infrastructure.
Features worth knowing about:
- Durable execution — tasks survive worker restarts, with retries, timeouts and dashboard replay
- DAG workflows and child tasks — chain steps, fan out and in, pass results along
- Scheduling — cron jobs, one-off runs and event-triggered tasks
- Concurrency and rate limits — global or per-key, so one tenant cannot starve others
- Observability — per-run logs, activity timelines, queue metrics, OpenTelemetry
- Multi-tenancy — tenants with their own tokens and workers
The four services map to that design directly: the dashboard hosts the UI and REST API, the engine owns the gRPC dispatcher and is the only one reachable from outside the private network, controllers handle retries, ticking and retention, and the scheduler assigns tasks to workers. Postgres is the source of truth for all four.
Why Deploy Hatchet on Railway
Railway removes most of the operational work self-hosting Hatchet involves:
- Managed Postgres, provisioned and wired to all four services
- A TCP proxy for the gRPC endpoint, so remote workers connect with no extra networking
- HTTPS and a public domain for the dashboard, issued automatically
- Health checks on every role, including the two with no HTTP surface
- Independent scaling per role
Common Use Cases
- Background jobs for a web app — send email, generate PDFs or sync APIs without blocking a request
- AI agent orchestration — long-running agent runs with retries, cancellation and streamed output
- Scheduled work — nightly reports, billing runs and data refreshes on cron
- Fan-out data pipelines — split a job into thousands of child tasks, collect the results
Dependencies for Hatchet
ghcr.io/hatchet-dev/hatchet/hatchet-dashboard— React dashboard and the REST API serverghcr.io/hatchet-dev/hatchet/hatchet-engine— the engine, run three times as the gRPC API, the controllers and the schedulerghcr.io/hatchet-dev/hatchet/hatchet-migrateandhatchet-admin— migrations and key generation at boot- Railway managed Postgres — application data, task queue and pub/sub
Sources: hatchet-dev/hatchet upstream, and gridalpha/hatchet-railway for the Railway build, which runs migrations and generates the encryption keys the roles share.
Environment Variables Reference
| Variable | Purpose |
|---|---|
ADMIN_EMAIL | Email for the first admin user |
ADMIN_PASSWORD | 8–64 chars, mixed case and a digit |
SERVER_ALLOW_SIGNUP | Set true to reopen public registration |
SERVER_LIMITS_DEFAULT_TENANT_RETENTION_PERIOD | Run history retention, default 720h |
SERVER_AUTH_GOOGLE_ENABLED | Enables Google sign-in with client credentials |
Deployment Dependencies
- Self-hosting docs and the
SERVER_*configuration reference - Python, TypeScript and Go SDKs, from the same repository
Hardware Requirements for Self-Hosting Hatchet
| Resource | Minimum | Recommended |
|---|---|---|
| CPU | 2 vCPU across all services | 4+ vCPU |
| RAM | 2 GB total | 4–8 GB |
| Storage | 5 GB Postgres volume | 20 GB+ at high task volume |
| Runtime | Postgres 15+ | Postgres 16+ |
Every run, event and log line is a Postgres row, so size the volume against throughput, not the application.
Self-Hosting Hatchet with Docker
The quickest local instance is the all-in-one image, which bundles engine, API and dashboard in one container and needs only a Postgres URL:
docker run -p 8888:8888 -p 7077:7077 \
-e DATABASE_URL="postgresql://hatchet:hatchet@postgres:5432/hatchet" \
-e SERVER_GRPC_BIND_ADDRESS=0.0.0.0 -e SERVER_GRPC_INSECURE=t \
-e SERVER_GRPC_BROADCAST_ADDRESS=localhost:7077 \
-e SERVER_URL=http://localhost:8888 \
ghcr.io/hatchet-dev/hatchet/hatchet-lite:latest
For production, run the roles separately as this template does, pointing each at the same database and encryption keysets. Connecting a worker is identical either way — this Python example registers a task and waits for work:
from hatchet_sdk import Context, EmptyModel, Hatchet
hatchet = Hatchet()
@hatchet.task(name="charge-order")
def charge_order(input: EmptyModel, ctx: Context) -> dict:
return {"status": "settled"}
hatchet.worker("billing-worker", slots=5, workflows=[charge_order]).start()
Set HATCHET_CLIENT_TOKEN from the dashboard plus HATCHET_CLIENT_TLS_STRATEGY=none, and the SDK reads the engine address from the token.
How Much Does Hatchet Cost to Self-Host?
Hatchet is open source under the MIT licence, with no seat limits or usage tiers on any feature in this template. The company sells Hatchet Cloud, a managed version of the same engine; that is the only paid option. On Railway you pay for the compute and Postgres storage the services use, so a low-volume instance runs at a few dollars a month.
FAQ
What is Hatchet?
Hatchet is an open-source background task queue and workflow engine built on Postgres. Applications enqueue tasks by name and workers in Python, TypeScript or Go execute them, with retries, timeouts, concurrency limits and full run history.
What does this Railway template deploy?
Four services plus a database: a dashboard with the REST API, a gRPC engine for workers, controllers, a scheduler and managed Postgres. Migrations and encryption keys are handled at boot.
Why does this template include a Postgres database?
Postgres is not only Hatchet's application database — it is the task queue and pub/sub layer too. That is what makes tasks durable across restarts, and why no Redis or RabbitMQ is needed.
How do my workers connect to self-hosted Hatchet?
Through the engine's public gRPC address, which Railway exposes as a TCP proxy endpoint. Create an API token, set it as HATCHET_CLIENT_TOKEN with HATCHET_CLIENT_TLS_STRATEGY=none, and the SDK reads the address from the token. Workers run anywhere, including another Railway service.
How is Hatchet different from Celery or BullMQ?
Celery and BullMQ are libraries backed by a broker you operate; Hatchet is a service with its own scheduler, dashboard and durable state in Postgres. Retries, DAG workflows, rate limits and run history are built in, not assembled from extensions.
Template Content
hatchet-dashboard
gridalpha/hatchet-railwayhatchet-scheduler
gridalpha/hatchet-railwayhatchet-engine
gridalpha/hatchet-railwayhatchet-controllers
gridalpha/hatchet-railway