FastHTTP: Building High-Performance HTTP Servers

FastHTTP: Building High-Performance HTTP Servers

Buffer HTTP Responses

Use bufio to read multiple requests at once, then write multiple responses together after processing.

This cuts down on received system calls and boosts throughput.

The downside: slow requests will drag down other requests in the same batch. This hurts latency across the whole system.

One gotcha comes from the prefetch behavior of buffered readers. You need to create the buffered reader outside your main for loop. Otherwise you’ll drop data between reads.

Parse HTTP Headers Later

Parse headers lazily. Don’t do work unless you actually need the values.

This saves CPU cycles on requests that don’t use certain headers.

Use Slices Instead of Maps for Key-Value Pairs

Slices beat maps for small key-value operations. They cut memory allocations dramatically compared to maps. You can get close to zero allocations through lazy memory reuse.

When you need to look up values, convert the []byte key to string and compare it against the target key. This works better than maps for header and cookie mappings because those usually have few keys.

Slices also keep entries in original order.

The downsides:

  • Slice lookups are O(N) instead of O(1) like maps
  • Large keys can cause memory fragmentation. The slice allocates big chunks but only uses parts of them. Over time this wastes memory.

Reuse RequestCtx Objects

Get objects from a pool. Reset them before use. Return them to the pool after use.

This still causes some memory fragmentation, but much less than creating new objects each time.

Cache DNS Lookups

Cache hostname-to-IP mappings. This cuts DNS resolution time.

The catch: it breaks when DNS changes often. Like in Kubernetes when pods restart. Cached IPs point to old machines instead of current ones after rescheduling.