Why BackWave
BackWave is a background-job system for .NET in the same species as Hangfire: you enqueue opaque work and it runs once-or-more with retries. What sets it apart is that the job logic is deterministically testable, enqueueing can be transactional, and it runs on infrastructure you already have.
The case for BackWave
The point-by-point comparisons against other products live on their own pages. First, what you actually get when you adopt BackWave, and how it earns the reliability claims it makes.
Test your jobs deterministically
Enqueue a job, advance a virtual clock your test owns, and assert the outcome. Retries, backoff, cron schedules, and dependency releases all run under that clock, so a year of daily cron ticks completes in one call in well under a second, with no sleeps and no real database. The harness pairs the shipping scheduler core with a real in-memory implementation of the same storage contract Postgres passes, not a mock.
Built like infrastructure software
BackWave’s own test suite drives a whole simulated cluster through crashes, clock skew, node isolation, and racing operator actions, and every run replays exactly from a single seed. One conformance suite runs against every supported store on real database instances. Invariant checks stay on in production and fail-stop rather than quietly mis-process work.
Enqueue inside your transaction
Enqueue a job inside your own database transaction: commit and it is durably queued, roll back and it never existed. That closes the dual-write race without an outbox pattern to build or a relay process to babysit, and the same guarantee extends to enqueueing whole workflow graphs.
Guarantees stated honestly
The handler may run more than once, and the docs say so plainly. The recorded outcome and everything downstream of it (terminal state, dependency release, concurrency slot) apply exactly once. Running jobs are held under heartbeat-renewed leases, so a crashed or frozen node simply stops renewing and its peers reclaim the work automatically.
No new infrastructure
The queue is tables in the Postgres, SQL Server, or SQLite you already run, next to your data. There is no broker or Redis to stand up, and no coordinator or leader election either; every node is an interchangeable stateless peer. On Postgres, LISTEN/NOTIFY wakes an idle worker the moment an enqueue commits, giving sub-second pickup with polling underneath as the correctness backstop.
Easy to adopt, hard to outgrow
Put an attribute on a method and the source generator emits the typed payload, reflection-free serialization, and registration. Job identity is a stable Wire Name, so renames never strand in-flight work, and because serialization and dispatch are generated rather than reflected, the whole enqueue-execute-store-observe loop on Postgres publishes warning-clean under Native AOT and trimming. Each attempt gets a fresh DI scope, so a scoped DbContext injects exactly as in a controller. If you’re coming from Hangfire, a documented playbook runs both in one process while you port one job at a time.
Operations you can defend
Every dashboard write action (requeue, cancel, pause, trigger) is an individual default-deny callback into your app’s own authorization, and each one lands in an append-only audit trail with the acting identity. Everything an operator can click is also a public API with defined semantics. Health checks tell a transient store blip apart from a genuine halt.
Orchestration for real pipelines
Continuations and dependencies are core and free: a dependent waits until its parent reaches a terminal state, a failed parent cancels the downstream branch, and a job can persist typed output that dependents read race-free. Pro adds a validated fan-out/fan-in DAG builder with atomic graph enqueue and group lifecycle controls.
Efficiency and throughput
BackWave does the same work as Hangfire while holding a fraction of the database connections and CPU, and then scales past it on demand without giving that efficiency back. The efficiency is the headline, and it holds as you scale up, so you go faster and still spend less.
See how we benchmark →At a matched work rate, held whether busy or idle. Connections are the genuinely scarce resource on managed Postgres (RDS, Cloud SQL, Supabase all cap them).
Same throughput, more idle headroom. That headroom is the thing you spend to scale, rather than a resource you have already given away.
Running more pumps in one process multiplies throughput near-linearly, so a node grows on demand without a redeploy or a new tier of infrastructure.
Indicative figures from local runs, not official benchmarks. They describe durable ratios and shapes; absolute jobs/sec numbers are pending an official run.
Throughput holds as jobs get heavier
On trivial empty jobs Hangfire is a touch faster. As handlers do realistic work in the 10 to 50 ms range, BackWave’s throughput stays flat while Hangfire’s falls off, and the lead crosses over in BackWave’s favor. Most real jobs do real work, so that crossover is the regime you actually live in.
Where Hangfire still wins, plainly
At default config on very short sub-10 ms jobs Hangfire is modestly faster, and its always-polling workers pick light, steady load up a few milliseconds sooner. BackWave trades those milliseconds for a quarter of the connections and half the CPU. The efficiency gap narrows in this light-job default regime but never reverses; at a matched work rate it widens to the ~10× and ~3× above, plus faster job submission.
How it compares
One long-form report per product, written against that project’s own source and documentation. BackWave publishes them, so they are not neutral. They are checkable: every claim is sourced, and each report has a section on where the other product wins.
vs Hangfire
The incumbent. Crash recovery and the outcome fence, queues and cluster-wide caps, job identity across refactors, and a measured throughput run.
Read the report →vs TickerQ
The other modern, source-generated, AOT-ready option. Where its EF Core provider reclaims a dead node’s work, and where it does not.
Read the report →Ready to look closer?
The documentation covers the core concepts, storage, testing, and the dashboard in depth.
Read the docs