Skip to content

AlexsanderHamir/prof

Prof - Go Benchmark Profiling Made Simple

Prof automates Go performance profiling by collecting all pprof data in one command and enabling easy performance comparisons between benchmark runs.

GoDoc Go Report Card License: MIT Issues Last Commit Code Size Version Go Version

📖 Documentation | ▶️ Watch Demo Video

Benchmark Comparison Summary View:

This view highlights regressions, improvements, and stable functions.

Summary of benchmark performance changes

Benchmark Comparison Detailed View:

This view provides a breakdown of performance metrics per function.

Function-level performance comparison

Why Prof?

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.

Installation

go install github.com/AlexsanderHamir/prof/cmd/prof@latest

Quick Start

  1. 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"
  1. Compare performance between tags:
prof track auto --base "baseline" --current "optimized" --profile-type "cpu" --bench-name "BenchmarkName" --output-format "summary"

CI/CD: fail the pipeline on regressions

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

Requirements

  • Go 1.24.3 or later
  • Install graphviz
  • Run from within your Go project directory (where benchmarks are located)

Troubleshooting

"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.

Contributing

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.

Quick Start

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

License

This project is licensed under the MIT License - see the LICENSE file for details.

Sponsor this project

 

Packages

No packages published

Languages