Databases & Data Access Best Practices
Context deadlines, pool sizing, and observability for queries.
Search across all documentation pages
Context deadlines, pool sizing, and observability for queries.
Apply these rules in code review, service templates, and runbooks so every handler, repository, and worker treats SQL as a shared resource with clear ownership and cancellation boundaries.
Query without Context) where possible.*sql.DB pool per DSN per process, wired in main. Avoid init() opening production databases.MaxOpenConns from capacity math (db_max / replicas). Prevents too many connections incidents.PingContext at startup with boot timeout. Fail deploy before traffic hits bad DSNs.db.Stats() to metrics (WaitCount, InUse, Idle). Alert on pool wait growth.*Context database methods on every request-scoped path. Ban Query/Exec without Context in handlers.ctx, not Background(). Preserves client cancel.statement_timeout when drivers lag. Defense in depth for runaway queries.ctx.Err() when cancel ends a query. Map to correct HTTP/gRPC status at the edge.sql.ErrNoRows to domain ErrNotFound sentinels. Do not leak driver errors to API clients.repo.GetOrder). Avoid logging full SQL with secrets in prod.rows and stmt with defer in repositories. Leaks starve the pool.defer tx.Rollback() immediately after BeginTx. Commit only on success path.down or documented irreversibility in migration review. CI applies up on ephemeral DB.*sql.DB pool. ORM does not remove ops work.Preload review on hot paths.ctx into Redis/NATS/Kafka handlers. Shutdown drains workers cooperatively.-race on code that shares repos across goroutines. Catches unsafe shared state above SQL.Tier A Context SQL methods, placeholder-only SQL, and migration CI apply should block merge.
Pool tuning tables and cache TTL policy are review-enforced.
Extract SQL to a storage package behind an interface, inject from main, keep handler signatures unchanged one PR at a time.
Yes when you route read-only repos to a follower DSN.
Document eventual consistency in API contracts.
Pass reconcile ctx into repository calls; do not store *sql.DB on the reconciler struct without injection patterns from main.
Enable linters that catch context misuse and error handling; custom review rules for SQL in handlers.
Edge APIs use tighter DB timeouts; batch workers use longer budgets but still propagate shutdown ctx.
Write differences in the timeout table.
Require WithContext, inspect generated SQL in staging, ban global session without request ctx.
Query p95/p99, error rate by operation, migration version lag, cache hit ratio, consumer lag.
Context and SQL hygiene yes; pool sizing and ORM choices may differ on constrained targets.
Verify board targets at build.
Database rules extend context Package Best Practices with storage-specific pool and migration policy.
Stack versions: This page was written for Go 1.26.x (Green Tea GC default, go fix modernizers - verify patch at build), chi (latest - verify at build), gin (latest - verify at build), echo (latest - verify at build), google.golang.org/grpc (latest - verify at build), sigs.k8s.io/controller-runtime (latest - verify at build), kubebuilder (latest - verify at build), tinygo (latest - verify board targets at build), wazero (latest - verify at build), and golangci-lint (latest - verify linter set at build).
Reviewed by Chris St. John·Last updated Jul 18, 2026