Trust

What Switchyard proves, and what it does not claim.

Every statement on this page is backed by the implementation, the test suite, or a recorded test run in the repository. Where a number appears, the hardware, software, topology, and duration it was measured under appear with it.

Guarantees

What Switchyard guarantees

Only guarantees supported by the implementation and its tests. Nothing here is aspirational.

PostgreSQL is the durable source of truth. PubSub carries notifications, not state.

Events are persisted before Switchyard returns acceptance.

Delivery is at least once; duplicates remain possible and are recorded as duplicate hints.

Important work does not live only in memory. Delivery and maintenance work runs on Oban durable jobs.

Private-network delivery uses the authenticated relay.

Receipts and evidence bundles are sanitized and versioned; raw bodies, header, cookie, and signature values, tokens, and secret material are structurally absent from exports.

Non-claims

What Switchyard does not claim

Stated plainly, because these are the claims that usually get webhook tooling in trouble.

Exactly-once delivery. Delivery is at least once; duplicates remain possible.

A Kafka replacement.

A general message broker.

An ETL platform.

A workflow automation platform.

A payment-grade delivery service.

A full API gateway.

An arbitrary code-execution environment.

System model

The durable system model

How the pieces fit together to make the guarantees above hold.

PostgreSQL source of truth
Events, deliveries, and operational history are rows in PostgreSQL. If it is not committed, Switchyard does not claim it happened.
Persist before accept
The ingest path commits the event before the sender receives an acceptance response.
Oban durable work
Delivery and maintenance jobs live in the database-backed Oban queues, so a restart does not strand work that exists only in process memory.
At-least-once semantics
A delivery can be attempted more than once. Duplicates remain possible and are surfaced as duplicate hints, never hidden.
Local relay boundary
The relay runs next to your services, authenticated, so the Switchyard server never dials your private network directly.
Remote destination restrictions
Outbound delivery is constrained to configured destinations; the delivery path does not fetch arbitrary addresses.
Audit history
Decisions, attempts, and operator actions are recorded so you can reconstruct what happened after the fact.
Redaction and evidence boundaries
Receipts and bundles are sanitized and versioned. Masked fields carry a masked marker with null values; secret material is structurally absent.

Tested limits

The v0.9 two-hour soak, with its full context

In a 2-hour loopback soak on an Apple M1 Pro (16 GiB), Switchyard accepted 142,120 of 142,120 offered events and sustained 19.74 events/s. Those numbers mean nothing without the scenario they were measured in, so here is the scenario.

Scenario and configuration

Hardware
Apple M1 Pro, 10 schedulers, 16 GiB RAM
Software
Elixir 1.19.5 / OTP 28 / PostgreSQL 17 (Docker) / released CLI 0.8.0 / released relay
Topology
Single loopback HTTP server, disposable database, default Oban queues (deliveries: 10, maintenance: 1), PostgreSQL pool 10
Concurrency
25
Duration
7,200 seconds (2 hours)
Seed
90045, run 2026-07-23

Results

Offered / accepted
142,120 / 142,120
Completed
142,110 (10 non-success terminal deliveries in one batch)
Sustained throughput
19.74 events/s
Capture latency p50 / p95 / p99 / max
130.3 / 254.5 / 348.0 / 2,445.8 ms
Delivery latency p50 / p95 / p99 / max
64 / 170 / 224 / 2,340 ms
Errors / timeouts / duplicates
2 / 1 / 0
Hard invariants
0 before the run, 0 after
Retention under load
120 cleanup runs deleted 137,019 events at 19.03 events/s, matching ingest
First bottleneck
The same-host load generator exceeded its 1-second batch budget 11 times across the 2 hours. Network and IO were not the bottleneck.

Classification

The strict harness rule classifies this run as Invalid: it requires zero errors and accepted equal to completed, and this run ended 10 rows apart. A human reviewed the failure pattern and accepted the numbers on 2026-07-23, because the system remained healthy throughout: hard invariants at 0 before and after, 0 duplicates, and a 0.0070% non-success rate across 142,120 events. The strict rule, not the system, was the problem. Both error batches are recorded in full in the receipt.

The soak ran against a loopback HTTP server. It excludes Internet and TLS behavior entirely. A tested limit is a conservative passed boundary under the recorded scenario — not a universal capacity claim, and never a product maximum.

The complete record, including raw receipts and per-table database growth, lives in the repository: docs/v0.9/TESTED_LIMITS.md.

Separately, a short-mode smoke run (seed 90045, 2026-07-23) passed all six harness scenarios as Valid with 0 hard invariant violations. That is harness smoke — a verification practice, not a performance result, and not publishable as one.

Release verification

The gates every release passes

These are the commands that run before a release ships. Each one is in the repository and safe to run yourself.

verification gates
mix setup            # deps, database, migrations, assets
mix test             # the full test suite
mix quality          # format check, warnings-as-errors, Credo --strict
mix security         # deps.audit, hex.audit, Sobelow
mix check            # fast gate: format, compile, Credo, security, tests
mix check.all        # everything in check, plus Dialyzer
bin/verify-v0.9      # the v0.9 operator exit gate
bin/verify-quickstart # the five-minute walkthrough, end to end
mix setup
Proves a fresh checkout can be brought to a working development state.
mix test
Proves the test suite passes against the real persistence layer.
mix quality
Proves the code is formatted, compiles with warnings as errors, and passes Credo in strict mode.
mix security
Proves dependencies and Hex packages audit clean and Sobelow finds no flagged issues.
mix check
Proves the fast gate passes: format, compile, Credo, security, and tests in one run.
mix check.all
Adds Dialyzer static analysis on top of the fast gate.
bin/verify-v0.9
Proves the v0.9 operator exit gate passes against the released artifacts.
bin/verify-quickstart
Proves the documented five-minute walkthrough actually works, end to end.

These gates verify code and operator behavior. They do not prove marketing-page visual quality, and this site does not pretend they do.

See the loop, then read the code.

Walk the diagnostic loop on sample data, or go straight to the repository and run the verification gates yourself.