How to Self-Host Trigger.dev in 2026
What Trigger.dev Is Best At
Trigger.dev (Apache-2.0, ~14.5K stars) is a code-first background job and workflow platform built with TypeScript, React, and Node. Developers define tasks as TypeScript functions — retries, concurrency, schedules, and long-running resumable flows are primitives, not plugins. Think "Sidekiq + Temporal + Zapier internals" for teams that want to own their automation surface without running a heavy workflow engine.
Use Trigger.dev when:
- You want background jobs defined in the same repo as your app, not in a visual builder
- Tasks can take minutes to hours (durable execution, resumability)
- You need scheduled jobs, webhooks, event triggers, and queues in one system
- You would otherwise stitch together BullMQ, a cron daemon, and custom retry logic
Core Architecture and Prerequisites
The self-hosted stack has four moving pieces:
- Web app — dashboard, API, task registration
- Workers — execute task runs, pull from queues, report results
- PostgreSQL — durable task state, run history, schedules
- Redis — coordination, rate limiting, short-term queue state
For larger deployments, an object store (S3-compatible) holds task artifacts and logs. The Trigger.dev v3+ architecture emphasizes container-based workers so task code is isolated from the control plane; plan for a container registry if you want the most flexible deployment.
Sizing rule of thumb. A single worker VM with 2 vCPU / 4 GB RAM comfortably handles low-throughput workloads (sub-100 concurrent runs, short jobs). Long-running jobs, video processing, or AI pipelines push worker memory up quickly — scale workers horizontally rather than vertically.
Docker / Self-Host Deployment Flow
The official self-host reference uses Docker Compose:
git clone https://github.com/triggerdotdev/trigger.dev
cd trigger.dev/hosting/docker
cp .env.example .env
# edit secrets, database password, APP_ORIGIN
docker compose up -d
This brings up the webapp, Postgres, and Redis, plus a worker pool. In production:
- Move Postgres and Redis to managed services (RDS/Neon, Upstash/Elasticache)
- Run the webapp behind a reverse proxy with TLS
- Deploy workers as a separate, horizontally scalable service
- Configure container registry credentials if using image-based task deployment
For Dokploy, Coolify, or Kubernetes, split the compose file into two deployments — one for the web app, one for workers — so you can scale workers independently.
Worker Concurrency and Queue Sizing
Concurrency on Trigger.dev lives at three levels: per-task, per-queue, and per-worker. Default settings will run many tasks at once, which is usually the wrong choice for anything hitting a downstream rate-limited API.
Rules that have held up in production:
- Set per-task concurrency explicitly for anything that calls external APIs
- Keep worker CPU oversubscription low — background jobs often block on I/O but spike on JSON parsing and hashing
- Separate workers into pools by workload class (fast/short vs slow/long) so a 10-minute task cannot starve a 100ms task
Measure before optimizing: the built-in dashboard exposes run duration percentiles, queue depth, and retry counts, which are enough for a first round of tuning.
Secrets, Webhooks, and Observability
Secrets are stored encrypted in the Trigger.dev database. Teams with stricter requirements can front them with an external secret manager and inject at worker boot.
Webhooks into Trigger.dev tasks are first-class — incoming webhooks trigger task runs, and outgoing HTTP calls inside tasks get automatic retry and timeout handling. Always sign webhooks at the edge (Cloudflare Worker, nginx) before they reach the task runtime.
Observability hooks into OpenTelemetry; traces and logs export to any OTLP-compatible backend. Pair it with a log sink (Loki, CloudWatch, Axiom) so you can search across runs, not just the latest dashboard view.
Backups, Upgrades, and Failure Modes
- Backups: nightly
pg_dumpof the Trigger.dev database, plus retention on object storage for task artifacts. - Upgrades: pin image tags per environment. Trigger.dev iterates quickly; always run schema migrations on a staging copy before production.
- Worker crashes: durable execution means an interrupted task resumes on another worker. Test it — run a 5-minute task, kill the worker mid-run, confirm the task completes on another.
- Database pressure: task history grows fast. Tune retention on completed runs; keep failures longer than successes.
- Redis eviction: never run Trigger.dev's Redis with
allkeys-lru. Queue state must be durable for the length of a run.
When to Pick Trigger.dev Over n8n
Trigger.dev and n8n overlap at a glance — both run workflows, both handle webhooks and schedules, both are open source. The split is audience:
- Trigger.dev belongs in an engineering org. Tasks are TypeScript; Git is the source of truth; code review and CI apply to automations just like product code. Use it when reliability, resumability, and testability matter more than non-engineer access.
- n8n belongs in an automation-heavy team where non-engineers build flows. The visual canvas is a feature, not a liability.
If both apply, it is reasonable to run both: Trigger.dev for app-internal jobs, n8n for cross-tool automation that marketing, ops, and support touch. For a head-to-head comparison, see Trigger.dev vs n8n.
For the platform layer underneath, see how to self-host Dokploy and the self-hosting backup guide — both apply directly to Trigger.dev operations.
Explore this tool
Find trigger-devalternatives on OSSAlt →