Saturday, September 30, 2017

Profiling and optimizing Go web applications

Profiling and optimizing Go web applications

Install Graphviz for generating a PDF file:

# apt-get install graphviz

Use hey as the benchmark tool:

# go get -u
# hey -n 100000 -c 10 http://localhost:8080

Sample code:

package main

import (
 _ "net/http/pprof" // here be dragons

func main() {
 http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
  fmt.Fprintf(w, "Hello World!")
 log.Fatal(http.ListenAndServe(":8080", nil))

If your web application is using a custom mux (HTTP request multiplexer), you will need to register a few pprof HTTP endpoints manually:

package main

import (

func hiHandler(w http.ResponseWriter, r *http.Request) {

func main() {
    r := http.NewServeMux()
    r.HandleFunc("/", hiHandler)

    // Register pprof handlers
    r.HandleFunc("/debug/pprof/", pprof.Index)
    r.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
    r.HandleFunc("/debug/pprof/profile", pprof.Profile)
    r.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
    r.HandleFunc("/debug/pprof/trace", pprof.Trace)

    http.ListenAndServe(":8080", r)

CPU profile:


Memory profile:


Goroutine blocking profile:


To look at the holders of contended mutexes, after calling runtime.SetMutexProfileFraction in your program:


All goroutines with stack traces:


Take a trace:


To view all available profiles, open:


To look at a 30-second CPU profile:

# go tool pprof http://localhost:8080/debug/pprof/profile?seconds=30
(pprof) top
(pprof) web
(pprof) exit

Note: Run go tool pprof -h 2>&1 | less for more information.

# go tool pprof -text http://localhost:8080/debug/pprof/profile?seconds=10 | tee cpu.txt

Note: output to a text file.

# go tool pprof -pdf http://localhost:8080/debug/pprof/profile?seconds=10 > cpu.pdf

Note: output to a PDF file.

# go tool pprof -tree http://localhost:8080/debug/pprof/profile?seconds=10 > cpu.txt

Note: Outputs a text rendering of call graph.

# go tool pprof -web http://localhost:8080/debug/pprof/profile?seconds=10

Note: Visualize graph through web browser.

To collect a 5-second execution trace:

# curl -o trace.out

# go tool trace -http="" trace.out

Note: You can run these two commands above on a client machine (e.g., Windows)


No comments: