Setting Up Continuous Profiling (Pyroscope/Parca)

When standard metrics and traces show symptoms but fail to reveal the root cause of performance degradation, continuous profiling comes to the rescue. We implement Pyroscope and Parca so you can see which code consumes resources at any given moment. Our team delivers a turnkey project—from audit to setup and support—providing a reliable tool for identifying bottlenecks and preventing regressions.

Our competencies:

Frequently Asked Questions

Latest works

  • Development of a web application for FEEDME
    Development of a web application for FEEDME
    1365
  • Development of an online store for the company FURNORO
    Development of an online store for the company FURNORO
    1330
  • B2B Advance company logo design
    B2B Advance company logo design
    776
  • Development of a web application for Enviok
    Development of a web application for Enviok
    1077
  • AIDER company logo development
    AIDER company logo development
    1022
  • CRM development for Chasseurs
    CRM development for Chasseurs
    1113

Traces show a request took 800 ms. Metrics confirm p99 tripled after a deploy. But neither explains which line of code consumes 40% CPU. For that, you need a profiler running continuously in production. Continuous Profiling — the constant recording of profiles (flamegraphs) of all processes. Over 5 years of practice, we've found hundreds of bottlenecks: from JSON serialization in hot paths to memory leaks in middleware. Implementing Pyroscope or Parca not only finds problems but also prevents regressions with every deploy. Discuss Continuous Profiling for your project and get a consultation.

Why Continuous Profiling Over One-Shot Profilers?

Let's see what continuous monitoring brings. A one-shot py-spy top gives a snapshot here and now. Continuous profiling gives history. If today p95 CPU is 70% and a week ago it was 50%, the flamegraph shows which commit caused the jump. Without history, you'll guess when degradation started. Moreover, Pyroscope and Parca help investigate incidents 2–3 times faster thanks to a ready time axis. You can see how the flamegraph changed with each deploy — reducing MTTR from hours to minutes. Based on our projects, debugging time savings reach 40%, and infrastructure costs drop by 15–20%.

What Problems Does Continuous Profiling Solve?

Let's look at specific scenarios.

Memory Leaks Invisible in Metrics

Standard container_memory_usage_bytes shows growth but not the culprit. A heap profiler (Pyroscope ProfileInuseObjects) pinpoints exactly which object and which function holds memory. In one project, we found a leak in middleware that raised the process RSS from 200 MB to 2 GB in 6 hours — the flamegraph immediately pointed to code misusing context.Context.

CPU Regressions After Deploy

Roll out a new version — CPU spikes 300%. A flamegraph 'before' and 'after' shows which function slowed down. Typical finds: accidental debug mode, log level changes, a new dependency with heavy regexps.

Correlation with Traces

When a slow trace indicates a 500 ms span, the flamegraph for that period shows which function inside the span took 80% of the time. Pyroscope supports middleware for OpenTelemetry and Jaeger — profile.id is written to the span automatically.

Which Tool to Choose: Pyroscope or Parca?

Characteristic Pyroscope (Grafana) Parca (PolarSignals)
Operation mode Push-mode (SDK) + Pull-mode (eBPF) Only Pull-mode (eBPF)
Code changes needed Push-mode — yes, Pull-mode — no No
Supported languages Java, Go, Python, Node.js, Ruby (Pull) Any process on node
Trace integration Built-in (OpenTelemetry, Jaeger) Only via labels
CPU overhead 1–5% (Pull 1-3%, Push 2-5%) 1-3%
Storage S3, GCS, local S3, GCS, local

Get expert advice on tool selection and setup — contact us for a consultation.

How We Set Up Continuous Profiling

Pyroscope: Pull Mode (eBPF Agent)

The Pyroscope Agent runs as a DaemonSet, reading profiles directly from the kernel via eBPF without application changes. Requires Kubernetes 1.19+ and Linux kernel 4.9+.

# pyroscope-values.yaml for Helm pyroscope:
replicaCount: 1
storage:
  backend: s3
  s3:
    bucket: my-pyroscope-profiles
    region: eu-west-1
agent:
  enabled: true
  tolerations:
    - operator: Exists # deploy to all nodes, including system
config:
  discovery.relabel "pods" {} # auto-discovery of pods
How does eBPF work?eBPF is a Linux kernel technology that allows running isolated programs in response to events (system calls, network packets, etc.). In profiling, eBPF samples call stacks of all processes without modifying their code. Overhead is minimal as collection happens at kernel level.

Pyroscope: Push Mode (SDK)

The application explicitly sends profiles to Pyroscope. This gives finer control over labels and lower overhead for specific services.

Go SDK:

import "github.com/grafana/pyroscope-go"

func main() {
    pyroscope.Start(pyroscope.Config{
        ApplicationName: "order-service",
        ServerAddress: "http://pyroscope:4040",
        Tags: map[string]string{
            "version": os.Getenv("APP_VERSION"),
            "region": os.Getenv("REGION"),
        },
        ProfileTypes: []pyroscope.ProfileType{
            pyroscope.ProfileCPU,
            pyroscope.ProfileAllocObjects,
            pyroscope.ProfileAllocSpace,
            pyroscope.ProfileInuseObjects,
            pyroscope.ProfileInuseSpace,
        },
    })
    // ...
}

ProfileAllocObjects and ProfileInuseObjects are heap profiles for finding memory leaks. They helped find the middleware leak that raised RSS from 200MB to 2GB in 6 hours. Explore Pyroscope for deeper understanding.

Parca: eBPF-Oriented Alternative

Parca is 100% built on eBPF, more minimalistic, and requires no code changes.

helm install parca parca/parca \
  --set parca.config.object_storage.bucket.type=S3 \
  --set parca.config.object_storage.bucket.config.bucket=my-parca-profiles

Implementation Process

Phase Duration Description
Audit of current stack and goals 1 day Profiling plan: which services, which metrics, sampling frequency.
Deploy Pyroscope/Parca 1–2 days DaemonSet/Helm release with S3 storage, dashboards in Grafana.
Integrate SDK (push-mode) 1–2 days per 5 services Code with SDK, tested in staging.
Correlate with traces and metrics 1 day Middleware for OpenTelemetry/Jaeger, links from Tempo to Pyroscope.
Train the team 0.5 day Documentation, runbook, typical flamegraph walkthrough.

What’s Included in the Work

  • Architecture and configuration documentation (runbook).
  • Access to dashboards and profile sources.
  • Team training (30 min demo session).
  • Support for 2 weeks after implementation.

Common Implementation Mistakes

  • Sampling too frequently (1000 Hz). Causes excessive overhead (up to 10%). We recommend 100 Hz for CPU, 50 Hz for heap.
  • Storing profiles on local PVC. Easily lost; use S3 with a retention policy.
  • Missing trace correlation. Without profile.id, the flamegraph sits isolated — drastically losing value.
  • Not excluding eBPF agent from nodes with high I/O load. In some cases it can cause latency; use tolerations for isolation.

Setup time ranges from 1 day (eBPF pull-mode with no application changes) to 3 days (push-mode SDK for all services plus trace correlation and Grafana datasource). Pricing is custom after a detailed assessment. To get a consultation on implementation, contact us — we’ll evaluate your project and propose the optimal architecture.