Every Formbricks web process starts one worker with a concurrency of one by default. You can tune these
values with environment variables after you have measured your workload.
Runtime architecture
The web application creates jobs and consumes them from a shared Redis-backed queue:- Queue name:
background-jobs - Redis key prefix:
{formbricks:jobs} - Worker startup: Next.js server instrumentation
- Default workers per web process:
1 - Default concurrent jobs per worker:
1
Current background jobs
Current workloads on the shared queue include:
These are current examples rather than a fixed list. Future Formbricks features can use the same Job Runner for
additional background work.
Configure the Job Runner
1
Connect Redis
Set All replicas must use the same Redis instance so they share the BullMQ queue and recurring schedules.
REDIS_URL to a Redis instance reachable by every Formbricks web replica.2
Keep the in-process worker enabled
BULLMQ_WORKER_ENABLED is enabled by default outside test environments. You can omit it or set it
explicitly:3
Verify startup
Check the web process logs for the exact message
BullMQ runtime started. Its structured fields include
the queue name, Redis prefix, worker count, and worker concurrency.Scale across replicas
Each web replica starts its own in-process workers and connects to the same queue. BullMQ coordinates job claims so one available worker ordinarily processes a queued job. Total processing capacity is approximately:Retry behavior
BullMQ applies the following defaults to background jobs:
Individual workloads can add their own recovery behavior on top of these queue-level retries.
Workflows
Workflows use the shared Job Runner to execute runs and reconcile runs that lost their queue or worker handoff. No additional worker process is required.Configure action dependencies
Configure the services required by the workflow actions you use. For example, the Send email action uses your deployment’s SMTP transport and sender. ConfigureSMTP_HOST, SMTP_PORT, MAIL_FROM, MAIL_FROM_NAME,
and any authentication or TLS variables required by your provider.
See SMTP Configuration for the complete setup.
Retry and recovery behavior
A recurring reconciliation job runs every three minutes to recover workflow runs that lost their queue or worker handoff:- Queued runs older than two minutes are eligible for redispatch.
- Queued runs older than 24 hours are marked as failed instead of being redispatched indefinitely.
- Running runs with no executor activity for one hour are marked as failed and unfinished steps are skipped.
- Each reconciliation sweep processes at most 250 queued and 250 running candidates. Larger backlogs drain over subsequent sweeps.
Workflow run reconciliation acted with structured
counts for redispatched, aged-out, and recovered runs.
Troubleshoot workflow jobs
If workflow runs stay queued after the Job Runner is healthy:- Search for
BullMQ job failedentries wherejobNameisworkflow-run.processorworkflow-run.reconcile. - Search for
Workflow run reconciliation actedand inspect the queued and stuck-running counts. - Open the workflow’s Runs view to inspect the run status and step-level error.
Use a custom external worker
The default in-process worker is the supported setup. Formbricks does not ship a standalone worker command or container. The external-worker flags are only for custom deployments that provide their own consumer and register the complete Formbricks application job handlers. In such a custom deployment, configure the web/API processes to keep enqueueing without starting local workers:Troubleshoot the Job Runner
Formbricks writes structured logs to stdout and stderr. Search themsg field for these exact messages:
If background jobs stay queued:
- Confirm
REDIS_URLis present and identical on all web replicas. - Confirm at least one in-process worker is enabled, or that a compatible external worker is running.
- Look for
BullMQ runtime startedafter the latest deployment or restart. - Check Redis connection and
BullMQ job failedlogs. - Use the
jobNamefield to identify the affected workload and continue in its feature-specific logs or UI.