Performance Benchmarking
Relevant source files
The following files were used as context for generating this wiki page:
Performance benchmarking in kamal-proxy (specifically the dash-proxy fork) focuses on measuring the efficiency and overhead of critical hot paths, such as request routing, load balancing, and response compression. The goal is to establish a performance baseline against the upstream main branch and ensure that new features do not introduce significant latency or allocation regressions.
The project utilizes standard Go testing tools and specialized slash commands to perform these measurements. Developers are encouraged to use the /perf command to baseline changes in a worktree via make bench on identified hot paths.
Sources: CLAUDE.md:144, ROADMAP.md:10-15
Benchmarking Architecture
The benchmarking infrastructure is integrated into the Go test suite, targeting Layer 1 (Server) components like the LoadBalancer and CompressionMiddleware.
Hot Path Analysis
The primary areas targeted for performance analysis include:
- Target Selection: Measuring the latency of the load balancer in choosing a target for a request.
- Path Resolution: Evaluating the speed of longest-prefix matching for path-based overrides.
- Response Compression: Assessing the overhead of different encoding algorithms (Gzip, Brotli, Zstd).
The following diagram illustrates the flow of a performance benchmark execution within the system:
A flowchart showing the standard Go benchmark loop applied to proxy components.
Sources: internal/server/load_balancer_test.go:217-227, internal/server/compression_middleware_test.go:217-248
Component Benchmarks
Load Balancer Target Selection
The BenchmarkLoadBalancer_ClaimTarget measures the overhead every request pays before being forwarded. This benchmark isolates the target selection logic from the actual network I/O of backends.
func BenchmarkLoadBalancer_ClaimTarget(b *testing.B) {
lb := benchmarkLoadBalancer(b)
req := httptest.NewRequest(http.MethodGet, "/", nil)
b.ReportAllocs()
for b.Loop() {
target, claimed, _, err := lb.claimTarget(req)
if err != nil {
b.Fatal(err)
}
target.endInflightRequest(claimed)
}
}
Sources: internal/server/load_balancer_test.go:217-227
Path Timeout Resolution
The BenchmarkResolvePathTimeout evaluates the efficiency of the ResolvePathTimeout function. It compares scenarios with no overrides against scenarios with multiple registered path prefixes to ensure the search remains performant.
Sources: internal/server/path_timeouts_test.go:119-136
Compression Overhead
Benchmarks are provided for each supported content encoding to measure the cost of real-time compression compared to passthrough.
| Encoding | Benchmark Target | Description |
|---|---|---|
| Gzip | BenchmarkCompressionMiddleware/gzip | Measures Gzip compression overhead. |
| Brotli | BenchmarkCompressionMiddleware/br | Measures Brotli compression overhead. |
| Zstd | BenchmarkCompressionMiddleware/zstd | Measures Zstd compression overhead. |
| None | BenchmarkCompressionMiddleware/passthrough | Baseline measurement with no compression. |
Sources: internal/server/compression_middleware_test.go:217-248
Performance Tooling & Commands
The project defines specific conventions for running and interpreting performance data.
Performance Commands
Developers interact with benchmarking through the following mechanisms:
make bench: The standard command for executing benchmarks./perfSlash Command: An LLM-integrated command used to automate baselining against themainbranch.internal/cmd/cache_stats.go: Provides thestatscommand to report on cache performance, including evictions of fresh vs. stale entries, which indicates if the memory budget is sufficient.
A sequence diagram showing how performance-related statistics are retrieved from the running proxy.
Sources: CLAUDE.md:144, internal/cmd/cache_stats.go:37-45, ROADMAP.md:112-120
Cache Performance Metrics
The cache stats command specifically surfaces metrics that impact system performance:
- Evicted Fresh: Number of entries removed before expiration (indicates undersized cache).
- Evicted Stale: Number of entries removed after expiration.
- Oversized: Count of responses refused because they exceeded
--cache-max-body.
Sources: internal/cmd/cache_stats.go:68-76
Summary
Performance benchmarking is a core part of the kamal-proxy development workflow. By targeting high-frequency operations like load balancing and compression via Go's built-in benchmarking toolset and providing observability through the cache stats CLI, the project ensures that its expanded feature set (TLS on-demand, caching, etc.) remains efficient for production traffic.