All PatternsCreational
Singleton
Ensures a class has only one instance and provides global access to it.
Configuration managementLoggingDatabase connections
Understanding Singleton
The Singleton pattern ensures only one instance of a type exists throughout the entire application lifetime and provides a global point of access to it. In Go, the standard approach uses sync.Once to guarantee thread-safe, lazy initialization — the instance is created only when first requested and never again, even under heavy concurrent access from multiple goroutines. This makes it ideal for shared resources like database connections, configuration managers, or logger instances where having multiple copies would be wasteful or cause conflicts.
Key Concepts
- •Lazy initialization — the instance is created on first access, not at program startup, saving resources if it's never needed
- •Thread safety with
sync.Once— guarantees the initializer runs exactly once, even with thousands of concurrent goroutines calling it simultaneously - •Global access — a package-level function (e.g.
GetInstance()) returns the same pointer every time, acting as the single entry point - •Fast path optimization — after initialization,
sync.Onceuses an atomic read to skip locking entirely, making subsequent calls nearly zero-cost
When to Use
✅ Use when
- • You need exactly one shared resource (DB pool, config, logger)
- • Creating multiple instances would cause bugs or resource waste
- • The instance needs lazy initialization in a concurrent environment
- • You want to replace global variables with controlled access
⚠️ Avoid when
- • You can pass dependencies explicitly via function parameters
- • The object holds mutable state that makes testing difficult
- • You're using it just for convenience rather than necessity
Structure
Goroutine 1
Goroutine 2
Goroutine N
↓ GetInstance()
sync.Once guard
↓
*Singleton (single instance)
How It Works
G1
Goroutine 1G2
Goroutine 2sync.Once
done0
mutexunlocked
instancenil
GetInstance()
G1 calls GetInstance()
1
First Request
Goroutine 1 calls GetInstance().
1 / 8
Basic Implementation
The simplest thread-safe singleton in Go:
main.go
Loading editor...
Real-World Example: Database Connection
100 goroutines all get the same database connection:
main.go
Loading editor...