Observability that runs anywhere you can run a binary
Point your traces, logs and metrics at one process over OpenTelemetry. Get a fast browser client, a chat investigator that works through the evidence, and alerts — without standing up a stack to hold them.
One Go process: OTLP in over gRPC or HTTP, Parquet on disk, DuckDB for queries. No collector to deploy alongside it and no database to operate.
why is checkout slow right now?
missing index on orders(user_id) — 88% of slow spans block on db-orders
What you look at
Every service, one screen, no query language.
Section titled “Every service, one screen, no query language.”Health, latency, error rate and throughput for everything reporting — with the slow one already at the top. The chat investigator works from the same typed queries this view does, so what it tells you and what you are looking at cannot disagree.
Services
| Service | Health | p95 | Errors | Rps |
|---|---|---|---|---|
| checkout | unhealthy | 412 ms+38% | 2.4% | 1.2k |
| cart | degraded | 187 ms | 0.6% | 2.1k |
| catalog | healthy | 42 ms | 0.0% | 3.8k |
| payment | healthy | 94 ms | 0.1% | 980 |
| auth | healthy | 28 ms | 0.0% | 5.4k |
Health
Throughput
The shape of it
Three signals in, one process, answers back out.
Section titled “Three signals in, one process, answers back out.”Fanout is where your telemetry lands, not something you put in front of the thing it lands in. Traces, logs and metrics arrive over standard OTLP from SDKs or a Collector you already run, and everything after that happens inside one binary.
Nothing in the middle crosses a network, and nothing else has to be running for it to answer. The data directory it writes is the whole of its state.
What it replaces
Five services, or one process.
Section titled “Five services, or one process.”This is the whole argument. Every other claim on this page follows from it — the short backup procedure, the single configuration, and the absence of an integration layer to debug at three in the morning.
The usual arrangement
- CollectorReceive OTLP, batch, forward
- Storage backendPersist telemetry, expire it
- Query layerAnswer questions over that store
- Dashboard serviceRender it for people
- AlertmanagerEvaluate rules, deliver notifications
Five deployments, five configurations, five upgrade cadences — and the failure modes that exist only between them.
Fanout
- OTLP in over gRPC and HTTP
- Parquet on local disk
- DuckDB, in the same process
- The browser client, served by the binary
- The alert engine, on a fixed interval
One binary to pin, one directory to back up, one process to restart.
Limits
What Fanout will not do.
Section titled “What Fanout will not do.”These decide whether Fanout fits, so they are here rather than three pages in. None of them is a roadmap item phrased as a virtue.
- Not multi-tenant: namespaces scope queries, not access. Anyone who can query the instance can query every namespace in it; an instance is one trust domain.
- No horizontal scale: ingest, query and maintenance share a process and a machine. There is no scaling one without the others, because they are the same thing.
- No published throughput figure: the previous benchmark was withdrawn because its raw reports and driver commit were not retained. Measure your own hardware instead.
- No migration paths: Fanout is pre-release. A renamed setting is renamed, not aliased, which is why an unknown variable stops the process rather than being ignored.
Install it and point something at it.
One binary, one data directory. The installer checks the archive against the release checksums before it extracts anything.
curl -fsSL https://raw.githubusercontent.com/labstack/fanout/main/scripts/install.sh | sh