Skip to content

Table of Contents

✅ Production Go Best-Practices Checklist

A running checklist to self-assess any Go service before calling it "done." Use it on every project from Month 4 onward.

Code & idioms

  • gofmt/goimports clean; go vet ./... passes; golangci-lint run passes.
  • Errors wrapped with %w; inspected with errors.Is/As; no ignored errors.
  • Small, consumer-defined interfaces; "accept interfaces, return structs."
  • context.Context is the first param, propagated, never stored in structs.
  • No panic in library/handler paths; recover only at goroutine boundaries.
  • Zero values usable; no unnecessary pointers; consistent receiver types.

Concurrency

  • go test -race is clean.
  • Every goroutine has a guaranteed exit path (no leaks).
  • Cancellation/timeouts via context; bounded parallelism where needed.
  • Shared state protected (mutex/atomic) or avoided via channels.

Testing

  • Table-driven unit tests; meaningful coverage (not vanity 100%).
  • Integration tests (testcontainers) for DB/external deps.
  • Benchmarks for hot paths; at least one fuzz target where parsing input.
  • Tests are deterministic and parallel-safe (t.Parallel() where valid).

API design

  • Correct HTTP status codes; consistent JSON error shape.
  • Input validation on every external boundary.
  • Pagination/filtering for list endpoints; rate limiting.
  • Versioning strategy; OpenAPI/proto documented.

Data & persistence

  • Parameterized queries (no string-built SQL).
  • Migrations versioned (golang-migrate); rollbacks tested.
  • Connection pool tuned; transactions where atomicity required.
  • Indexes for query patterns; N+1 queries avoided.

Security

  • govulncheck and gosec clean.
  • Secrets via env/secret manager, never committed or logged.
  • AuthN + AuthZ enforced; least privilege; TLS in transit.
  • Dependencies pinned; Dependabot enabled.

Observability & ops

  • Structured logging (slog) with request/correlation IDs; no secret leakage.
  • Prometheus metrics (RED/USE); OpenTelemetry traces.
  • /healthz + /readyz; graceful shutdown on SIGINT/SIGTERM.
  • 12-factor config (env-driven); sane timeouts everywhere.

Build & deploy

  • Multi-stage Docker, CGO_ENABLED=0, minimal base image, -ldflags="-s -w".
  • CI: build + test + lint + scan on every PR; CD on main/tag.
  • Reproducible builds; version/commit embedded via -ldflags.

Docs

  • README: problem, architecture diagram, run instructions, screenshots.
  • ADRs for significant decisions.
  • "Lessons learned" + "future improvements" captured.

README