Go Production Best Practices
Go's simplicity makes it easy to write code. Writing production-grade Go requires discipline. Here are the practices that matter.
Project Structure
Follow the standard layout:
cmd/
server/main.go # Entry points
internal/
handler/ # HTTP handlers
service/ # Business logic
repository/ # Data access
pkg/
middleware/ # Reusable middlewareThe internal/ directory prevents external packages from importing your business logic.
Context Propagation
Pass context.Context as the first parameter to every function that does I/O:
func (s *OrderService) CreateOrder(ctx context.Context, req CreateOrderRequest) (*Order, error) {
if err := s.validate(req); err != nil {
return nil, fmt.Errorf("validate order: %w", err)
}
return s.repo.Insert(ctx, order)
}This enables request cancellation, timeouts, and tracing to propagate through your entire call chain.
Concurrency Safety
- Use channels for communication, mutexes for state
- Never start goroutines without a shutdown mechanism
- Use `errgroup` for coordinated goroutine management
import "golang.org/x/sync/errgroup"
g, ctx := errgroup.WithContext(ctx)
g.Go(func() error {
return fetchInventory(ctx)
})
g.Go(func() error {
return fetchPricing(ctx)
})
if err := g.Wait(); err != nil {
return fmt.Errorf("parallel fetch: %w", err)
}Dependency Injection
Avoid global variables. Inject dependencies through constructors:
type Server struct {
userService *UserService
orderService *OrderService
logger *slog.Logger
}
func NewServer(us *UserService, os *OrderService, l *slog.Logger) *Server {
return &Server{userService: us, orderService: os, logger: l}
}Production Essentials
- Structured logging with
slogorzerolog - Graceful shutdown handling SIGTERM/SIGINT
- Health check endpoints that verify dependencies
- Rate limiting to protect against abuse
- Error tracking with Bugsly to catch panics and unexpected errors before your users report them
These patterns keep Go applications maintainable and reliable as they grow.
Try Bugsly Free
AI-powered error tracking that explains your bugs. Set up in 2 minutes, free forever for small projects.
Get Started FreeRelated Articles
Error Tracking Best Practices for Production Apps
Learn the best practices for setting up and managing error tracking in production, from alert configuration to noise reduction.
Read moreVue.js Production Best Practices
Essential Vue.js best practices for production apps covering state management, component patterns, performance optimization, and error handling.
Read moreDjango Performance Monitoring Best Practices
Master Django performance monitoring with best practices for query optimization, middleware profiling, caching strategies, and real-time alerting.
Read moreExpress Error Handling Patterns That Scale
Master Express.js error handling with patterns for async errors, custom error classes, centralized handlers, and operational error recovery.
Read more