Files
2026-07-24 16:23:24 +07:00

5.0 KiB

Production Observability for Performance

Third-party monitoring tools complement local profiling (pprof, benchmarks) by providing continuous monitoring, historical trends, and regression detection in production.

Prometheus Metrics for Go

Setup: github.com/prometheus/client_golang — expose /metrics endpoint with promhttp.Handler(). Default collectors automatically export Go runtime metrics (go_goroutines, go_memstats_*, go_gc_duration_seconds, process_cpu_seconds_total, etc.).

→ See samber/cc-skills-golang@golang-benchmark skill (investigation-session.md) for the full runtime metrics table, investigation session setup (scrape interval tuning, env-var toggling), and cost warnings for profiling tools.

PromQL Queries for Performance Diagnosis

GC pressure

PromQL What to look for
rate(go_gc_duration_seconds_count[5m]) GC cycles/s — >2/s sustained suggests excessive allocation rate
rate(go_gc_duration_seconds_sum[5m]) / rate(go_gc_duration_seconds_count[5m]) Average GC pause — increasing trend means heap is growing or has too many pointers
go_gc_duration_seconds{quantile="1"} Worst-case GC pause — spikes here cause tail latency

Memory leaks

PromQL What to look for
go_memstats_alloc_bytes Should be roughly stable under constant load; continuous increase = memory leak
rate(go_memstats_alloc_bytes_total[5m]) Allocation rate (bytes/s) — drives GC frequency; compare before/after deploy for regressions
process_resident_memory_bytes - go_memstats_sys_bytes Gap = non-Go memory (cgo, mmap); growing gap = non-Go leak

Goroutine leaks

PromQL What to look for
go_goroutines Should correlate with load; growing independently of traffic = leak
delta(go_goroutines[1h]) Net goroutine change over 1h; positive without load increase = leak

CPU saturation

PromQL What to look for
rate(process_cpu_seconds_total[5m]) CPU cores consumed; compare to GOMAXPROCS to detect saturation
rate(process_cpu_seconds_total[5m]) / <GOMAXPROCS> CPU utilization ratio; >0.8 sustained = CPU-saturated

Regression detection (after deploy)

PromQL What to look for
rate(go_memstats_alloc_bytes_total[5m]) Compare before/after deploy; significant increase = new allocation pattern introduced
histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m])) p99 latency increase after deploy = regression (requires app-level histogram)

Alerting rules (examples)

Example alerting rules — adjust thresholds to your application; a high-throughput data pipeline will have different baselines than a lightweight API server.

→ See samber/cc-skills@promql-cli skill for interactively testing these PromQL expressions against your Prometheus instance from the CLI.

Grafana Dashboards

→ See samber/cc-skills-golang@golang-observability skill for recommended community Grafana dashboards that visualize Go runtime metrics out of the box.

Continuous Profiling

Continuous profiling collects low-overhead samples in production and stores them for historical comparison. Use it to detect regressions across deploys, compare flamegraphs over time, and feed PGO (see Runtime Tuning).

Tool Model Overhead Best for
Grafana Pyroscope push SDK or pull (via Alloy) ~2-5% Grafana ecosystem, historical flamegraph comparison
Parca (Polar Signals) eBPF-based pull <1% Infrastructure-wide profiling, no code changes
Datadog Continuous Profiler push (agent) ~1-2% Existing Datadog users
Google Cloud Profiler push (agent) ~1-2% GCP-hosted Go services

Pyroscope push mode

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

pyroscope.Start(pyroscope.Config{
    ApplicationName: "myapp",
    ServerAddress:   "http://pyroscope:4040",
    ProfileTypes: []pyroscope.ProfileType{
        pyroscope.ProfileCPU,
        pyroscope.ProfileAllocObjects,
        pyroscope.ProfileAllocSpace,
        pyroscope.ProfileInuseObjects,
        pyroscope.ProfileInuseSpace,
        pyroscope.ProfileGoroutines,
    },
})

Pyroscope pull mode (via Grafana Alloy)

No code changes required — Alloy scrapes /debug/pprof/* endpoints periodically. Configure Alloy to target your service's pprof endpoint.

When using third-party profiling libraries, refer to the library's official documentation for current API signatures.

Real-Time Visualization (Development)

Tool What it does
statsviz (github.com/arl/statsviz) Real-time browser dashboard at /debug/statsviz — heap, GC pauses, goroutines, scheduler. Register with statsviz.Register(mux). Great for local development
expvar (stdlib expvar) JSON metrics at /debug/vars — lightweight, no dependencies. Integrates with Netdata, Telegraf, or custom dashboards