### Build the Multidomain Example Source: https://github.com/valyala/fasthttp/blob/master/examples/multidomain/README.md Build the multidomain example using make. Ensure you have the necessary build tools installed. ```bash make ``` -------------------------------- ### Install fasthttp Source: https://github.com/valyala/fasthttp/blob/master/README.md Use this command to install the fasthttp package using go get. ```bash go get -u github.com/valyala/fasthttp ``` -------------------------------- ### Run the Multidomain Example Source: https://github.com/valyala/fasthttp/blob/master/examples/multidomain/README.md Run the compiled multidomain executable. This will start the fasthttp server. ```bash ./multidomain ``` -------------------------------- ### Start fasthttp Server with ListenAndServe Source: https://context7.com/valyala/fasthttp/llms.txt Use ListenAndServe for a simple way to start a fasthttp server. It accepts a TCP address and a request handler function. The handler is invoked for every incoming request. Ensure to handle potential errors from ListenAndServe. ```go package main import ( "fmt" "log" "github.com/valyala/fasthttp" ) func main() { // requestHandler is called for every incoming HTTP request. requestHandler := func(ctx *fasthttp.RequestCtx) { fmt.Fprintf(ctx, "Hello, world!\n\n") fmt.Fprintf(ctx, "Method: %s\n", ctx.Method()) fmt.Fprintf(ctx, "Path: %s\n", ctx.Path()) fmt.Fprintf(ctx, "Host: %s\n", ctx.Host()) fmt.Fprintf(ctx, "Query: %s\n", ctx.QueryArgs()) fmt.Fprintf(ctx, "RemoteIP: %s\n", ctx.RemoteIP()) fmt.Fprintf(ctx, "User-Agent: %s\n", ctx.UserAgent()) // Set response headers and cookies ctx.SetContentType("text/plain; charset=utf8") ctx.Response.Header.Set("X-Custom-Header", "value") var c fasthttp.Cookie c.SetKey("session") c.SetValue("abc123") c.SetHTTPOnly(true) ctx.Response.Header.SetCookie(&c) } log.Fatal(fasthttp.ListenAndServe(":8080", requestHandler)) } ``` -------------------------------- ### Simple Client GET and POST Requests Source: https://context7.com/valyala/fasthttp/llms.txt Performs basic HTTP GET and POST requests using the package-level functions. These functions utilize a shared default client and handle redirects. The `dst` parameter can be used to reuse a body buffer for efficiency. ```go package main import ( "fmt" "log" "time" "github.com/valyala/fasthttp ) func main() { // Simple GET — follows redirects statusCode, body, err := fasthttp.Get(nil, "https://httpbin.org/get") if err != nil { log.Fatalf("GET error: %v", err) } fmt.Printf("Status: %d\nBody: %s\n", statusCode, body) // GET with timeout — reuse body buffer statusCode, body, err = fasthttp.GetTimeout(body[:0], "https://httpbin.org/delay/1", 2*time.Second) if err != nil { log.Printf("Timed-out GET: %v", err) } // POST with form args args := fasthttp.AcquireArgs() args.Set("name", "fasthttp") args.Set("value", "42") statusCode, body, err = fasthttp.Post(body[:0], "https://httpbin.org/post", args) fasthttp.ReleaseArgs(args) if err != nil { log.Fatalf("POST error: %v", err) } fmt.Printf("POST status: %d\n", statusCode) } ``` -------------------------------- ### HostClient: Single-Host Connection Pool Example Source: https://context7.com/valyala/fasthttp/llms.txt Use HostClient for connections to a fixed host, optimizing performance when all requests target the same server. Supports HTTP proxy usage and TLS. ```go package main import ( "fmt" "log" "github.com/valyala/fasthttp ) func main() { // All requests go to api.example.com:443 over HTTPS hc := &fasthttp.HostClient{ Addr: "api.example.com:443", IsTLS: true, MaxConns: 64, MaxConnWaitTimeout: 100_000_000, // 100ms in nanoseconds } var buf []byte for _, path := range []string{"/users", "/orders", "/products"} { code, body, err := hc.Get(buf, "https://api.example.com"+path) if err != nil { log.Printf("Error fetching %s: %v", path, err) continue } buf = body[:0] // reuse backing array fmt.Printf("%s → %d (%d bytes)\n", path, code, len(body)) } } ``` -------------------------------- ### Configure fasthttp Server with Custom Server Struct Source: https://context7.com/valyala/fasthttp/llms.txt Create a Server struct for fine-grained control over timeouts, concurrency, connection limits, and other settings. Adjust these only if defaults are insufficient, as incorrect settings can impact performance. The example includes a basic error handler and a placeholder for graceful shutdown. ```go package main import ( "fmt" "log" "time" "github.com/valyala/fasthttp" ) func main() { s := &fasthttp.Server{ Handler: func(ctx *fasthttp.RequestCtx) { fmt.Fprintf(ctx, "OK") }, Name: "MyApp", ReadTimeout: 5 * time.Second, WriteTimeout: 10 * time.Second, IdleTimeout: 60 * time.Second, MaxConnsPerIP: 100, MaxRequestsPerConn: 1000, MaxRequestBodySize: 4 * 1024 * 1024, // 4 MB Concurrency: 256 * 1024, DisableKeepalive: false, TCPKeepalive: true, ReduceMemoryUsage: false, GetOnly: false, DisablePreParseMultipartForm: false, ErrorHandler: func(ctx *fasthttp.RequestCtx, err error) { ctx.Error("Bad request: "+err.Error(), fasthttp.StatusBadRequest) }, } // Graceful shutdown example go func() { // signal received — call s.Shutdown() }() if err := s.ListenAndServe(":8080"); err != nil { log.Fatalf("Server error: %v", err) } } ``` -------------------------------- ### Fasthttp Functions Accepting Nil Buffers Source: https://github.com/valyala/fasthttp/blob/master/README.md Demonstrates that fasthttp functions like `Get` and `AppendUint` can accept nil byte slices as arguments. ```go statusCode, body, err := fasthttp.Get(nil, "http://google.com/") uintBuf := fasthttp.AppendUint(nil, 1234) ``` -------------------------------- ### Handle Request and Response Headers in fasthttp Source: https://context7.com/valyala/fasthttp/llms.txt Access standard and custom headers for both requests and responses. Use `Peek` for reading arbitrary headers and `VisitAll` to iterate through all headers. `SetStatusCode` and `SetContentRange` are examples of response header manipulation. ```go func headersExample(ctx *fasthttp.RequestCtx) { rh := &ctx.Request.Header // Read standard fields fmt.Println(string(rh.Method())) // "POST" fmt.Println(string(rh.Host())) // "api.example.com" fmt.Println(string(rh.UserAgent())) // "MyClient/1.0" fmt.Println(string(rh.ContentType())) // "application/json" fmt.Println(rh.ContentLength()) // 256 // Read arbitrary header authHeader := string(rh.Peek("Authorization")) // "Bearer token..." // Iterate all headers rh.VisitAll(func(key, value []byte) { fmt.Printf("%s: %s\n", key, value) }) // --- Response headers --- wh := &ctx.Response.Header wh.SetStatusCode(fasthttp.StatusOK) wh.SetContentType("application/json") wh.Set("X-Rate-Limit", "1000") wh.Add("Vary", "Accept-Encoding") wh.SetContentRange(0, 999, 5000) // Content-Range: bytes 0-999/5000 _ = authHeader } ``` -------------------------------- ### Zero-Allocation String/Byte Conversions in Fasthttp Source: https://context7.com/valyala/fasthttp/llms.txt Converts between []byte and string without allocation. Use only when the original value is guaranteed immutable for the lifetime of the converted result. This example shows converting request path and host to strings, and a string key to bytes for header manipulation. ```go func zeroAllocExample(ctx *fasthttp.RequestCtx) { // []byte → string without allocation (DO NOT mutate the original []byte) path := fasthttp.UnsafeString(ctx.Path()) host := fasthttp.UnsafeString(ctx.Host()) // string → []byte without allocation (DO NOT mutate the returned []byte) key := "Content-Type" keyBytes := fasthttp.UnsafeBytes(key) // Safe to use for read-only comparisons / map lookups switch path { case "/health": ctx.SetBodyString(`{"status":"up","host":"` + host + `"}`) default: ctx.Response.Header.SetBytesV(string(keyBytes), []byte("text/plain")) fmt.Fprintf(ctx, "path: %s", path) } } ``` -------------------------------- ### Serve Static Files with fasthttp.FS Source: https://context7.com/valyala/fasthttp/llms.txt Configures a production-ready static file server with features like compression, directory indexing, and byte-range support. Ensure the Root directory exists and is accessible. ```go package main import ( "log" "time" "github.com/valyala/fasthttp ) func main() { fs := &fasthttp.FS{ Root: "/var/www/html", IndexNames: []string{"index.html"}, GenerateIndexPages: false, Compress: true, // serve .gz/.br variants CompressBrotli: true, AcceptByteRange: true, // support Range: bytes=... CacheDuration: 10 * time.Second, SkipCache: false, } log.Fatal(fasthttp.ListenAndServe(":8080", fs.NewRequestHandler())) } ``` -------------------------------- ### Wrap fasthttp Server with Prefork Source: https://github.com/valyala/fasthttp/blob/master/prefork/README.md Use prefork.New to wrap your fasthttp.Server for preforking. Ensure to handle potential errors during ListenAndServe. ```go import ( "github.com/valyala/fasthttp" "github.com/valyala/fasthttp/prefork" ) server := &fasthttp.Server{ // Your configuration } // Wraps the server with prefork preforkServer := prefork.New(server) if err := preforkServer.ListenAndServe(":8080"); err != nil { panic(err) } ``` -------------------------------- ### Custom Client with Connection Pooling Source: https://context7.com/valyala/fasthttp/llms.txt Demonstrates using a custom `fasthttp.Client` for managing per-host connection pools and performing zero-allocation requests using `AcquireRequest`/`AcquireResponse`. Configure client options like timeouts, connection limits, and dialer settings for performance. ```go package main import ( "encoding/json" "fmt" "log" "time" "github.com/valyala/fasthttp ) var client = &fasthttp.Client{ ReadTimeout: 500 * time.Millisecond, WriteTimeout: 500 * time.Millisecond, MaxIdleConnDuration: time.Hour, MaxConnsPerHost: 512, MaxResponseBodySize: 8 * 1024 * 1024, // 8 MB NoDefaultUserAgentHeader: true, Dial: (&fasthttp.TCPDialer{ Concurrency: 4096, DNSCacheDuration: time.Hour, }).Dial, } func main() { // Acquire pooled request/response objects — zero allocation req := fasthttp.AcquireRequest() resp := fasthttp.AcquireResponse() defer fasthttp.ReleaseRequest(req) defer fasthttp.ReleaseResponse(resp) req.SetRequestURI("http://localhost:8080/api/data") req.Header.SetMethod(fasthttp.MethodPost) req.Header.SetContentType("application/json") payload, _ := json.Marshal(map[string]any{"key": "value", "count": 42}) req.SetBodyRaw(payload) if err := client.DoTimeout(req, resp, 200*time.Millisecond); err != nil { switch { case err == fasthttp.ErrTimeout: log.Println("request timed out") case err == fasthttp.ErrNoFreeConns: log.Println("connection pool exhausted") default: log.Printf("request failed: %v", err) } return } fmt.Printf("Status: %d\nBody: %s\n", resp.StatusCode(), resp.Body()) } ``` -------------------------------- ### Run the HelloWorld Server Source: https://github.com/valyala/fasthttp/blob/master/examples/helloworldserver/README.md Runs the HelloWorld server executable. Specify the TCP address and port to listen on. ```bash ./helloworldserver -addr=tcp.addr.to.listen:to ``` -------------------------------- ### Multi-Process Scaling with Prefork Source: https://context7.com/valyala/fasthttp/llms.txt Utilizes the `prefork` package to fork the server into multiple child processes, one per CPU core, for enhanced throughput. Each process runs with `GOMAXPROCS=1`, minimizing Go runtime cross-core memory overhead. Note that global in-memory state is not shared between processes. ```go package main import ( "fmt" "log" "github.com/valyala/fasthttp" "github.com/valyala/fasthttp/prefork" ) func main() { s := &fasthttp.Server{ Handler: func(ctx *fasthttp.RequestCtx) { fmt.Fprintf(ctx, "Handled by child PID %d", ctx.ConnID()) }, Name: "PreforkServer", } pf := prefork.New(s) pf.Reuseport = true // use SO_REUSEPORT (recommended) pf.RecoverThreshold = 4 if prefork.IsChild() { log.Printf("Child process started") } if err := pf.ListenAndServe(":8080"); err != nil { log.Fatalf("prefork error: %v", err) } } ``` -------------------------------- ### Access and Build Query Arguments with Args in fasthttp Source: https://context7.com/valyala/fasthttp/llms.txt Read query string parameters and build new query strings using `fasthttp.Args`. Use `AcquireArgs` and `ReleaseArgs` for efficient memory management. `GetUintOrZero` returns 0 for missing keys, and `GetBool` returns true if the key is present. ```go func argsExample(ctx *fasthttp.RequestCtx) { // Read from query string: /search?q=golang&page=3&active q := ctx.QueryArgs() search := string(q.Peek("q")) // "golang" page := q.GetUintOrZero("page") // 3 active := q.GetBool("active") // true (key present) missing := q.GetUintOrZero("limit") // 0 (not present) // Build a new query string a := fasthttp.AcquireArgs() defer fasthttp.ReleaseArgs(a) a.Set("q", search) a.SetUint("page", page+1) a.SetBool("debug", true) // a.String() → "q=golang&page=4&debug=true" fmt.Fprintf(ctx, "next page: /search?%s", a.QueryString()) _ = active; _ = missing } ``` -------------------------------- ### Run fasthttp Fileserver Source: https://github.com/valyala/fasthttp/blob/master/examples/fileserver/README.md Run the fasthttp fileserver executable with specified address and directory. Use -h for help. ```bash ./fileserver -h ``` ```bash ./fileserver -addr=tcp.addr.to.listen:to -dir=/path/to/directory/to/serve ``` -------------------------------- ### Server: TLS/HTTPS with ListenAndServeTLS Source: https://context7.com/valyala/fasthttp/llms.txt Enables HTTPS support by serving requests over TLS. Requires certificate and key files on disk. Use ListenAndServeTLSEmbed for in-memory certificate data. ```go package main import ( "fmt" "log" "github.com/valyala/fasthttp" ) func main() { handler := func(ctx *fasthttp.RequestCtx) { fmt.Fprintf(ctx, "Secure response. TLS: %v", ctx.IsTLS()) } // Using cert/key files on disk: log.Fatal(fasthttp.ListenAndServeTLS(":443", "server.crt", "server.key", handler)) // Or with embedded cert data (e.g., from go:embed): // log.Fatal(fasthttp.ListenAndServeTLSEmbed(":443", certData, keyData, handler)) } ``` -------------------------------- ### Fasthttp Fileserver Performance Test (10s) Source: https://github.com/valyala/fasthttp/blob/master/examples/fileserver/README.md Performance benchmark of fasthttp fileserver serving static files using wrk. Tests 10 seconds duration with 4 threads and 16 connections. ```bash $ ./wrk -t 4 -c 16 -d 10 http://localhost:8080 Running 10s test @ http://localhost:8080 4 threads and 16 connections Thread Stats Avg Stdev Max +/- Stdev Latency 447.99us 1.59ms 27.20ms 94.79% Req/Sec 37.13k 3.99k 47.86k 76.00% 1478457 requests in 10.02s, 1.03GB read Requests/sec: 147597.06 Transfer/sec: 105.15MB ``` -------------------------------- ### Fasthttp Fileserver Pipelined Performance Test (8 requests) Source: https://github.com/valyala/fasthttp/blob/master/examples/fileserver/README.md Performance benchmark of fasthttp fileserver serving static files with 8 pipelined requests using wrk. Tests 10 seconds duration with 4 threads and 16 connections. ```bash $ ./wrk -s pipeline.lua -t 4 -c 16 -d 10 http://localhost:8080 -- 8 Running 10s test @ http://localhost:8080 4 threads and 16 connections Thread Stats Avg Stdev Max +/- Stdev Latency 2.08ms 6.33ms 88.26ms 92.83% Req/Sec 116.54k 14.66k 167.98k 69.00% 4642226 requests in 10.03s, 3.23GB read Requests/sec: 462769.41 Transfer/sec: 329.67MB ``` -------------------------------- ### Nginx Performance Test (10s) Source: https://github.com/valyala/fasthttp/blob/master/examples/fileserver/README.md Performance benchmark of Nginx serving static files using wrk. Tests 10 seconds duration with 4 threads and 16 connections. ```bash $ ./wrk -t 4 -c 16 -d 10 http://localhost:80 Running 10s test @ http://localhost:80 4 threads and 16 connections Thread Stats Avg Stdev Max +/- Stdev Latency 397.76us 1.08ms 20.23ms 95.19% Req/Sec 21.20k 2.49k 31.34k 79.65% 850220 requests in 10.10s, 695.65MB read Requests/sec: 84182.71 Transfer/sec: 68.88MB ``` -------------------------------- ### Benchmark net/http Server (GOMAXPROCS=1) Source: https://github.com/valyala/fasthttp/blob/master/README.md Shows benchmark results for the standard Go net/http server when GOMAXPROCS is set to 1. This serves as a baseline for performance comparison. ```bash $ GOMAXPROCS=1 go test -bench=NetHTTPServerGet -benchmem -benchtime=10s cpu: Intel(R) Xeon(R) CPU @ 2.20GHz BenchmarkNetHTTPServerGet1ReqPerConn 722565 15327 ns/op 3258 B/op 36 allocs/op BenchmarkNetHTTPServerGet2ReqPerConn 990067 11533 ns/op 2817 B/op 28 allocs/op BenchmarkNetHTTPServerGet10ReqPerConn 1376821 8734 ns/op 2483 B/op 23 allocs/op BenchmarkNetHTTPServerGet10KReqPerConn 1691265 7151 ns/op 2385 B/op 21 allocs/op BenchmarkNetHTTPServerGet1ReqPerConn10KClients 643940 17152 ns/op 3529 B/op 36 allocs/op BenchmarkNetHTTPServerGet2ReqPerConn10KClients 868576 14010 ns/op 2826 B/op 28 allocs/op BenchmarkNetHTTPServerGet10ReqPerConn10KClients 1297398 9329 ns/op 2611 B/op 23 allocs/op BenchmarkNetHTTPServerGet100ReqPerConn10KClients 1467963 7902 ns/op 2450 B/op 21 allocs/op ``` -------------------------------- ### Convert net/http ServeMux to fasthttp Router Source: https://github.com/valyala/fasthttp/blob/master/README.md Demonstrates a simple conversion of net/http's ServeMux routing to a custom fasthttp handler function that manually dispatches requests based on the path. ```go // net/http code m := &http.ServeMux{} m.HandleFunc("/foo", fooHandlerFunc) m.HandleFunc("/bar", barHandlerFunc) m.Handle("/baz", bazHandler) http.ListenAndServe(":80", m) ``` ```go // the corresponding fasthttp code m := func(ctx *fasthttp.RequestCtx) { sswitch string(ctx.Path()) { case "/foo": fooHandlerFunc(ctx) case "/bar": barHandlerFunc(ctx) case "/baz": bazHandler.HandlerFunc(ctx) default: ctx.Error("not found", fasthttp.StatusNotFound) } } fasthttp.ListenAndServe(":80", m) ``` -------------------------------- ### Benchmark fasthttp Server (GOMAXPROCS=1) Source: https://github.com/valyala/fasthttp/blob/master/README.md Shows benchmark results for the fasthttp server when GOMAXPROCS is set to 1. This highlights the performance of fasthttp under a single CPU core. ```bash $ GOMAXPROCS=1 go test -bench=kServerGet -benchmem -benchtime=10s cpu: Intel(R) Xeon(R) CPU @ 2.20GHz BenchmarkServerGet1ReqPerConn 4304683 2733 ns/op 0 B/op 0 allocs/op BenchmarkServerGet2ReqPerConn 5685157 2140 ns/op 0 B/op 0 allocs/op BenchmarkServerGet10ReqPerConn 7659729 1550 ns/op 0 B/op 0 allocs/op BenchmarkServerGet10KReqPerConn 8580660 1422 ns/op 0 B/op 0 allocs/op BenchmarkServerGet1ReqPerConn10KClients 4092148 3009 ns/op 0 B/op 0 allocs/op BenchmarkServerGet2ReqPerConn10KClients 5272755 2208 ns/op 0 B/op 0 allocs/op BenchmarkServerGet10ReqPerConn10KClients 7566351 1546 ns/op 0 B/op 0 allocs/op BenchmarkServerGet100ReqPerConn10KClients 8369295 1418 ns/op 0 B/op 0 allocs/op ``` -------------------------------- ### Benchmark net/http Server (GOMAXPROCS=4) Source: https://github.com/valyala/fasthttp/blob/master/README.md Shows benchmark results for the standard Go net/http server when GOMAXPROCS is set to 4. This demonstrates performance with multiple CPU cores utilized. ```bash $ GOMAXPROCS=4 go test -bench=NetHTTPServerGet -benchmem -benchtime=10s cpu: Intel(R) Xeon(R) CPU @ 2.20GHz BenchmarkNetHTTPServerGet1ReqPerConn-4 2670654 4542 ns/op 3263 B/op 36 allocs/op BenchmarkNetHTTPServerGet2ReqPerConn-4 3376021 3559 ns/op 2823 B/op 28 allocs/op BenchmarkNetHTTPServerGet10ReqPerConn-4 4387959 2707 ns/op 2489 B/op 23 allocs/op BenchmarkNetHTTPServerGet10KReqPerConn-4 5412049 2179 ns/op 2386 B/op 21 allocs/op BenchmarkNetHTTPServerGet1ReqPerConn10KClients-4 2226048 5216 ns/op 3289 B/op 36 allocs/op BenchmarkNetHTTPServerGet2ReqPerConn10KClients-4 2989957 3982 ns/op 2839 B/op 28 allocs/op BenchmarkNetHTTPServerGet10ReqPerConn10KClients-4 4383570 2834 ns/op 2514 B/op 23 allocs/op BenchmarkNetHTTPServerGet100ReqPerConn10KClients-4 5315100 2394 ns/op 2419 B/op 21 allocs/op ``` -------------------------------- ### Handling Nil Byte Slices in Go Source: https://github.com/valyala/fasthttp/blob/master/README.md Demonstrates that standard Go functions like append and copy, as well as length checks and iteration, work correctly with nil byte slices, eliminating the need for explicit nil checks. ```go var ( // both buffers are uninitialized dst []byte src []byte ) dst = append(dst, src...) // is legal if dst is nil and/or src is nil copy(dst, src) // is legal if dst is nil and/or src is nil (string(src) == "") // is true if src is nil (len(src) == 0) // is true if src is nil src = src[:0] // works like a charm with nil src // this for loop doesn't panic if src is nil for i, ch := range src { doSomething(i, ch) } ``` -------------------------------- ### Nginx Pipelined Performance Test (8 requests) Source: https://github.com/valyala/fasthttp/blob/master/examples/fileserver/README.md Performance benchmark of Nginx serving static files with 8 pipelined requests using wrk. Tests 10 seconds duration with 4 threads and 16 connections. ```bash $ ./wrk -s pipeline.lua -t 4 -c 16 -d 10 http://localhost:80 -- 8 Running 10s test @ http://localhost:80 4 threads and 16 connections Thread Stats Avg Stdev Max +/- Stdev Latency 1.34ms 2.15ms 30.91ms 92.16% Req/Sec 33.54k 7.36k 108.12k 76.81% 1339908 requests in 10.10s, 1.07GB read Requests/sec: 132705.81 Transfer/sec: 108.58MB ``` -------------------------------- ### Benchmark fasthttp Server (GOMAXPROCS=4) Source: https://github.com/valyala/fasthttp/blob/master/README.md Shows benchmark results for the fasthttp server when GOMAXPROCS is set to 4. This demonstrates fasthttp's performance with multiple CPU cores utilized. ```bash $ GOMAXPROCS=4 go test -bench=kServerGet -benchmem -benchtime=10s cpu: Intel(R) Xeon(R) CPU @ 2.20GHz BenchmarkServerGet1ReqPerConn-4 7797037 1494 ns/op 0 B/op 0 allocs/op BenchmarkServerGet2ReqPerConn-4 13004892 963.7 ns/op 0 B/op 0 allocs/op BenchmarkServerGet10ReqPerConn-4 22479348 522.6 ns/op 0 B/op 0 allocs/op BenchmarkServerGet10KReqPerConn-4 25899390 451.4 ns/op 0 B/op 0 allocs/op BenchmarkServerGet1ReqPerConn10KClients-4 8421531 1469 ns/op 0 B/op 0 allocs/op BenchmarkServerGet2ReqPerConn10KClients-4 13426772 903.7 ns/op 0 B/op 0 allocs/op BenchmarkServerGet10ReqPerConn10KClients-4 21899584 513.5 ns/op 0 B/op 0 allocs/op BenchmarkServerGet100ReqPerConn10KClients-4 25291686 439.4 ns/op 0 B/op 0 allocs/op ``` -------------------------------- ### net/http to fasthttp Conversion Table Source: https://github.com/valyala/fasthttp/blob/master/README.md This table outlines the direct equivalents for common net/http request and response operations when using fasthttp. It serves as a quick reference for developers migrating their code. ```go var ( w http.ResponseWriter r *http.Request ctx *fasthttp.RequestCtx ) ``` ```go r.Body ➜ ctx.PostBody() ``` ```go r.URL.Path ➜ ctx.Path() ``` ```go r.URL ➜ ctx.URI() ``` ```go r.Method ➜ ctx.Method() ``` ```go r.Header ➜ ctx.Request.Header ``` ```go r.Header.Get() ➜ ctx.Request.Header.Peek() ``` ```go r.Host ➜ ctx.Host() ``` ```go r.Form ➜ ctx.QueryArgs() + ctx.PostArgs() ``` ```go r.PostForm ➜ ctx.PostArgs() ``` ```go r.FormValue() ➜ ctx.FormValue() ``` ```go r.FormFile() ➜ ctx.FormFile() ``` ```go r.MultipartForm ➜ ctx.MultipartForm() ``` ```go r.RemoteAddr ➜ ctx.RemoteAddr() ``` ```go r.RequestURI ➜ ctx.RequestURI() ``` ```go r.TLS ➜ ctx.IsTLS() ``` ```go r.Cookie() ➜ ctx.Request.Header.Cookie() ``` ```go r.Referer() ➜ ctx.Referer() ``` ```go r.UserAgent() ➜ ctx.UserAgent() ``` ```go w.Header() ➜ ctx.Response.Header ``` ```go w.Header().Set() ➜ ctx.Response.Header.Set() ``` ```go w.Header().Set("Content-Type") ➜ ctx.SetContentType() ``` ```go w.Header().Set("Set-Cookie") ➜ ctx.Response.Header.SetCookie() ``` ```go w.Write() ➜ ctx.Write(), ctx.SetBody(), ctx.SetBodyStream(), ctx.SetBodyStreamWriter() ``` ```go w.WriteHeader() ➜ ctx.SetStatusCode() ``` ```go w.(http.Hijacker).Hijack() ➜ ctx.Hijack() ``` -------------------------------- ### Benchmark net/http Client (GOMAXPROCS=1) Source: https://github.com/valyala/fasthttp/blob/master/README.md This benchmark measures the performance of the standard Go net/http client when GOMAXPROCS is set to 1. It includes tests for direct requests and end-to-end scenarios with varying TCP connections and in-memory data. ```bash $ GOMAXPROCS=1 go test -bench='HTTPClient(Do|GetEndToEnd)' -benchmem -benchtime=10s cpu: Intel(R) Xeon(R) CPU @ 2.20GHz BenchmarkNetHTTPClientDoFastServer 885637 13883 ns/op 3384 B/op 44 allocs/op BenchmarkNetHTTPClientGetEndToEnd1TCP 203875 55619 ns/op 6296 B/op 70 allocs/op BenchmarkNetHTTPClientGetEndToEnd10TCP 231290 54618 ns/op 6299 B/op 70 allocs/op BenchmarkNetHTTPClientGetEndToEnd100TCP 202879 58278 ns/op 6304 B/op 69 allocs/op BenchmarkNetHTTPClientGetEndToEnd1Inmemory 396764 26878 ns/op 6216 B/op 69 allocs/op BenchmarkNetHTTPClientGetEndToEnd10Inmemory 396422 28373 ns/op 6209 B/op 68 allocs/op BenchmarkNetHTTPClientGetEndToEnd100Inmemory 363976 33101 ns/op 6326 B/op 68 allocs/op BenchmarkNetHTTPClientGetEndToEnd1000Inmemory 208881 51725 ns/op 8298 B/op 84 allocs/op BenchmarkNetHTTPClientGetEndToEndWaitConn1Inmemory 237 50451765 ns/op 7474 B/op 79 allocs/op BenchmarkNetHTTPClientGetEndToEndWaitConn10Inmemory 237 50447244 ns/op 7434 B/op 77 allocs/op BenchmarkNetHTTPClientGetEndToEndWaitConn100Inmemory 238 50067993 ns/op 8639 B/op 82 allocs/op BenchmarkNetHTTPClientGetEndToEndWaitConn1000Inmemory 1366 7324990 ns/op 4064 B/op 44 allocs/op ``` -------------------------------- ### Define and Use fasthttp Request Handlers Source: https://github.com/valyala/fasthttp/blob/master/README.md Demonstrates how to define request handlers as bound struct methods or plain functions and pass them to fasthttp.ListenAndServe. Access struct properties within bound methods. ```go type MyHandler struct { foobar string } // request handler in net/http style, i.e. method bound to MyHandler struct. func (h *MyHandler) HandleFastHTTP(ctx *fasthttp.RequestCtx) { // notice that we may access MyHandler properties here - see h.foobar. fmt.Fprintf(ctx, "Hello, world! Requested path is %q. Foobar is %q", ctx.Path(), h.foobar) } // request handler in fasthttp style, i.e. just plain function. func fastHTTPHandler(ctx *fasthttp.RequestCtx) { fmt.Fprintf(ctx, "Hi there! RequestURI is %q", ctx.RequestURI()) } // pass bound struct method to fasthttp myHandler := &MyHandler{ foobar: "foobar", } fasthttp.ListenAndServe(":8080", myHandler.HandleFastHTTP) // pass plain function to fasthttp fasthttp.ListenAndServe(":8081", fastHTTPHandler) ``` -------------------------------- ### Benchmark net/http Client (GOMAXPROCS=4) Source: https://github.com/valyala/fasthttp/blob/master/README.md This benchmark evaluates the net/http client's performance with GOMAXPROCS set to 4. It tests end-to-end scenarios with varying TCP connections and in-memory data, showing performance improvements over GOMAXPROCS=1. ```bash $ GOMAXPROCS=4 go test -bench='HTTPClient(Do|GetEndToEnd)' -benchmem -benchtime=10s cpu: Intel(R) Xeon(R) CPU @ 2.20GHz BenchmarkNetHTTPClientGetEndToEnd1TCP-4 767133 16175 ns/op 6304 B/op 69 allocs/op BenchmarkNetHTTPClientGetEndToEnd10TCP-4 785198 15276 ns/op 6295 B/op 69 allocs/op BenchmarkNetHTTPClientGetEndToEnd100TCP-4 780464 15605 ns/op 6305 B/op 69 allocs/op BenchmarkNetHTTPClientGetEndToEnd1Inmemory-4 1356932 8772 ns/op 6220 B/op 68 allocs/op BenchmarkNetHTTPClientGetEndToEnd10Inmemory-4 1379245 8726 ns/op 6213 B/op 68 allocs/op BenchmarkNetHTTPClientGetEndToEnd100Inmemory-4 1119213 10294 ns/op 6418 B/op 68 allocs/op BenchmarkNetHTTPClientGetEndToEnd1000Inmemory-4 504194 31010 ns/op 17668 B/op 102 allocs/op ``` -------------------------------- ### In-Process Testing with InmemoryListener Source: https://context7.com/valyala/fasthttp/llms.txt Uses `fasthttputil.InmemoryListener` to create a `net.Listener` that operates entirely in memory, ideal for unit-testing server handlers without binding to actual network ports. It allows creating a client that connects through this in-memory listener. ```go package main_test import ( "fmt" "testing" "github.com/valyala/fasthttp" "github.com/valyala/fasthttp/fasthttputil" ) func TestMyHandler(t *testing.T) { ln := fasthttputil.NewInmemoryListener() defer ln.Close() // Start server in background go func() { err := fasthttp.Serve(ln, func(ctx *fasthttp.RequestCtx) { ctx.SetStatusCode(fasthttp.StatusOK) fmt.Fprintf(ctx, `{"status":"ok"}`) }) if err != nil { t.Logf("server stopped: %v", err) } }() // Create a client that dials through the in-memory listener client := &fasthttp.Client{ Dial: ln.Dial, } statusCode, body, err := client.Get(nil, "http://test/api/ping") if err != nil { t.Fatalf("unexpected error: %v", err) } if statusCode != fasthttp.StatusOK { t.Fatalf("expected 200, got %d", statusCode) } fmt.Println(string(body)) // {"status":"ok"} } ``` -------------------------------- ### Serve Static Files with FSHandler (Path-Prefix) Source: https://context7.com/valyala/fasthttp/llms.txt Creates a static file handler that serves files from a specified root directory, stripping a configurable number of leading path segments from the request URI. Useful for routing different URL prefixes to different file system roots. ```go package main import ( "bytes" "log" "github.com/valyala/fasthttp ) var ( imgPrefix = []byte("/img/") cssPrefix = []byte("/static/css/") imgHandler = fasthttp.FSHandler("/var/www/images", 1) // strip /img/ cssHandler = fasthttp.FSHandler("/var/www/css", 2) // strip /static/css/ filesHandler = fasthttp.FSHandler("/var/www/html", 0) // no strip ) func main() { router := func(ctx *fasthttp.RequestCtx) { p := ctx.Path() switch { case bytes.HasPrefix(p, imgPrefix): imgHandler(ctx) case bytes.HasPrefix(p, cssPrefix): cssHandler(ctx) default: filesHandler(ctx) } } log.Fatal(fasthttp.ListenAndServe(":8080", router)) } ``` -------------------------------- ### Convert net/http Handler to fasthttp Handler Source: https://github.com/valyala/fasthttp/blob/master/README.md Shows the conversion of a net/http style request handler, which uses a switch statement on the URL path, to its fasthttp equivalent using ctx.Path(). ```go // net/http request handler requestHandler := func(w http.ResponseWriter, r *http.Request) { switch r.URL.Path { case "/foo": fooHandler(w, r) case "/bar": barHandler(w, r) default: http.Error(w, "Unsupported path", http.StatusNotFound) } } ``` ```go // the corresponding fasthttp request handler requestHandler := func(ctx *fasthttp.RequestCtx) { sswitch string(ctx.Path()) { case "/foo": fooHandler(ctx) case "/bar": barHandler(ctx) default: ctx.Error("Unsupported path", fasthttp.StatusNotFound) } } ``` -------------------------------- ### Benchmark fasthttp Client (GOMAXPROCS=4) Source: https://github.com/valyala/fasthttp/blob/master/README.md This benchmark measures the fasthttp client's performance with GOMAXPROCS set to 4. It includes end-to-end tests with varying TCP connections and in-memory data, demonstrating substantial performance gains and reduced allocations compared to net/http. ```bash $ GOMAXPROCS=4 go test -bench='kClient(Do|GetEndToEnd)' -benchmem -benchtime=10s cpu: Intel(R) Xeon(R) CPU @ 2.20GHz BenchmarkClientGetEndToEnd1TCP-4 1474552 8143 ns/op 0 B/op 0 allocs/op BenchmarkClientGetEndToEnd10TCP-4 1710270 7186 ns/op 0 B/op 0 allocs/op BenchmarkClientGetEndToEnd100TCP-4 1701672 6892 ns/op 4 B/op 0 allocs/op BenchmarkClientGetEndToEnd1Inmemory-4 6797713 1590 ns/op 0 B/op 0 allocs/op BenchmarkClientGetEndToEnd10Inmemory-4 6663642 1782 ns/op 0 B/op 0 allocs/op ``` -------------------------------- ### Server: Response Compression with CompressHandler Source: https://context7.com/valyala/fasthttp/llms.txt Automatically compresses responses using gzip, brotli, or zstd based on the client's Accept-Encoding header. No modifications are needed for the wrapped handler. ```go package main import ( "fmt" "log" "github.com/valyala/fasthttp" ) func main() { handler := func(ctx *fasthttp.RequestCtx) { // Response body will be automatically compressed if the // client sends Accept-Encoding: gzip (or br, zstd). ctx.SetContentType("application/json") fmt.Fprintf(ctx, `{"message":"hello","data":%s}`, largeJSONPayload()) } log.Fatal(fasthttp.ListenAndServe(":8080", fasthttp.CompressHandler(handler))) } func largeJSONPayload() string { return "..." // your actual payload } ``` -------------------------------- ### LBClient: Load Balancer with Health Checks Source: https://context7.com/valyala/fasthttp/llms.txt LBClient distributes requests across multiple backends using a least-loaded algorithm and automatically penalizes unhealthy backends. Configure health checks to ensure reliability. ```go package main import ( "fmt" "log" "github.com/valyala/fasthttp" ) func main() { backends := []string{ "backend1.internal:8080", "backend2.internal:8080", "backend3.internal:8080", } var lb fasthttp.LBClient for _, addr := range backends { lb.Clients = append(lb.Clients, &fasthttp.HostClient{Addr: addr}) } lb.HealthCheck = func(req *fasthttp.Request, resp *fasthttp.Response, err error) bool { return err == nil && resp.StatusCode() < 500 } req := fasthttp.AcquireRequest() resp := fasthttp.AcquireResponse() defer fasthttp.ReleaseRequest(req) defer fasthttp.ReleaseResponse(resp) for i := range 20 { req.SetRequestURI(fmt.Sprintf("http://backend/api/item/%d", i)) if err := lb.Do(req, resp); err != nil { log.Printf("lb error: %v", err) continue } fmt.Printf("item %d → status %d\n", i, resp.StatusCode()) } } ``` -------------------------------- ### Benchmark fasthttp Client (GOMAXPROCS=1) Source: https://github.com/valyala/fasthttp/blob/master/README.md This benchmark measures the performance of the fasthttp client when GOMAXPROCS is set to 1. It includes end-to-end tests with varying TCP connections and in-memory data, highlighting its efficiency with zero allocations in many cases. ```bash $ GOMAXPROCS=1 go test -bench='kClient(Do|GetEndToEnd)' -benchmem -benchtime=10s cpu: Intel(R) Xeon(R) CPU @ 2.20GHz BenchmarkClientGetEndToEnd1TCP 406376 26558 ns/op 0 B/op 0 allocs/op BenchmarkClientGetEndToEnd10TCP 517425 23595 ns/op 0 B/op 0 allocs/op BenchmarkClientGetEndToEnd100TCP 474800 25153 ns/op 3 B/op 0 allocs/op BenchmarkClientGetEndToEnd1Inmemory 2563800 4827 ns/op 0 B/op 0 allocs/op BenchmarkClientGetEndToEnd10Inmemory 2460135 4805 ns/op 0 B/op 0 allocs/op BenchmarkClientGetEndToEnd100Inmemory 2520543 4846 ns/op 0 B/op 0 allocs/op BenchmarkClientGetEndToEnd1000Inmemory 2437015 4914 ns/op 2 B/op 0 allocs/op BenchmarkClientGetEndToEnd10KInmemory 2481050 5049 ns/op 9 B/op 0 allocs/op ``` -------------------------------- ### Extending Byte Slice Capacity Source: https://github.com/valyala/fasthttp/blob/master/README.md Illustrates how to create a new slice that references the same underlying array but with a larger length, up to the original capacity. ```go buf := make([]byte, 100) a := buf[:10] // len(a) == 10, cap(a) == 100. b := a[:100] // is valid, since cap(a) == 100. ``` -------------------------------- ### Cookie Management with Fasthttp Source: https://context7.com/valyala/fasthttp/llms.txt Demonstrates reading, writing, and deleting cookies using fasthttp's pooled cookie objects for efficiency. Supports advanced cookie attributes like SameSite, Secure, HttpOnly, and Partitioned. ```go func cookieExample(ctx *fasthttp.RequestCtx) { // Read request cookie sessionVal := ctx.Request.Header.Cookie("session") fmt.Printf("session cookie: %s\n", sessionVal) // Write a response cookie using pool c := fasthttp.AcquireCookie() defer fasthttp.ReleaseCookie(c) c.SetKey("auth_token") c.SetValue("v2.eyJhbGci...") c.SetDomain("example.com") c.SetPath("/") c.SetMaxAge(86400) // 1 day c.SetHTTPOnly(true) c.SetSecure(true) c.SetSameSite(fasthttp.CookieSameSiteStrictMode) // c.SetPartitioned(true) // CHIPS / partitioned cookies ctx.Response.Header.SetCookie(c) // Delete a cookie del := fasthttp.AcquireCookie() defer fasthttp.ReleaseCookie(del) del.SetKey("old_token") del.SetExpire(fasthttp.CookieExpireDelete) // sets expiry to past date ctx.Response.Header.SetCookie(del) fmt.Fprintf(ctx, "cookies set") } ```