Day 59 — Benchmark the Full L4 Stack
Learning Objectives
- Write a load test in pure Go — measure RPS, latency percentiles
- Know the numbers: what throughput can your proxy handle?
- Use the results to set SLOs and identify bottlenecks
Exercise: Load Test the L4 Load Balancer
package main
import (
"fmt"
"net"
"sort"
"sync"
"sync/atomic"
"time"
)
type LoadTestResult struct {
TotalRequests int64
Errors int64
Duration time.Duration
Latencies []time.Duration
}
func (r *LoadTestResult) Print() {
rps := float64(r.TotalRequests) / r.Duration.Seconds()
errorRate := float64(r.Errors) / float64(r.TotalRequests) * 100
sort.Slice(r.Latencies, func(i, j int) bool { return r.Latencies[i] < r.Latencies[j] })
pct := func(p float64) time.Duration {
if len(r.Latencies) == 0 { return 0 }
idx := int(p / 100 * float64(len(r.Latencies)))
if idx >= len(r.Latencies) { idx = len(r.Latencies) - 1 }
return r.Latencies[idx]
}
fmt.Printf("\n=== Load Test Results ===\n")
fmt.Printf("Duration: %v\n", r.Duration.Round(time.Millisecond))
fmt.Printf("Total: %d requests\n", r.TotalRequests)
fmt.Printf("RPS: %.0f req/s\n", rps)
fmt.Printf("Error rate: %.2f%% (%d errors)\n", errorRate, r.Errors)
fmt.Printf("Latency p50: %v\n", pct(50))
fmt.Printf("Latency p95: %v\n", pct(95))
fmt.Printf("Latency p99: %v\n", pct(99))
fmt.Printf("Latency max: %v\n", pct(100))
}
func runLoadTest(proxyAddr string, concurrency, requestsPerClient int) LoadTestResult {
var (
totalRequests atomic.Int64
errors atomic.Int64
mu sync.Mutex
allLatencies []time.Duration
)
start := time.Now()
var wg sync.WaitGroup
for i := 0; i < concurrency; i++ {
wg.Add(1)
go func() {
defer wg.Done()
var localLatencies []time.Duration
for j := 0; j < requestsPerClient; j++ {
t := time.Now()
conn, err := net.DialTimeout("tcp", proxyAddr, 2*time.Second)
if err != nil {
errors.Add(1)
continue
}
msg := []byte("ping\n")
conn.Write(msg)
buf := make([]byte, 16)
conn.SetReadDeadline(time.Now().Add(2 * time.Second))
conn.Read(buf)
conn.Close()
localLatencies = append(localLatencies, time.Since(t))
totalRequests.Add(1)
}
mu.Lock()
allLatencies = append(allLatencies, localLatencies...)
mu.Unlock()
}()
}
wg.Wait()
return LoadTestResult{
TotalRequests: totalRequests.Load(),
Errors: errors.Load(),
Duration: time.Since(start),
Latencies: allLatencies,
}
}
func main() {
fmt.Println("Load testing L4 proxy at :8080")
fmt.Println("(Start the proxy from Week 5/7 first)")
fmt.Println("Concurrency: 100, 100 requests each = 10,000 total")
result := runLoadTest(":8080", 100, 100)
result.Print()
}
Expected results on a developer machine:
Duration: ~2-5 seconds
RPS: 2,000-5,000 req/s
Latency p50: ~1ms
Latency p95: ~5ms
Latency p99: ~20ms
Error rate: 0%
Real-World Context
"Our proxy adds 2ms p99 latency" is a concrete, defensible number. Without benchmarks, every performance discussion is guessing. Run this load test before and after adding WAF middleware in Week 10 — that gives you the exact overhead of security inspection.