Performance & Deployment

Profiling, benchmarks, memory optimization, and deploying Go apps.

Advanced 35 min read 🐹 Go

Profiling with pprof

Go has built-in profiling. Import net/http/pprof and access profiles at /debug/pprof/:

import _ "net/http/pprof"

// CPU profile
go tool pprof http://localhost:6060/debug/pprof/profile?seconds=10

// Memory profile
go tool pprof http://localhost:6060/debug/pprof/heap

// Goroutine profile (find leaks)
go tool pprof http://localhost:6060/debug/pprof/goroutine

Benchmarks

func BenchmarkStringConcat(b *testing.B) {
    for i := 0; i < b.N; i++ {
        s := ""
        for j := 0; j < 100; j++ { s += "x" }
    }
}

func BenchmarkStringBuilder(b *testing.B) {
    for i := 0; i < b.N; i++ {
        var sb strings.Builder
        for j := 0; j < 100; j++ { sb.WriteString("x") }
        _ = sb.String()
    }
}
go test -bench=. -benchmem
Output
BenchmarkStringConcat-8     50000    28432 ns/op   11840 B/op   99 allocs/op
BenchmarkStringBuilder-8  1000000     1052 ns/op     504 B/op    7 allocs/op

StringBuilder is 27x faster with 14x fewer allocations. Always benchmark before and after optimization.

Key Takeaway: Profile first, optimize second. Use go test -bench for micro-benchmarks and pprof for production profiling. The biggest wins come from reducing allocations and using appropriate data structures.

Practice Exercises

Hard Production Scenario

Design a solution using these concepts for a real-world production system.

Hard Performance Analysis

Benchmark two different approaches and explain which is better and why.