Database timeouts
Database calls should usually be context-bound, cancellable, and aligned with request or job deadlines.
Canonical guidance
- pass context into database operations
- derive deadlines from request or job scope, not arbitrary scattered constants
- cancel long-running work when the caller no longer needs it
- keep timeout decisions near operational boundaries
Use when
- HTTP handlers calling a database
- background jobs with deadlines
- queue workers
Avoid
- database calls with no cancellation path
- timeout logic duplicated inconsistently across layers
- detached queries that outlive the request meaningfully
Preferred pattern
ctx, cancel := context.WithTimeout(ctx, 2*time.Second)
defer cancel()
row := db.QueryRowContext(ctx, q, id)
Anti-pattern
- using
db.QueryRowordb.Execwithout context in request-scoped paths
Explanation: This anti-pattern is tempting because context-free calls are shorter, but they let slow queries outlive the request or job that needed them.
Why
- database latency is often one of the dominant external costs in Go services
- cancellation and deadline propagation reduce tail-latency damage and leaked work
Sources
- Go Concurrency Patterns: Context - Sameer Ajmani
- database/sql package - Go Team