What is the fastest host and server software to host nothing!

First off, forget about Apache. Apache is slow.

I was intrigued by the question so I decided to write the smallest possible webserver I could come up with in Go, which is read the request, ignore it, and respond with HTTP/1.1 200 OK. Note that this breaks the HTTP spec because it doesn’t return any Date headers or anything, but I assume that’s not really a problem? Less headers = less bytes over the wire = less time.

So here is the code

package main

import (
	"io"
	"log"
	"net"
	"os"
	"runtime"
)

func handleConnection(conn net.Conn) {
	defer conn.Close()
	b := make([]byte, 100)
	for {
		_, err := conn.Read(b)
		if err == io.EOF {
			return
		}
		if containsDoubleLnRf(b) {
			break
		}
	}
	conn.Write([]byte("HTTP/1.1 200 OK\n"))
}

func containsDoubleLnRf(b []byte) bool {
	for i := 0; i < len(b)-3; i++ {
		if b[i] == 13 && b[i+1] == 10 && b[i+2] == 13 && b[i+3] == 10 {
			return true
		}
	}
	return false
}

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())
	ln, err := net.Listen("tcp", ":8080")
	if err != nil {
		log.Printf("Error starting server: %s", err)
		os.Exit(1)
	}
	for {
		conn, err := ln.Accept()
		if err != nil {
			log.Printf("Could not accept connection: %s", err)
			continue
		}
		go handleConnection(conn)
	}
}

I have benchmarked this using ab -n 100000 -c 100 and got:

Concurrency Level:      100
Time taken for tests:   17.481 seconds
Complete requests:      100000
Failed requests:        0
Write errors:           0
Total transferred:      1600000 bytes
HTML transferred:       0 bytes
Requests per second:    5720.57 [#/sec] (mean)
Time per request:       17.481 [ms] (mean)
Time per request:       0.175 [ms] (mean, across all concurrent requests)
Transfer rate:          89.38 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    8   2.0      8      40
Processing:     1    9   2.5      9      44
Waiting:        0    7   2.4      6      41
Total:          6   17   2.3     17      50

The same thing for NGiNX serving a blank html file yielded:

Concurrency Level:      100
Time taken for tests:   21.586 seconds
Complete requests:      100000
Failed requests:        0
Write errors:           0
Total transferred:      15600000 bytes
HTML transferred:       0 bytes
Requests per second:    4632.73 [#/sec] (mean)
Time per request:       21.586 [ms] (mean)
Time per request:       0.216 [ms] (mean, across all concurrent requests)
Transfer rate:          705.77 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    9   7.9      8     229
Processing:     2   12  13.1     10     231
Waiting:        1    9  11.3      7     221
Total:         14   22  15.6     18     241

so basically my go program is about 23% faster than NGiNX :smile:

(to run the program, install go, save my code to a file, say server.go, when in the directory where server.go is stored, type go build server.go and then ./server)

3 Likes