Grafana Pyroscope
Continuous profiling for finding performance bottlenecks
Grafana Pyroscope is a continuous profiling platform that collects, stores, and queries profiling data with minimal overhead. It helps engineers pinpoint CPU and memory hotspots across services.
Key features
- Continuous code profiling
- Flame graph visualization
- Low-overhead agents
- Grafana integration
Pros & cons
Strengths
- Pinpoints performance hotspots
- Scales efficiently
Trade-offs
- Niche use case
- Language agent setup required
Grafana Pyroscope replaces
Last reviewed Aug 26, 2026 · 854 words
Pyroscope answers exactly one question: which function in your code is burning the CPU or holding the memory, right now and over the last week, in production. If you do not write and run your own services, you have no reason to run it. Grafana with Prometheus tells you the container is at 90% CPU; Pyroscope tells you it is json.Unmarshal inside the webhook handler, and shows that it started with Tuesday's deploy. That is a niche, as the catalogue says, and for the people in it there is no cheaper route to the answer than a 512 MB container with an AGPL-3.0 licence and 11,600 stars.
The fourth pillar, and where it plugs in
Grafana's stack has settled on 4 signals: metrics in Prometheus or Mimir, logs in Loki, traces in Tempo, and continuous profiles in Pyroscope, which absorbed Grafana's own Phlare project in 2023. In practice that means Pyroscope is a data source in Grafana, profiles appear in Explore next to logs and traces, and if your services are instrumented for tracing you can jump from a slow span to the profile of the code that ran during it. Without Grafana, Pyroscope still serves its own web UI on port 4040, which is enough for a single developer.
services:
pyroscope:
image: grafana/pyroscope:latest
ports:
- "4040:4040"
volumes:
- ./data:/data
restart: unless-stopped
That is the monolithic mode, one binary doing ingest, storage and query, storing to a local directory. The microservices layout and object-storage backends (S3, GCS, Azure) exist for teams profiling hundreds of services; a homelab or a small company never needs them.
Profiles get in by push or by pull
The push route is an SDK inside the service. Go is the first-class citizen:
import "github.com/grafana/pyroscope-go"
func main() {
pyroscope.Start(pyroscope.Config{
ApplicationName: "webhook-api",
ServerAddress: "http://pyroscope:4040",
ProfileTypes: []pyroscope.ProfileType{
pyroscope.ProfileCPU,
pyroscope.ProfileAllocSpace,
pyroscope.ProfileInuseSpace,
pyroscope.ProfileGoroutines,
},
})
// rest of the program
}
Python, Java, .NET, Ruby, Node.js and Rust have SDKs or agents of their own, and the catalogue's "language agent setup required" is the honest cost: each service needs a few lines and a redeploy. The pull route avoids that. Grafana Alloy can scrape the standard /debug/pprof endpoints that Go services expose, and its eBPF profiler samples any process on a Linux host with no code changes, which is the way to profile a binary you did not write. eBPF results are best for compiled languages; interpreted runtimes give you frames from the interpreter rather than your script.
Reading a flame graph in 30 seconds
Width is time. The root is the whole program, each row down is a call deeper, and the widest leaf at the bottom is where the CPU went. Pyroscope's query bar uses label selectors in the Prometheus style, {service_name="webhook-api"}, plus a time range, so a week of profiles collapses into one graph. The diff view is the feature that pays the bill: select the hour before a deploy and the hour after, and functions that got more expensive turn red. Memory profiles work the same way with bytes instead of samples, and the inuse versus alloc distinction is the first thing to learn: alloc_space finds churn that stresses the garbage collector, inuse_space finds the leak.
Overhead, retention and the disk
Sampling at 100 Hz keeps the SDK cost in the low single-digit percent range for CPU, which is why "continuous" is not reckless; the number is on the order of what tracing already costs. On the server side, storage grows with the number of distinct label combinations more than with time, so avoid putting a request ID or a user ID into labels. Retention is a configuration setting, and a few Go services at default sampling produce tens of megabytes a day, so a 10 GB volume lasts a long time. The 512 MB minimum is fair for that scale; ingesting 50 services wants several gigabytes and, at that point, the documentation's scaling guidance.
The alternative, and the honest scope
Parca covers the same ground with an eBPF-first design and a lighter server, and suits a single-host setup where you want to profile everything without touching code. Pyroscope wins when Grafana is already your front door, when you have SDK-friendly services, and when you want profiles correlated with traces and logs. Neither replaces the monitoring category basics; profile only after metrics have told you something is wrong.
What I'd do
If you run 1 or more services you wrote in Go, Python or Java, add the monolithic container above, wire Grafana to it, and instrument one service with the SDK this week; the first flame graph of real production traffic usually pays for the hour by itself. Keep labels coarse, set a 30-day retention, and use the diff view after every deploy. If you only run other people's software, skip it entirely and spend the 512 MB on something that will change your week.
Compare Grafana Pyroscope
1 head-to-head comparisons.
Similar monitoring & status apps
Uptime Kuma
Monitoring & StatusEasy self-hosted uptime monitoring tool
Replaces Pingdom, UptimeRobot
Netdata
Monitoring & StatusReal-time per-second infrastructure monitoring
Replaces Datadog, New Relic
Grafana
Monitoring & StatusOpen observability dashboards and visualization
Replaces Datadog
Prometheus
Monitoring & StatusMetrics-based monitoring and alerting toolkit
Replaces Datadog
Glances
Monitoring & StatusCross-platform system monitoring at a glance
Replaces Datadog
InfluxDB
Monitoring & StatusPurpose-built time series database for metrics and events
Replaces Datadog, AWS Timestream