Self-hosted service
parca-dev/parca avatar
parca-dev/parca

Parca: continuous profiling with eBPF and pprof, from a single binary to a fleet

Continuous profiling for analysis of CPU and memory usage, down to the line number and throughout time. Saving infrastructure cost, improving performance, and increasing reliability.

4,988 stars264 forksTypeScriptApache-2.0

At a glance

What is it?
Parca collects CPU and memory profiles across an infrastructure without instrumenting applications, stores them in its own columnar store, and lets you compare profiles by label. It is a serious tool for platform teams, and a poor fit for anyone who only needs a one-off flame graph.
Who is it for?
Adopt Parca if you run Kubernetes or systemd fleets and want infrastructure-wide CPU and memory profiles without adding instrumentation to each service; the eBPF agent plus the pprof ingest path covers both worlds. Do not adopt it if you need a single-language profiler for one process and nothing else, or if you cannot give the storage backend disk and memory.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem Parca solves, and who actually has it

Most profiling happens at the wrong moment. A developer reproduces a slowdown locally, attaches a profiler, gets a flame graph, and fixes that one path. The expensive problems are the ones nobody reproduces: a service that is 20% over its CPU request in one region, a memory leak that only shows up after four days, a deploy that quietly doubled the cost of a hot loop. The README frames this directly, saying many organizations have 20-30% of resources wasted with easily optimized code paths, and that the agent aims to lower the entry bar by requiring zero instrumentation.

That framing tells you the intended user. Parca is for platform and infrastructure teams that already run Kubernetes or systemd-managed workloads and want profile data as a standing dataset rather than an incident-time artifact. The value is not a prettier flame graph. It is being able to ask what changed between version 1.4 and 1.5, or between two regions, using the same label dimensions you already use in Prometheus. A single developer profiling one Python process on a laptop is not the audience, and the project does not pretend otherwise.

How the profiler, the store and the query path fit together

Parca splits into an agent and a server, and the repository makes the split visible: cmd/ holds the binaries, pkg/ holds the components, proto/ holds the gRPC definitions, and ui/ holds the TypeScript front end. The README describes the agent as a single eBPF profiler that automatically discovers targets from Kubernetes or systemd, with support for C, C++, Rust, Go and more. That discovery model is the part that matters operationally: you deploy one thing per node, and targets appear without per-application configuration.

On the server side, the data model is pprof. The README states that the agent produces pprof-formatted profiles and that the server ingests any pprof-formatted profile, which is what makes the tool interoperable with existing language runtimes and tooling rather than a closed format. Storage is the other half. The go.mod lists github.com/polarsignals/frostdb, github.com/apache/arrow-go/v18, github.com/parquet-go/parquet-go and github.com/dgraph-io/badger/v4, which matches the README's claim of optimized storage that retains raw data and allows slicing through a label-based search. In practice that means profiles land in a columnar store, individual samples stay addressable, and queries aggregate across labels instead of replaying whole profiles. The flags confirm the same architecture from the other direction: --storage-active-memory defaults to 536870912, --storage-row-group-size defaults to 8192, and --storage-index-on-disk exists specifically to reduce the memory footprint of the store. Those are not tuning knobs bolted onto a simple file store; they are the shape of the thing.

Installing Parca and getting the first profile

The README points at parca.dev for installation guides and documentation, and the repository itself documents the development path. Building from source needs Go, Node and pnpm, which the README lists explicitly. The Makefile's build target depends on ui/build and go/bin, so the front end is compiled before the Go binaries.

bash
git clone https://github.com/parca-dev/parca.git
cd parca
make build

After that, the README says the binary is at bin/parca and can be started directly. The default HTTP address is :7070, so the UI comes up at http://localhost:7070/. The README notes that Parca scrapes its own pprof endpoints by default, which means you should see profiles appear over time without configuring anything. That is a useful property for a first run: it proves the ingest path works before you involve the agent.

bash
./bin/parca

The scrape configuration lives in parca.yaml in the repository root, and the config path itself is a flag. The defaults are worth reading before you change them, because several of them decide whether data survives a restart. The flags below are exactly the ones the README's help output lists.

txt
--config-path="parca.yaml"
--http-address=":7070"
--enable-persistence
--storage-path="data"

With --enable-persistence and --storage-path set, the metastore and profile storage are written to disk instead of being held only in memory. For a production deployment, the deploy/ directory and the container image built from the Dockerfile are the paths the repository provides; the Dockerfile copies the compiled parca binary onto Alpine and includes grpc_health_probe for health checking, which tells you the intended runtime shape is a container with a gRPC health endpoint.

Where Parca gets awkward

The eBPF agent is the headline feature and also the main constraint. It depends on kernel support and on the agent being able to see the targets it profiles, which in a container environment means thinking about how the agent is deployed relative to the workloads. The README does not document a fallback path for kernels where the eBPF profiler cannot attach, and it does not describe rollback behaviour for a failed agent deployment. If your fleet includes kernels you cannot control, that is a question to answer before, not after.

