Prof automates Go performance profiling by collecting all pprof data in one command and enabling easy performance comparisons between benchmark runs.
📖 Documentation |
This view highlights regressions, improvements, and stable functions.
This view provides a breakdown of performance metrics per function.
Before Prof: Profiling a single benchmark with multiple profile types requires dozens of manual commands:
# Run benchmark
go test -bench=BenchmarkName -cpuprofile=cpu.out -memprofile=memory.out ...
# Generate reports for each profile type
go tool pprof -cum -top cpu.out
go tool pprof -cum -top memory.out
# Extract function-level data for each function of interest
go tool pprof -list=Function1 cpu.out > function1.txt
go tool pprof -list=Function2 cpu.out > function2.txt
# ... repeat for every function × every profile type
With Prof: One command collects everything and organizes it automatically.
go install github.com/AlexsanderHamir/prof/cmd/prof@latest
- Collect profiling data:
prof auto --benchmarks "BenchmarkName" --profiles "cpu,memory,mutex,block" --count 10 --tag "baseline"
prof auto --benchmarks "BenchmarkName" --profiles "cpu,memory,mutex,block" --count 10 --tag "optimized"
- Compare performance between tags:
prof track auto --base "baseline" --current "optimized" --profile-type "cpu" --bench-name "BenchmarkName" --output-format "summary"
Use the tracking command with a threshold so your pipeline fails if the worst flat regression exceeds the limit:
What is the regression threshold?
The --regression-threshold
flag sets a percentage limit on performance regressions. When enabled with --fail-on-regression
, the command will exit with a non-zero status code if any function's flat time regression exceeds this threshold.
Flat time regression calculation:
Flat regression % = (current_time - baseline_time) / baseline_time × 100
Example: If a function took 100ms in baseline and 110ms in current run:
- Flat regression = (110 - 100) / 100 × 100 = +10%
- With
--regression-threshold 5.0
, this would fail the build - With
--regression-threshold 15.0
, this would pass
Note: The threshold applies to flat time (time spent directly in the function), not cumulative time (time including all called functions). Flat time gives a more direct measure of the function's own performance impact.
prof track auto \
--base "baseline" \
--current "PR" \
--profile-type "cpu" \
--bench-name "BenchmarkName" \
--output-format "summary" \
--fail-on-regression \
--regression-threshold 5.0
Important: The prof
command must be run from within the Go project directory where the benchmarks are located, otherwise it will fail with "go: cannot find main module" errors. This means running prof
from the exact directory containing your *_test.go
files with the benchmarks.
Example GitHub Actions job:
name: perf-regression-check
on: [pull_request]
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: ">=1.24"
- name: Install prof
run: go install github.com/AlexsanderHamir/prof/cmd/prof@latest
- name: Collect baseline (main)
run: |
git fetch origin main --depth=1
git checkout -qf origin/main
# prof must be run from within the Go project directory where benchmarks are located
cd ${{ github.workspace }}
prof auto --benchmarks "BenchmarkName" --profiles "cpu" --count 5 --tag baseline
- name: Collect current (PR)
run: |
git checkout -
# prof must be run from within the Go project directory where benchmarks are located
cd ${{ github.workspace }}
prof auto --benchmarks "BenchmarkName" --profiles "cpu" --count 5 --tag PR
- name: Compare and fail on regression
run: |
# prof must be run from within the Go project directory where benchmarks are located
cd ${{ github.workspace }}
prof track auto --base baseline --current PR \
--profile-type cpu --bench-name "BenchmarkName" \
--output-format summary --fail-on-regression --regression-threshold 5.0
- Go 1.24.3 or later
- Install graphviz
- Run from within your Go project directory (where benchmarks are located)
"go: cannot find main module"
- Run prof from within a Go project directory with
go.mod
"Profile file not found"
- Verify benchmark names are correct
- Ensure benchmarks run successfully and generate profiles
Too many function files
- Use configuration to filter functions with
include_prefixes
Configuration Not Taking Effect
- Make sure the config file is located in the current working directory, the one you're running the command from.
We welcome contributions of all kinds—bug fixes, new features, tests, and documentation improvements. Before getting started, make sure to review the issues to avoid duplicated effort, and see the contribution guidelines for more information.
Requirements: Go 1.24.3+, Git
# Clone the repository
git clone https://github.com/AlexsanderHamir/prof.git
cd prof
# Run tests
go test -v ./...
# Check for linter issues (first-time install if needed)
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
golangci-lint run
# Build the binary for local testing
go build -o prof ./cmd/prof
This project is licensed under the MIT License - see the LICENSE file for details.