Packages & Compatibility
The BackWave NuGet package map, the net8.0/net9.0/net10.0 target framework, and the canonical per-adapter capability matrix for transactional enqueue and wake-up hints.
BackWave ships as a small set of focused NuGet packages: a core package, a hosting shell, one package per storage adapter, a read-only dashboard, the Pro add-ons, and testing helpers. Every shipped package multi-targets the same three .NET versions and moves in lockstep on a single version number, so there is never a version skew between the core and the adapter you install next to it. This page is the reference for what each package contains, the frameworks they target, the third-party versions they pin, and the capability matrix that separates the storage adapters from one another.
Target framework#
Every shipped BackWave package targets net8.0, net9.0, and net10.0. net10 is the current
release; net8 is the long-term-support line and net9 broadens reach to applications that have
not yet moved to net10. The runtime primitives BackWave depends on, TimeProvider and
Enumerable.Order(), are native on all three, so the multi-targeting carries no behavioral
difference across framework versions.
There is one exception, and it is not a package you install directly. The source generator that
powers the [Job] attribute targets netstandard2.0, because that is what the Roslyn analyzer
host requires. It is not published as its own package; it is bundled inside the BackWave
package as an analyzer, so a plain dotnet add package BackWave brings the generator with it.
There is no separate generator package to reference, and no version to keep in sync.
The packages are built with nullable reference types enabled and the latest language version.
They ship as deterministic, reproducible builds and carry XML documentation alongside the
assembly. Each one records the public repository and the exact commit it was built from through
Source Link, and ships its symbols as a separate .snupkg. With symbol lookup enabled, a
debugger steps from your code into the matching BackWave source rather than stopping at the
assembly boundary.
Versioning#
All packages carry one version, stamped in lockstep across the entire set. The source generator
packs inside the BackWave package and the code it generates binds to BackWave runtime APIs, so
the generator and the runtime must never drift apart in version. The version is derived from the
git tag at build time: a tag such as v1.0.0 produces a 1.0.0 package, commits past a tag
produce a height-stamped prerelease, and an untagged tree packs as 0.0.0-alpha.0. Because every package is cut from the same commit, the adapter, hosting, and
dashboard packages you install always match the core version exactly.
The package map#
Install the core package plus the one storage adapter for your database, and add hosting,
dashboard, EF Core, testing, or Pro as your application needs them. Each package below depends
on BackWave unless noted otherwise.
| Package | What it provides | Notes |
|---|---|---|
BackWave | The core: job system, the Storage Contract, and the In-Memory Store, with the source generator bundled in as an analyzer. | AOT-compatible. No third-party runtime dependencies. |
BackWave.Hosting | DI registration, Worker Group hosted services, and fail-stop health reporting. | AOT-compatible. |
BackWave.Postgres | The PostgreSQL storage adapter: versioned SQL schema, FOR UPDATE SKIP LOCKED claims, and Transactional Enqueue. | AOT-compatible. |
BackWave.Sqlite | The SQLite storage adapter, the first Embedded Adapter: single host, WAL with whole-writer serialization, co-resident Transactional Enqueue. | Not AOT-compatible. |
BackWave.SqlServer | The SQL Server storage adapter: versioned SQL schema, UPDLOCK/READPAST claims, and Transactional Enqueue. | Not AOT-compatible. |
BackWave.EntityFrameworkCore | EF Core integration: Transactional Enqueue inside the ambient unit of work. | A client extension, not a storage adapter. |
BackWave.Dashboard | The read-only monitoring dashboard, rendered server-side with zero static assets to host. | Razor SDK; references the ASP.NET Core shared framework. |
BackWave.OpenTelemetry | One-call registration of the job-lifecycle traces and metrics onto an OpenTelemetry provider, with per-adapter opt-in for store spans. | AOT-compatible. Subscribes by source name, so it references neither BackWave nor any adapter. |
BackWave.Pro | Revenue-gated add-on features (Workflows). | Commercial license. Requires license acceptance. |
BackWave.Pro.Dashboard | Pro dashboard surfaces that plug into the free dashboard's extension points, including the Workflow UI. | Depends on BackWave.Dashboard and BackWave.Pro. Commercial license. |
BackWave.Pro.Mcp | A Model Context Protocol server over your jobs, mounted in your own ASP.NET Core host, with every tool behind a gate you control. | AOT-compatible. Depends on BackWave.Hosting and BackWave.Pro. Commercial license. |
BackWave.Testing | A deterministic test harness: the In-Memory Store plus Virtual Time behind one API. | See Testing. |
BackWave.Conformance | The Storage Contract Conformance Suite — subclass it with a store factory to certify an adapter. | A library of abstract suites; not itself a test project. |
The Pro packages are free to use under $1M in annual revenue; above that threshold a license is required. They carry a commercial license file and prompt for license acceptance on install. Everything else ships source-available under the PolyForm Shield License with no acceptance prompt.
Where the source lives#
Every package is built from the public
repository, which holds one directory per package under
src/, named for the package itself: src/BackWave, src/BackWave.Postgres,
src/BackWave.Pro, and so on. Pro is no exception; its source sits beside the free packages
under the commercial license. The source generator lives there too, as
src/BackWave.SourceGenerators, even though it ships inside the BackWave package rather than
as a package of its own.
AOT compatibility#
The core, the hosting shell, the Postgres adapter, the OpenTelemetry package, and the Pro MCP
server advertise AOT compatibility. The SQLite, SQL Server, and EF Core packages do not, so an
application that trims and compiles ahead of time must reach for Postgres as its store. The
dashboard packages and BackWave.Pro itself are not AOT-compatible either.
Third-party dependencies#
The dependency footprint is narrow: each adapter pulls in only its own database driver. The versions below are the pinned floors; several are held at a specific version to stay clear of a known advisory.
| Dependency | Version | In package | Notes |
|---|---|---|---|
Microsoft.Extensions.*.Abstractions | 8.0.0 / 9.0.0 / 10.0.0 | Hosting, Pro | Matched to the target framework. |
Microsoft.EntityFrameworkCore.Relational | 8.0.10 / 9.0.0 / 10.0.0 | EntityFrameworkCore | net8 floors at 8.0.10 for a security advisory. |
Npgsql | 9.0.3 | Postgres | |
Microsoft.Data.Sqlite | 9.0.9 | Sqlite | |
SQLitePCLRaw.bundle_e_sqlite3 | 3.0.3 | Sqlite | Direct pin, forward off the vulnerable 2.x line. |
Microsoft.Data.SqlClient | 6.1.1 | SqlServer | |
Microsoft.Bcl.Memory | 9.0.14 | Pro | net8 only; backports System.Buffers.Text.Base64Url. |
OpenTelemetry.Api | 1.16.0 | OpenTelemetry | The API only, never the SDK: you own the provider. |
ModelContextProtocol.AspNetCore | 1.4.1 | Pro.Mcp | The official MCP SDK's streamable-HTTP transport. |
xunit | 2.9.3 | Conformance | |
Microsoft.AspNetCore.App | shared framework | Dashboard, Pro.Dashboard, Pro.Mcp | Framework reference, not a package. |
The adapter capability matrix#
BackWave ships three production storage adapters: Postgres and SQL Server, the Networked Adapters, and SQLite, the first Embedded Adapter. They implement the same Storage Contract, so your job code is identical across them, but they differ on two optional capabilities that a store may or may not offer. This matrix is the authoritative statement of which adapter offers what.
| Adapter | Kind | Transactional Enqueue | Wake-Up Hints | Transient-fault classification |
|---|---|---|---|---|
| Postgres | Networked | Yes | Yes — LISTEN/NOTIFY, cross-host | Uses the driver's own transient flag |
| SQL Server | Networked | Yes | No — poll interval only | Uses the driver's own transient flag |
| SQLite | Embedded, single host | Yes (only the co-resident deployment can exploit it) | Yes — in-process, same-process only | Yes — busy and locked conditions |
The In-Memory Store also reports Transactional Enqueue as supported, but it runs on Virtual Time and persists nothing, which keeps it a testing and local-development store. EF Core is not a store at all; it is covered separately below.
Transactional Enqueue#
All three real adapters support Transactional Enqueue: an enqueue can enlist in a transaction you
own, so the job becomes visible only when your business transaction commits, and rolls away with
it if it aborts. A store declares this through a capability flag, SupportsTransactionalEnqueue,
which every real adapter returns as true.
The differentiator is SQLite. Because SQLite is a single-file, in-process engine, transactional
enqueue is only usable in the co-resident deployment, where BackWave's tables live in the
same database file as your business writes and a single transaction can span both. The
dedicated deployment, where BackWave keeps its own file, cannot enlist a cross-file
transaction and forgoes the capability; the flag is still true either way, but only
co-resident can put it to use. See SQLite for the two deployment shapes.
When you pass a transaction to a store that does not support the capability, the enqueue is
rejected loudly with a NotSupportedException rather than silently ignoring the transaction.
Wake-Up Hints#
A Wake-Up Hint is an optional, latency-only signal that lets a Worker learn about newly-due work before its next poll, cutting idle-to-running latency. Hints are never correctness-bearing: polling is the sole source of truth, and an adapter that offers no hint mechanism simply degrades to the configured poll interval with no loss of correctness.
This is the sharpest difference between the adapters. Postgres delivers hints over LISTEN/NOTIFY on a dedicated connection, so a hint fired on one host wakes a Worker on another; the notification is transactional and fires on commit. SQLite delivers hints through an in-process hub, so they reach only Workers in the same process and only fire on the store's own commits; the mechanism is on by default and can be turned off. SQL Server offers no wake-up hints at all; its latency is bounded by the poll interval, full stop. Do not assume parity here: if low claim latency across hosts matters, that is a reason to choose Postgres.
A store advertises this capability by implementing IWakeUpHintSource, which the host probes for
at runtime. Its subscription method hands each subscriber the name of the Queue that has new
work:
Task<IAsyncDisposable> SubscribeAsync(Action<string> onHint, CancellationToken cancellationToken = default);The Wake-Up Hints & Latency page covers the latency story and the degradation behavior in full.
Transient-fault classification#
A store may optionally classify its own exceptions as transient so the Worker degrades and
retries rather than treating a blip as fatal. This is only needed when a driver leaves a fault
unclassified. Networked drivers already flag their transient conditions, so the Postgres and SQL
Server adapters lean on the driver and add nothing. SQLite implements the optional interface,
IStoreFaultClassifier, to mark its busy and locked conditions as transient:
bool IsTransientFault(Exception exception);EF Core is a client extension, not an adapter#
BackWave.EntityFrameworkCore does not implement the Storage Contract and is not a store you
select. It is an extension over the client that pulls the ambient transaction off your
DbContext and forwards the enqueue to whichever storage adapter you have registered. It
therefore inherits that adapter's capabilities: the underlying store must support Transactional
Enqueue, or the enqueue throws NotSupportedException; and there must be an open transaction on
the DbContext, or it throws InvalidOperationException. The EF Core
Integration page covers the pattern.
Where to go next#
- Choosing an Adapter: the decision guide across the networked, embedded, and in-memory stores.
- PostgreSQL, SQLite, and SQL Server: registration and options for each adapter.
- Wake-Up Hints & Latency: the per-adapter latency story and graceful degradation.
- EF Core Integration: the storage angle on transactional enqueue
through a
DbContext. - Storage Contract Reference: the operation surface, invariants, and capability flags an adapter implements.
- Limits & Defaults: the storage bounds and other defaults in one place.
Found a problem on this page? Report an issue