Storage is the second constraint, and it is a resource decision rather than a bug. The store holds raw data and supports label-based slicing, and the flags expose the cost: --storage-active-memory defaults to 512MB, snapshots are triggered by --storage-snapshot-trigger-size (default 134217728 bytes, described as one quarter of active memory, and only used when the WAL is enabled), and --storage-index-on-disk exists to trade speed for a smaller memory footprint. A team that wants months of high-cardinality profile data on a small VM will not get it. The README does not state retention defaults or a compaction schedule, so capacity planning has to come from your own measurements.

Finally, Parca is the wrong tool when the question is narrow. If you want to profile one Go service during development, the standard library and pprof tooling already do that with no server, no storage and no agent. Parca earns its place when the profiling data has to persist, be aggregated across many targets, and be sliced by deployment labels.

Parca compared with Pyroscope

The most common comparison is with Pyroscope, and the difference is mostly about where the profiling data is expected to live. Parca is built around pprof as the interchange format and around its own storage engine, with a Go server that owns ingestion, storage and query, and a UI in the same repository. The eBPF agent is part of the same project and is described in the README as automatically discovering targets from Kubernetes or systemd. The result is a self-contained profiling backend: you run Parca, you point the agent at it, you query it.

Pyroscope takes a different route in the wider observability stack, where profiling is one signal among traces, logs and metrics and the storage and query layer is shared with the rest of that stack. The practical consequence is that choosing between them is less about the profiler and more about whether you want a dedicated profiling service with its own storage lifecycle, or profiling folded into a system you already operate. Parca's storage flags, its pprof-only ingest contract and its separate agent make the boundary between components explicit. That is a benefit if you want to reason about profiling costs on their own, and a cost if you were hoping profiling would come for free with infrastructure you already run.

Maintenance, licensing and upgrade cost

The repository is not archived, and the last push was on 2026-09-21. Releases are not frequent: v0.28.0 is dated 2026-05-07, and v0.27.0 and v0.27.1 both landed on 2026-03-20. The project is still on a 0.x version line, which is the honest signal for upgrade planning. The README does not promise API stability across minor versions, and the configuration surface is wide enough that a flag rename or a default change will touch your deployment manifests. The Makefile shows the standard hygiene you would want from a project at this stage: a lint target that runs check-license, go/lint, proto/lint and ui/lint, and a test target split into go/test and ui/test.

Licensing is Apache-2.0, stated in the README badge and in the LICENSE file at the repository root. The Dockerfile labels the image with the source and license URLs. Apache-2.0 is permissive and includes an explicit patent grant, which matters for a project that ships an eBPF agent. It also means there is no copyleft obligation on your own code that merely talks to Parca over gRPC. What the licence does not settle is the provenance of every dependency; govulncheck is wired into the Makefile as go/deps-check, and that is the mechanism the project offers for tracking dependency risk. This is not legal advice, and the usual review of the dependency tree applies.

Editorial conclusion

Adopt Parca if you run Kubernetes or systemd fleets and want infrastructure-wide CPU and memory profiles without adding instrumentation to each service; the eBPF agent plus the pprof ingest path covers both worlds. Do not adopt it if you need a single-language profiler for one process and nothing else, or if you cannot give the storage backend disk and memory. Before committing, verify that your kernel and container runtime are supported by the agent, and check how --enable-persistence, --storage-path and the WAL flags behave under your expected retention volume.

Frequently asked questions

What is Parca and what does it do?

Parca is a continuous profiling system: an eBPF-based agent discovers targets from Kubernetes or systemd and produces pprof profiles, and a server stores them and lets you slice and compare profiles by label. The project describes the goal as saving infrastructure cost, improving performance and increasing reliability.

How does Parca compare with Pyroscope?

Parca is a self-contained profiling backend built around pprof ingest and its own storage engine, with the eBPF agent in the same repository. Pyroscope sits inside a wider observability stack where profiling shares storage and query with other signals, so the choice is largely about whether you want a dedicated profiling service or profiling folded into a system you already run.

How do I install and run Parca locally?

The README's development path is to clone the repository, run make build with Go, Node and pnpm installed, then start ./bin/parca. The UI is then available on http://localhost:7070/, and Parca scrapes its own pprof endpoints by default so profiles appear over time.

What can I configure with Parca's command line flags?

The flags cover the HTTP address and timeouts, the config path, the run mode, log format and level, CORS origins, OTLP tracing, and the storage layer. Storage-related flags include --enable-persistence, --storage-path, --storage-active-memory, --storage-enable-wal and --storage-index-on-disk.

What licence does Parca use?

Parca is licensed under Apache-2.0, as stated in the README badge and the LICENSE file at the repository root. The Dockerfile also labels the published image with the source and licence URLs.

Official sources

  1. License: Apache-2.0
  2. parca-dev/parca on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/parca-dev-parca.svg)](https://hysenlabs.com/projects/parca-dev-parca)