A follow-up to the timeout middleware post. The same file upload endpoint that needed a longer timeout also needed a larger request body limit, and the standard http.MaxBytesReader fails the same way – an inner middleware can shrink the limit set by an outer one, but never extend it. The fix is the same one the timeout post landed on, one layer down: share a single mutable limiter through the…
Sometimes we need concurrent processing that preserves input order while streaming. The standard worker pool pattern shuffles the results. We want ordering with bounded memory, backpressure, and minimal allocations. I implemented and benchmarked three approaches – ReplyTo channels, sync.Cond turn-taking, and a permission-passing chain – the winner adds at most 500ns overhead, and sometimes even…
After a decade of Go backends, I wanted to try something different – so I built a daily number-picking game with vintage UI and game theory elements. A humble introduction to my side project "How Low Can You Go?" (Tags: #side-project #frontend)
I needed a longer timeout for a single file upload endpoint, and the obvious fix – wrapping the route in another timeout middleware – silently did nothing. In Go, a child context can never extend its parent's deadline, so I built a chainable timeout middleware that reliably handles per-route overrides. (Tags: #go)
Imagine updating a user's last_active_at timestamp on every HTTP request – thousands of tiny UPDATEs per second, perfect for batching, except each call only sees one user ID at a time. Here's a transparent batching pattern built on ReplyTo channels, where callers still make a simple blocking function call that respects context and returns errors, while the database sees clean batches. (Tags: #go…
File upload handlers often stream the request body straight to S3, so there's nothing buffered to validate. Here's a small io.Reader wrapper that sniffs magic bytes with http.DetectContentType as the data flows through, and fails the upload with your own error when the content type doesn't pass validation. (Tags: #go #quick-tip)
Concurrent one-off scripts need progress visibility, but Grafana is overkill and a pile of atomic counters with fmt.Printf is barely readable. So I built dspc, a dead simple progress counter for Go – named counters created on first use, in-place terminal output that doesn't clobber your logs, and a lock-free copy-on-write map underneath that's at least 2x faster than a mutex under contention.…
I was cleaning up a large GCS bucket when I discovered that listing the files, not deleting them, was the real bottleneck – list APIs are paginated and strictly sequential, 1000 files per request. The fix is to partition the bucket into lexicographic ranges and stream all of them concurrently. The same scan that took hours completes in minutes, at practically the same API cost, and the trick works…