# Overview

BackWave is a background-job system for .NET. You get typed jobs, cron
schedules, dependency workflows, and a write-capable dashboard, all running
in-process on a database you already run. It is deliberately small in surface
area, and built so the background work you never see in production is something
you can test like ordinary code.

## What you get

BackWave is a library you add to an existing .NET application. It gives you a
typed way to enqueue work, a storage-backed queue, and a runtime that processes
jobs reliably. The pieces a real job system needs are already in the box:

- **Jobs & handlers.** Attribute a method with `[Job]` and the source generator
  emits the payload, handler, and a stable wire name that survives refactors.
  Enqueue a typed payload and it runs once, with retries.
- **Scheduling.** Every job carries a due time: fire it now, hold it for later,
  or mint it on a cron with a recurring schedule.
- **Workflows.** Compose jobs into a named DAG. A step waits for its parents and
  can read their output, and the whole graph can be cancelled or restarted as a
  unit.
- **Transactional enqueue.** Enqueuing a job participates in your database
  transaction. Commit and the job is durably queued; roll back and it never
  existed. There's no outbox to hand-roll, and no dual-write race between your
  data and your queue.
- **Runs on your database.** BackWave stores its queue in the database you
  already run, whether that's Postgres, SQL Server, or SQLite. There's no broker
  to provision, secure, and monitor, which is one fewer moving part in
  production and in CI.
- **A write-capable dashboard.** Inspect queues and job timelines, then act:
  requeue, cancel, or pause a queue, with every action authorized by your own
  app.

Here's a minimal wiring. Register BackWave, point it at your store and jobs, and
enqueue work inside your existing transaction:

```csharp title="Program.cs" {31-33}
using BackWave;
using BackWave.Generated;
using BackWave.Postgres;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddBackWave(backwave =>
{
    backwave
        .UseStore(_ => new PostgresJobStore(new PostgresStoreOptions
        {
            ConnectionString = connectionString,
            AutoMigrate = true,
        }))
        .UseJobs(BackWaveJobs.Module);

    backwave.AddWorkerGroup(new WorkerGroupOptions
    {
        Name = "default",
        Policy = new DispatchPolicy.Strict(["default"]),
        RetryPolicy = new RetryPolicy { MaxAttempts = 5 },
    });
});

var app = builder.Build();

app.MapPost("/orders", async (OrderRequest req, BackWaveClient client, AppDbContext db) =>
{
    db.Orders.Add(new Order(req.Id));

    // Enqueued inside the same transaction as the write above:
    // commit and the job is durably queued; roll back and it never existed.
    await client.EnqueueAsync(new SendOrderNotification(req.Id), db, dueTime: DateTimeOffset.UtcNow);

    await db.SaveChangesAsync();
    return Results.Accepted();
});

app.Run();
```

## Why you can trust it

Those capabilities are table stakes; what makes BackWave safe to put in front of
a production queue is that its scheduling logic is a deterministic core. It does
no I/O and never reads the wall clock, so the same inputs always produce the
same decisions. Two things fall out of that:

- **You can test it like ordinary code.** Drive the scheduler from a test on a
  clock you control, advance it, and assert on exactly what ran. Years of
  schedule activity replay in milliseconds, without real timers or flaky waits.
- **It is simulation-tested for correctness.** The core runs continuously
  against seeded fault injection (crashes, clock skew, lost heartbeats, store
  faults), and any failure it finds replays exactly from a single seed.

## What BackWave is not

BackWave is not a durable-execution engine. It does ship first-class
Workflows: named groups of jobs wired together by dependency edges, with a
graph view and lifecycle controls, where a step can read the output of the jobs
it depends on. What it does not do is record and replay the steps inside a job
the way Temporal does: no signals or waits, no conditionals, and no graph that
reshapes itself based on results. If you need that, reach for a tool built for
it. BackWave's job is to run discrete background work reliably and make it easy
to test, without dragging in extra infrastructure.

## Where to go next

This Overview is the entry point to the Introduction. From here the docs move
into the core concepts: how jobs are defined and enqueued, how transactional
enqueue works against your storage, and how to drive the runtime
deterministically in tests.
