A Go library that provides process-local monotonic timestamps with accurate initialization. The library fetches the initial time from NTP servers (or system clock) at startup, then uses Go's built-in monotonic clock to ensure consistent, always-increasing timestamps throughout the application's lifecycle.
This library solves a specific problem: ensuring monotonic timestamp ordering within a process while starting with accurate wall-clock time.
- β Monotonic: Timestamps always increase, never go backwards
- β° Accurate Start: Initial time synchronized with NTP servers
- π No Drift: Uses monotonic clock, immune to system clock adjustments
- π High Performance: No network calls after initialization
- π― Process-Scoped: Consistent ordering within application lifecycle
- β Not wall-clock accurate over long periods (no re-synchronization)
- β Process-local only (not synchronized across different processes)
- β Single initialization (accuracy locked at startup)
- β Process-local monotonic timestamps based on Go's built-in monotonic clock
- π NTP initialization from configurable servers for accurate startup time
- π Automatic fallback to system time if NTP servers are unreachable
- π§ Environment-based configuration for NTP server selection
- ποΈ Zero overhead after initialization - no background tasks or network calls
- β‘ Thread-safe timestamp generation
- Event ordering within a microservice or application
- Rate limiting with consistent time progression
- Metrics collection where monotonic progression matters
- Request tracing with guaranteed timestamp ordering
- Database operations requiring consistent time-based sorting
- Avoiding issues with system clock adjustments (NTP corrections, leap seconds)
- Cross-process synchronization (each process has its own timeline)
- Long-running services requiring wall-clock accuracy over days/weeks
- Time-sensitive calculations that need real-time precision
- Distributed systems where processes need synchronized timestamps
- Financial systems requiring exact wall-clock time
- Need cross-process sync? β Use external time service (Redis, database)
- Need wall-clock accuracy? β Use
time.Now()with periodic NTP sync - Need distributed sync? β Consider logical clocks (Lamport, Vector clocks)
go get github.com/fgrzl/timestampGuides: docs/ β overview, getting started
package main
import (
"fmt"
"time"
"github.com/fgrzl/timestamp"
)
func main() {
// Get timestamps - guaranteed to be monotonic
ts1 := timestamp.GetTimestamp()
fmt.Println("Initial Timestamp:", ts1)
time.Sleep(100 * time.Millisecond)
ts2 := timestamp.GetTimestamp()
fmt.Println("Later Timestamp:", ts2)
// This will ALWAYS be true (monotonic guarantee)
if ts2 > ts1 {
fmt.Println("β
Monotonic behavior confirmed")
fmt.Printf("Elapsed: %d milliseconds\n", ts2-ts1)
}
}type Event struct {
ID string `json:"id"`
Timestamp int64 `json:"timestamp"`
Message string `json:"message"`
}
func logEvent(message string) Event {
return Event{
ID: generateID(),
Timestamp: timestamp.GetTimestamp(), // Always increasing
Message: message,
}
}type RateLimiter struct {
lastRequest int64
minInterval int64 // milliseconds
}
func (rl *RateLimiter) Allow() bool {
now := timestamp.GetTimestamp()
if now-rl.lastRequest >= rl.minInterval {
rl.lastRequest = now
return true
}
return false
}func measureOperation() {
start := timestamp.GetTimestamp()
// Your operation here
performWork()
end := timestamp.GetTimestamp()
duration := end - start
fmt.Printf("Operation took %d milliseconds\n", duration)
}Control the initial time source using the FGRZL_TIME_SERVER environment variable:
| Value | Behavior | Use Case |
|---|---|---|
system |
Use system clock directly | Testing, offline environments |
default or empty |
Try multiple NTP servers | Production (recommended) |
| Custom server | Use specific NTP server | Corporate networks, specific requirements |
# Use system time (fastest startup, may be inaccurate)
export FGRZL_TIME_SERVER="system"
# Use default NTP servers (recommended for production)
export FGRZL_TIME_SERVER="default"
# OR simply don't set the variable
# Use specific NTP server
export FGRZL_TIME_SERVER="time.cloudflare.com:123"
export FGRZL_TIME_SERVER="pool.ntp.org:123"
export FGRZL_TIME_SERVER="time.nist.gov:123"When using default mode, the library tries these servers in order:
time.google.com:123time.aws.com:123time.cloudflare.com:123time.windows.com:123
If all NTP servers fail, the library automatically falls back to system time.
-
Initialization (once per process):
- Fetches accurate time from NTP server (or uses system time)
- Records the initial timestamp and Go's monotonic clock reference
- This happens automatically when the package is first imported
-
Timestamp Generation (every call to
GetTimestamp()):- Calculates elapsed time using Go's monotonic clock
- Adds elapsed time to initial timestamp
- Returns result in Unix milliseconds
- Initialization: ~100ms (network-dependent)
- Per-call overhead: ~10ns (pure calculation)
- Memory usage: <100 bytes (single clock instance)
- Thread safety: Concurrent-safe reads
- Resolution: 1 millisecond
- Initial accuracy: Β±100ms (NTP-dependent)
- Long-term drift: None (monotonic clock based)
- Thread consistency: Perfect (same monotonic reference)