Files
go-kata/02-performance-allocation/12-sync-pool-buffer-middleware

Kata 12: The sync.Pool Buffer Middleware

Target Idioms: sync.Pool, Avoiding GC Pressure, bytes.Buffer Reset, Benchmarks (-benchmem)
Difficulty: 🔴 Advanced

🧠 The "Why"

In Go, performance regressions often come from allocation/GC churn, not “slow CPU”. People use sync.Pool incorrectly:

  • pooling long-lived objects (wrong),
  • forgetting to reset buffers (data leak),
  • storing huge buffers back into the pool (memory bloat).

This kata is about safe pooling for high-throughput handlers.

🎯 The Scenario

Youre writing an HTTP middleware that:

  • reads up to 16KB of request body for audit logging
  • must not allocate per-request in the hot path

🛠 The Challenge

Implement a middleware:

  • func AuditBody(max int, next http.Handler) http.Handler

1. Functional Requirements

  • Read up to max bytes of request body (do not consume beyond max).
  • Log the captured bytes with slog fields.
  • Pass the request downstream intact (body still readable).

2. The "Idiomatic" Constraints (Pass/Fail Criteria)

  • Must use sync.Pool to reuse buffers.
  • Must Reset()/clear buffers before putting back.
  • Must bound memory: never keep buffers larger than max in the pool.
  • Provide a benchmark showing reduced allocations (go test -bench . -benchmem).

🧪 Self-Correction (Test Yourself)

  • If a request leaks previous request content: you failed (no reset).
  • If allocations are ~O(requests): you failed pooling.
  • If buffers grow unbounded and stay in pool: you failed memory bounds.

📚 Resources