package main
import (
"context"
"net/http"
"time"
)
func newServer(handler http.Handler) *http.Server {
return &http.Server{
Addr: ":8080",
Handler: handler,
ReadHeaderTimeout: 2 * time.Second,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
IdleTimeout: 60 * time.Second,
BaseContext: func(net.Listener) context.Context {
return context.Background()
},
}
}
The default http.Server will happily keep connections open longer than you intended, which is how you end up with “mysterious” goroutine growth during partial outages. I set ReadHeaderTimeout to protect against slowloris-style attacks, keep IdleTimeout tight to reclaim keep-alive sockets, and set ReadTimeout/WriteTimeout as a coarse guardrail for handlers that forget to enforce per-request deadlines with context.WithTimeout. I also use a custom BaseContext so every connection inherits a root context that can be canceled on shutdown. The win is operational: when something goes wrong, connections drain predictably and you don’t end up with thousands of half-open clients pinning memory. This is a small config block, but it’s a big reliability upgrade.
Related snips
package api
import (
"net/http"
"runtime/debug"
)
Expose build metadata for debugging deploys
export interface RetryOptions {
retries: number;
baseMs: number;
maxMs: number;
signal?: AbortSignal;
onRetry?: (attempt: number, delay: number, err: unknown) => void;
Exponential backoff with jitter for retries
package dbutil
import (
"context"
"github.com/jackc/pgconn"
Retry Postgres serialization failures with bounded attempts
package files
import (
"context"
"time"
Presigned S3 upload URLs (AWS SDK v2)
package deps
import (
"net"
"net/http"
"time"
HTTP client tuned for production: timeouts, transport, and connection reuse
package api
import (
"io"
"net/http"
"os"
Safe multipart uploads using temp files (bounded memory)
Share this code
Here's the card — post it anywhere.