For most of the last decade, production profiling meant a tradeoff: sample a request here and there, ship a flame graph when something looked slow, and accept that the exact moment a service actually stalled almost never made it into the sample. eBPF-based whole-system profilers changed that math. Parca and Grafana Pyroscope both now run as a DaemonSet on every node, sampling every process's stack continuously, at a CPU cost commonly benchmarked under 1%. Always-on production profiling stopped being a compromise and became a background primitive any fleet can leave running.
But "under 1% CPU" answers only the compute half of the question. Profiles have to land somewhere, get compacted, and stay queryable for weeks — and that's a new stateful service, not a free lunch. Here's the actual number: profiling a representative 20-node, 8-core-per-node fleet (160 cores) at the storage rate Parca's own docs quote — roughly 10GB per core per month — works out to about 1.6TB/month of profile data. Stored on Hetzner Object Storage (€4.99/month for the first 1TB, €0.0067/TB-hour beyond it), that's under €8/month for the whole fleet's continuous profiling history. Route the same 160 hosts through Datadog's Continuous Profiler at $19/host standalone and it's $3,040/month — or $80/month bundled into APM, but only if you're already paying for APM Enterprise underneath it. Send the same volume to Grafana Cloud Profiles at roughly $0.30–$0.45/GB ingested and it lands between $480 and $720/month. Self-hosting the same data is one to two orders of magnitude cheaper — and that gap is the entire argument for running your own profiling stack on a Cluster API-managed fleet instead of buying it by the gigabyte.
How "Under 1%" Actually Gets There
The mechanism matters, because it's the reason the overhead number is credible rather than marketing. Parca's agent samples every logical CPU core 19 times per second — a prime number chosen specifically so its sampling interval doesn't collide with other periodic work already happening on the machine. That's it. No per-request instrumentation, no code changes, no SDK a tenant has to import into their app. The eBPF program runs in kernel space, walks the stack on each timer tick, and hands a small structured sample up to userspace for aggregation. Grafana's Alloy-based eBPF profiler works the same way: stack-trace sampling at the kernel level, unwinding via .eh_frame data rather than requiring frame pointers, which is what lets it profile languages that were never compiled with profiling in mind.
Compare that to the previous generation of "continuous" profilers, which typically meant either sampling a fraction of requests at the application layer (missing whatever didn't get sampled) or running a full symbolic profiler that could add double-digit percentage overhead if left on permanently — which is exactly why most teams only turned it on after something already broke. eBPF sampling a fixed number of times per second per core, regardless of load, is what makes "leave it running in production, always" a defensible default instead of an incident-response tool.
Parca and Pyroscope Aren't the Same Architecture Wearing Different Names
Both tools solve the collection problem the same way. They diverge hard on what happens after a sample leaves the kernel — and that divergence is what a platform is actually choosing between.
Parca stores everything in FrostDB, a columnar embeddable database Polar Signals built specifically for this workload, backed by Parquet files at rest and Arrow at query time. The whole system ships as a single Go server binary plus the DaemonSet agent — no separate ingesters, compactors, or query frontends to run. It's the simplest possible footprint: one binary, one agent, one object-storage bucket. The tradeoff shows up in language coverage. Parca's eBPF path today resolves stack symbols cleanly for compiled languages — Go, Rust, C, C++ — because their binaries carry the debug information eBPF needs to walk the stack directly. Interpreted and JIT-compiled runtimes (Python, Ruby, the JVM, Node.js) need a different symbolization strategy Parca's own docs list as forward-looking work, not a shipped feature.
Grafana Pyroscope took the opposite bet. As of Pyroscope 2.0 (shipped April 21, 2026), the OSS default architecture writes profiles directly to S3-compatible object storage with no in-memory ingester tier at all — the same shift Grafana made with Mimir for metrics and Loki for logs, trading a bit of write-path complexity for a system that scales by adding object storage rather than by adding stateful nodes. Multi-tenancy is a first-class concept, not a bolt-on: profiles carry a tenant ID header from ingestion through query, which matters directly for a platform serving many tenants off one profiling backend rather than standing up one Pyroscope per customer. And via Grafana Alloy's eBPF profiler, language coverage is broader today — Java (Hotspot JVM), .NET, Python, Ruby, PHP, and Node.js are all supported symbolization targets alongside the natively-compiled languages, at the cost of running more moving components: distributor, ingester-free write path, store-gateway, compactor, query-frontend — a Mimir-shaped stack, not a single binary.
Neither is "the better tool" in the abstract. They're optimized for different tenant populations:
| Parca | Pyroscope 2.0 | |
|---|---|---|
| Storage backend | FrostDB (Parquet/Arrow), self-built | Object storage, Mimir-style microservices |
| Deployment shape | Single binary + agent DaemonSet | Distributor / write-path / store-gateway / compactor / query-frontend |
| eBPF language coverage | Strong: Go, Rust, C/C++ | Broad: adds Java, .NET, Python, Ruby, PHP, Node.js |
| Multi-tenancy | Not first-class by default | Built-in tenant ID header |
| Governance | Fully open-source, Polar Signals-led, no gated cloud tier | OSS core; Grafana Cloud is the commercial upsell path |
What "First-Class Cluster-API-Provisioned Service" Actually Costs
Running either as a platform-level primitive — not a per-tenant opt-in sidecar, but a service the fleet stands up once and every tenant's workloads get profiled by default — adds two categories of real cost, and pretending otherwise would undercut the honest case for self-hosting it.
Object storage becomes load-bearing. Both tools' modern architectures assume an S3-compatible bucket sits underneath them — Parca for FrostDB's Parquet files, Pyroscope 2.0 for its entire write path. A Cluster API fleet that's already running object storage for OCI registry layers or build-artifact caching isn't adding a wholly new capability, but it is adding real, continuously-growing volume to that bucket: the ~1.6TB/month figure above for a 160-core fleet isn't a one-time cost, it's an ongoing line the platform has to account for in its own storage-capacity planning, with retention policy (30, 60, 90 days) directly controlling how large it grows.
The DaemonSet needs privileged kernel access, and that's a real multi-tenant boundary to draw carefully. eBPF stack-walking requires a BTF-capable kernel (5.3+) and elevated capabilities to attach probes — this isn't a workload running in the same sandbox as tenant containers, it's a node-level agent with visibility into every process on the box, tenant workloads included. That's a deliberate, audited exception to an otherwise strict container-isolation model, not a component you deploy the same way you deploy a tenant's app. Getting that boundary right — scoping exactly what the profiling DaemonSet can read and where profile data flows — is the actual engineering cost of "free" continuous profiling, and it's a one-time cost to get right rather than a recurring bill.
Pyroscope's multi-component write path also means more independently-scaled services to run and monitor than Parca's single binary — a genuine operational-surface tradeoff for the broader language coverage and native multi-tenancy it buys.
The Honest Pick
Neither tool is free in the sense of "zero additional infrastructure." Both are cheap in the sense that matters: a few dollars a month in object storage plus a DaemonSet's worth of CPU and memory, against hundreds to thousands of dollars a month for the SaaS equivalent at the same fleet size.
Choose Pyroscope if the fleet's tenants are the polyglot mix a typical git-push PaaS actually serves — Node.js, Python, Ruby, PHP, and JVM apps alongside Go services — because that's exactly the language coverage its eBPF path was built to reach, and doubly so if the platform already runs Grafana, Mimir, Loki, or Tempo and wants one consistent operational model across metrics, logs, traces, and profiles.
Choose Parca if the fleet skews toward compiled-language workloads, the priority is the smallest possible operational footprint — one binary instead of a microservices write path — and a fully open-source project with no adjacent commercial cloud tier to eventually feel pressure from is worth more than broader out-of-the-box language coverage.
Either way, the number that matters is the one from the top: single-digit euros a month in object storage against triple- or quadruple-digit dollars for the SaaS alternative, on hardware the platform already owns. Continuous profiling stopped being expensive to run the moment it stopped needing a per-request instrumentation tax — it just needed somewhere honest to live.
Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own, with the observability data staying on that same hardware instead of a third party's ingestion pipeline. Star the repo on GitHub or deploy your first app today.



