See what broke without operating an observability stack.
Send traces, logs and metrics to one process over OpenTelemetry. Investigate incidents in the browser or through an agent, and run alerts — without operating the stack behind them.
One Go process: OTLP in over gRPC or HTTP, authoritative Parquet on disk, indexed trace reads, and embedded DuckDB analytics. No database to operate.
why is checkout slow right now?
missing index on orders(user_id) — 88% of slow spans block on db-orders
-
Self-hosted on your hardware
-
OTLP native traces, logs and metrics
-
Open local storage authoritative Parquet, embedded queries
-
One small VM reference deployment target
-
Apache-2.0 open source
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 |
5 of 47 services · worst first
Health
Throughput
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
- Authoritative Parquet on local disk
- Indexed traces and DuckDB analytics
- 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.
Inside the binary
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.
Measured on one machine
Nearly 300,000 OpenTelemetry items a second. One binary.
Section titled “Nearly 300,000 OpenTelemetry items a second. One binary.”In a five-minute publication-candidate run, Fanout accepted 296,196 spans, log records and metric data points per second on a machine with eight logical CPUs and 15.6 GiB of memory. Fanout reported zero dropped rows, the process did not restart, and the resulting Parquet store passed verification. The load generators shared the machine, so this is an observed whole-host result—not an isolated storage-engine ceiling.
Sustained three-signal ingest
296,196 items/s
Fanout's accepted-row counter over five minutes—not the load generator's requested rate.
ONE BINARYPARQUET
VERIFIED
Each signal was also saturated on its own. These three runs are separate measurements, not a breakdown of the sustained three-signal rate above.
v2026.8.11 · 8 logical CPUs · 15.6 GiB · same-host generators · OTLP/gRPC
It is labeled a candidate because it is a single run: the published headline waits on a clean harness repeating it three times. Read the methodology and every qualification, or run the same open-source harness on your own host.
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 universal capacity number: the benchmark above describes one release, host and workload. Your payload cardinality, query mix and disk decide the capacity of your instance. Measure your own hardware.
- 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