Decide separately who operates the datastore, who runs processors, and who owns workflow semantics. Managed and self-hosted are not a single binary choice.
- 01Execution semantics
Retries, scheduling, durable waits, signals, concurrency, and idempotency.
- 02Infrastructure ownership
Who runs the broker, scheduler, worker compute, upgrades, and recovery?
- 03Total operating cost
Usage charges + compute + storage + networking + support + engineering time.
Separate the datastore, processor, and workflow layers
For a Redis-backed BullMQ deployment, the datastore holds queue state and the application workers perform the work. Redis may be managed by a provider even when the worker fleet belongs to your team. Durabull adds an operations interface; it does not become the processor or remove the need to operate Redis and workers.
Inngest orchestrates durable functions and steps whose code typically runs in your own application, on serverless endpoints or workers. Trigger.dev Cloud runs task code on managed workers. Temporal separates its service from workers that execute workflow and activity code. These distinctions determine where deployment, scaling, and network troubleshooting happen.
Write down the owner of each layer in your proposed architecture. If two teams each believe the other owns worker availability or recovery testing, a platform purchase will not close that gap.
Choose semantics before deployment mode
Describe the actual work: a short independent job, a fan-out graph, a workflow waiting for a webhook, or a process lasting days. Then define ordering requirements, duplicate tolerance, failure recovery, and the state a human must inspect. The same word, “job,” can conceal very different requirements.
Queue retries are useful for transient failures, but they do not by themselves specify business-level idempotency or how to resume a partially completed operation. Durable workflow systems offer explicit models for persisted progress. Evaluate those models against your application instead of assuming all products provide interchangeable execution units.
BullMQ also documents an optional PostgreSQL backend. That is a datastore decision with its own compatibility checks; it does not mean every Redis-oriented dashboard or operations tool automatically supports the new backend.
Test the failure responsibility you are accepting
Build a staging exercise around four failures: terminate a worker during a side effect, interrupt datastore connectivity, make a downstream API return errors, and deploy a new processor while work remains queued. Record what resumes automatically, what may repeat, what becomes visible, and what a human must repair.
For self-operated components, assign ownership for upgrades, backups, restore tests, capacity, and credentials. For managed components, verify documented limits, support paths, region requirements, and the application’s behavior while the service is unavailable. Both designs have dependencies; owning a Redis instance is not an availability guarantee.
Pay attention to recovery time rather than only steady-state throughput. A queue that processes quickly when healthy can still require hours of manual repair after a bad deployment. Include that operational exercise in acceptance criteria.
Compare costs using the same workload and outcome
Model fixed infrastructure, variable execution, telemetry, network transfer, and engineering effort separately. Include peak load and retention, not only average monthly job count. If one option includes managed compute and another requires your workers, leaving the worker bill out creates a misleading comparison.
Keep unit labels on every number: function runs, durable steps, execution seconds, requests, and completed business operations are different quantities. A retry storm can change cost and load differently across systems. Test that scenario explicitly before relying on a normal-month estimate.
Value managed capabilities when you need them. A higher service invoice can still be a reasonable decision if it avoids an operational system your team cannot support. Conversely, replacing a reliable fleet solely to obtain a dashboard may introduce migration effort without addressing a runtime requirement.
Make portability a concrete migration exercise
Portability is more than whether source code is available. Inventory the job payload contract, identifiers, retry policy, schedules, workflow state, secrets, and operational history. Determine which pieces can move unchanged and which require translation or replay.
Keep business operations behind application functions with explicit inputs and idempotency behavior. This can reduce migration effort without pretending orchestration APIs are portable. For existing jobs, plan how old and new workers coexist, how in-flight work drains, and how a rollback avoids duplicate side effects.
A useful decision record ends with an owner for each component, a measured pilot, known limits, a monthly estimate, and the condition that would cause you to revisit the decision. That is a better basis for choosing than a universal rule that managed is expensive or self-hosted is risky.
Common questions
Does using BullMQ mean I must operate Redis myself?
No. Redis-backed BullMQ can use a compatible managed Redis service while your team runs the workers. Datastore hosting, worker hosting, and dashboard hosting are separate decisions.
Should I migrate away from BullMQ just to get a dashboard?
Usually start by evaluating compatible dashboards. Consider a runtime migration when you also need different execution semantics, deployment responsibility, or workflow capabilities.
Which architecture is cheapest at 100 million jobs?
There is no useful answer until “job” is defined. Duration, step count, retries, retained data, peak concurrency, and operational responsibility determine the comparison.
Sources & review
Written by Durabull. Reviewed against the references below and Durabull’s implementation. Pricing examples are documented models, not measured benchmarks or vendor quotes.
- BullMQ: going to production
- Durabull: Cloud and self-hosted deployments
- BullMQ: retries and backoff
- BullMQ: idempotent jobs
- BullMQ: stalled jobs
- BullMQ: optional PostgreSQL backend
- Inngest: durable workflow execution
- Inngest: pricing and execution definition
- Trigger.dev: Cloud pricing
- Temporal: platform architecture
Suggest a correction if a feature, price, or documented behavior has changed.
Compare the options
- Durabull vsInngestReplaces BullMQ. Cloud bills executions (run + each step). Official MCP inspects Inngest runs, not Redis queues.
- Durabull vsTrigger.devReplaces BullMQ. Trigger.dev Cloud runs your task code and bills compute-seconds plus $0.000025 per run.
- Durabull vsTemporal CloudReplaces BullMQ with Workflows and Activities. Actions cost $50 per million on the Developer plan.
- Durabull vsUpstash QStashServerless HTTP push queue. Pay-as-you-go $1 per 100K messages. Not Redis, not BullMQ.
- Durabull vsAmazon SQS + Step FunctionsManaged AWS queue plus optional orchestrator. Low per-request prices, but every API call bills, including empty receives. Not BullMQ.