# grafana/pyroscope-go architecture

> Architecture diagram of the GitHub repository grafana/pyroscope-go, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-29). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/grafana/pyroscope-go
- Repository: https://github.com/grafana/pyroscope-go

## Overview

Pyroscope Go Client profiles an application and sends profile snapshots to a Pyroscope server. Its main push workflow starts a session, periodically collects enabled CPU, memory, goroutine, block, and mutex data, encodes profiles, and submits upload jobs through an upstream. The README also documents pull profiling through pprof HTTP routes and label-based filtering; the tree includes a k6 baggage middleware integration. The session excerpt supports the collection and upload flow; connections for unsampled subsystems are limited to documented behavior.

Main entry points: [`session.go`](https://github.com/grafana/pyroscope-go/blob/main/session.go) (Profiling session), [`upstream/upstream.go`](https://github.com/grafana/pyroscope-go/blob/main/upstream/upstream.go) (Upload job), [`api.go`](https://github.com/grafana/pyroscope-go/blob/main/api.go) (Start API), [`internal/semconv/labels.go`](https://github.com/grafana/pyroscope-go/blob/main/internal/semconv/labels.go) (App labels)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_sdk["Client session"]
  node_start["Start API<br/>[api.go]"]
  node_session["Profiling session<br/>[session.go]"]
  node_labels["App labels<br/>[labels.go]"]
  node_labelset["Label validation<br/>[labelset.go]"]
end

subgraph group_profiling["Profile collection"]
  node_cpu["CPU collector<br/>[collector.go]"]
  node_runtime["Go runtime profiles<br/>[session.go]"]
  node_delta["Delta profiles<br/>[block.go]"]
  node_heap["Heap profiler<br/>[heap.go]"]
  node_encoding["Profile encoding<br/>[proto.go]"]
end

subgraph group_transport["Upload transport"]
  node_uploadjob["Upload job<br/>[upstream.go]"]
  node_upstream["Upstream interface<br/>[upstream.go]"]
  node_remote["Remote uploader<br/>[remote.go]"]
end

subgraph group_integrations["Integrations"]
  node_pull["Pprof HTTP routes<br/>[pprof.go]"]
  node_internalpprof["Runtime pprof<br/>[pprof.go]"]
  node_baggage["k6 baggage middleware<br/>[baggage.go]"]
end

node_app(("Go application"))
node_server(("Pyroscope server"))
node_request(("HTTP or gRPC request"))

node_app -->|"starts profiling"| node_start
node_start -->|"creates session"| node_session
node_session -->|"builds app names"| node_labels
node_labels -->|"parses and validates"| node_labelset
node_session -->|"starts CPU collection"| node_cpu
node_session -->|"reads runtime profiles"| node_runtime
node_session -->|"dumps block and mutex"| node_delta
node_session -->|"dumps heap deltas"| node_heap
node_delta -->|"encodes profile"| node_encoding
node_heap -->|"encodes profile"| node_encoding
node_cpu -->|"creates upload jobs"| node_uploadjob
node_session -->|"submits snapshots"| node_uploadjob
node_runtime -->|"packages profiles"| node_uploadjob
node_uploadjob -->|"submitted through"| node_upstream
node_upstream -->|"implemented by"| node_remote
node_remote -->|"posts profile data"| node_server
node_request -->|"requests profile"| node_pull
node_pull -->|"collects CPU profile"| node_internalpprof
node_internalpprof -->|"writes profile response"| node_request
node_request -.->|"carries baggage"| node_baggage
node_baggage -.->|"sets profiling labels"| node_app

click node_start "https://github.com/grafana/pyroscope-go/blob/main/api.go"
click node_session "https://github.com/grafana/pyroscope-go/blob/main/session.go"
click node_labels "https://github.com/grafana/pyroscope-go/blob/main/internal/semconv/labels.go"
click node_labelset "https://github.com/grafana/pyroscope-go/blob/main/internal/labelset/labelset.go"
click node_cpu "https://github.com/grafana/pyroscope-go/blob/main/collector.go"
click node_runtime "https://github.com/grafana/pyroscope-go/blob/main/session.go"
click node_delta "https://github.com/grafana/pyroscope-go/blob/main/godeltaprof/block.go"
click node_heap "https://github.com/grafana/pyroscope-go/blob/main/godeltaprof/heap.go"
click node_encoding "https://github.com/grafana/pyroscope-go/blob/main/godeltaprof/internal/pprof/proto.go"
click node_uploadjob "https://github.com/grafana/pyroscope-go/blob/main/upstream/upstream.go"
click node_upstream "https://github.com/grafana/pyroscope-go/blob/main/upstream/upstream.go"
click node_remote "https://github.com/grafana/pyroscope-go/blob/main/upstream/remote/remote.go"
click node_pull "https://github.com/grafana/pyroscope-go/blob/main/http/pprof/pprof.go"
click node_internalpprof "https://github.com/grafana/pyroscope-go/blob/main/internal/pprof/pprof.go"
click node_baggage "https://github.com/grafana/pyroscope-go/blob/main/x/k6/baggage.go"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_start,node_session,node_labels,node_labelset toneBlue
class node_cpu,node_runtime,node_delta,node_heap,node_encoding toneAmber
class node_uploadjob,node_upstream,node_remote,node_server,node_request toneMint
class node_pull,node_internalpprof,node_baggage toneRose
class node_app toneIndigo
```

## Components

### Client session

- [Start API](https://github.com/grafana/pyroscope-go/blob/main/api.go): `api.go`
- [Profiling session](https://github.com/grafana/pyroscope-go/blob/main/session.go): `session.go`
- [App labels](https://github.com/grafana/pyroscope-go/blob/main/internal/semconv/labels.go): `internal/semconv/labels.go`
- [Label validation](https://github.com/grafana/pyroscope-go/blob/main/internal/labelset/labelset.go): `internal/labelset/labelset.go`

### Profile collection

- [CPU collector](https://github.com/grafana/pyroscope-go/blob/main/collector.go): `collector.go`
- [Go runtime profiles](https://github.com/grafana/pyroscope-go/blob/main/session.go): `session.go`
- [Delta profiles](https://github.com/grafana/pyroscope-go/blob/main/godeltaprof/block.go): `godeltaprof/block.go`
- [Heap profiler](https://github.com/grafana/pyroscope-go/blob/main/godeltaprof/heap.go): `godeltaprof/heap.go`
- [Profile encoding](https://github.com/grafana/pyroscope-go/blob/main/godeltaprof/internal/pprof/proto.go): `godeltaprof/internal/pprof/proto.go`

### Upload transport

- [Upload job](https://github.com/grafana/pyroscope-go/blob/main/upstream/upstream.go): `upstream/upstream.go`
- [Upstream interface](https://github.com/grafana/pyroscope-go/blob/main/upstream/upstream.go): `upstream/upstream.go`
- [Remote uploader](https://github.com/grafana/pyroscope-go/blob/main/upstream/remote/remote.go): `upstream/remote/remote.go`

### Integrations

- [Pprof HTTP routes](https://github.com/grafana/pyroscope-go/blob/main/http/pprof/pprof.go): `http/pprof/pprof.go`
- [Runtime pprof](https://github.com/grafana/pyroscope-go/blob/main/internal/pprof/pprof.go): `internal/pprof/pprof.go`
- [k6 baggage middleware](https://github.com/grafana/pyroscope-go/blob/main/x/k6/baggage.go): `x/k6/baggage.go`

### Other components

- **Go application**
- **Pyroscope server**
- **HTTP or gRPC request**

## Connections

- Go application → Start API: starts profiling
- Start API → Profiling session: creates session
- Profiling session → App labels: builds app names
- App labels → Label validation: parses and validates
- Profiling session → CPU collector: starts CPU collection
- Profiling session → Go runtime profiles: reads runtime profiles
- Profiling session → Delta profiles: dumps block and mutex
- Profiling session → Heap profiler: dumps heap deltas
- Delta profiles → Profile encoding: encodes profile
- Heap profiler → Profile encoding: encodes profile
- CPU collector → Upload job: creates upload jobs
- Profiling session → Upload job: submits snapshots
- Go runtime profiles → Upload job: packages profiles
- Upload job → Upstream interface: submitted through
- Upstream interface → Remote uploader: implemented by
- Remote uploader → Pyroscope server: posts profile data
- HTTP or gRPC request → Pprof HTTP routes: requests profile
- Pprof HTTP routes → Runtime pprof: collects CPU profile
- Runtime pprof → HTTP or gRPC request: writes profile response
- HTTP or gRPC request → k6 baggage middleware: carries baggage
- k6 baggage middleware → Go application: sets profiling labels
