Skip to content

Instantly share code, notes, and snippets.

@barron9
Forked from yosssi/go-nginx.md
Created July 6, 2021 14:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save barron9/cb12a62e746ee8e2df0fe1ac96f5816e to your computer and use it in GitHub Desktop.
Save barron9/cb12a62e746ee8e2df0fe1ac96f5816e to your computer and use it in GitHub Desktop.
Go networking performance vs Nginx

1. Nginx

$ wrk -t12 -c400 -d2s http://127.0.0.1:8080
Running 2s test @ http://127.0.0.1:8080
  12 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     7.71ms    3.16ms  23.05ms   69.17%
    Req/Sec     3.44k     1.98k    7.80k    58.22%
  63697 requests in 2.00s, 17.86MB read
  Socket errors: connect 155, read 47, write 0, timeout 66
Requests/sec:  31780.82
Transfer/sec:      8.91MB

2. Go with an empty response

main.go

package main

import (
	"log"
	"net/http"
)

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {

	})
	if err := http.ListenAndServe(":8080", nil); err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}
$ GOMAXPROCS=2 go run main.go
$ wrk -t12 -c400 -d2s http://127.0.0.1:8080
Running 2s test @ http://127.0.0.1:8080
  12 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     3.79ms  492.55us   7.85ms   76.02%
    Req/Sec     6.63k     2.47k   13.10k    60.47%
  124846 requests in 2.00s, 13.81MB read
  Socket errors: connect 155, read 50, write 0, timeout 66
Requests/sec:  62314.54
Transfer/sec:      6.89MB

3. Go with a simple response

main.go

package main

import (
	"fmt"
	"log"
	"net/http"
)

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprint(w, "Hello")
	})
	if err := http.ListenAndServe(":8080", nil); err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}
$ GOMAXPROCS=2 go run main.go
$ wrk -t12 -c400 -d2s http://127.0.0.1:8080
Running 2s test @ http://127.0.0.1:8080
  12 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     3.79ms  492.55us   7.85ms   76.02%
    Req/Sec     6.63k     2.47k   13.10k    60.47%
  124846 requests in 2.00s, 13.81MB read
  Socket errors: connect 155, read 50, write 0, timeout 66
Requests/sec:  62314.54
Transfer/sec:      6.89MB
mac:~ yoshidakeiji$ wrk -t12 -c400 -d2s http://127.0.0.1:8080
Running 2s test @ http://127.0.0.1:8080
  12 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     3.87ms  725.83us  13.10ms   84.56%
    Req/Sec     6.50k     3.06k   23.70k    60.89%
  121878 requests in 2.00s, 14.06MB read
  Socket errors: connect 155, read 54, write 0, timeout 66
Requests/sec:  60837.67
Transfer/sec:      7.02MB

4. Go with a file server

main.go

package main

import (
	"log"
	"net/http"
)

func main() {
	http.Handle("/", http.FileServer(http.Dir("/Users/yoshidakeiji/www")))
	if err := http.ListenAndServe(":8080", nil); err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}
$ GOMAXPROCS=2 go run main.go
$ wrk -t12 -c400 -d2s http://127.0.0.1:8080
Running 2s test @ http://127.0.0.1:8080
  12 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    14.86ms    1.52ms  19.52ms   74.31%
    Req/Sec     1.65k   795.40     2.53k    69.16%
  32254 requests in 2.00s, 7.47MB read
  Socket errors: connect 155, read 0, write 0, timeout 66
Requests/sec:  16088.43
Transfer/sec:      3.73MB

5. Go with a cached file server

main.go

package main

import (
	"log"
	"net/http"

	"github.com/yosssi/go-fileserver"
)

func main() {
	fs := fileserver.New(fileserver.Options{})
	http.Handle("/", fs.Serve(http.Dir("/Users/yoshidakeiji/www")))
	if err := http.ListenAndServe(":8080", nil); err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}
$ GOMAXPROCS=2 go run main.go
$ wrk -t12 -c400 -d2s http://127.0.0.1:8080
Running 2s test @ http://127.0.0.1:8080
  12 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    13.55ms    2.76ms  27.83ms   75.61%
    Req/Sec     2.19k   393.78     3.04k    57.03%
  51146 requests in 2.00s, 8.93MB read
  Socket errors: connect 0, read 190, write 0, timeout 0
Requests/sec:  25581.43
Transfer/sec:      4.46MB

6. Go with a cached file server which calls io.Copy instead of http.ServeContent

main.go

package main

import (
	"log"
	"net/http"

	"github.com/yosssi/go-fileserver"
)

func main() {
	fs := fileserver.New(fileserver.Options{})
	http.Handle("/", fs.Serve(http.Dir("/Users/yoshidakeiji/www")))
	if err := http.ListenAndServe(":8080", nil); err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}
$ GOMAXPROCS=2 go run main.go
$ wrk -t12 -c400 -d2s http://127.0.0.1:8080
Running 2s test @ http://127.0.0.1:8080
  12 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     5.01ms  641.48us   9.39ms   79.67%
    Req/Sec     5.27k     1.48k    9.30k    60.07%
  118962 requests in 2.00s, 13.17MB read
  Socket errors: connect 0, read 125, write 0, timeout 0
Requests/sec:  59517.07
Transfer/sec:      6.59MB
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment