Testable Time for Go. Deterministic. Instant.

Inject a clock, control time in tests. Real clock for production, fake clock for testing — same API, zero flakiness.

Get Started
import "github.com/zoobz-io/clockz"

func TestRetryBackoff(t *testing.T) {
    clock := clockz.NewFakeClockAt(time.Date(2024, 1, 1, 12, 0, 0, 0, time.UTC))
    service := NewService(clock)

    go service.RetryWithBackoff()

    clock.Advance(1 * time.Second)   // First retry
    clock.Advance(2 * time.Second)   // Second retry
    clock.Advance(4 * time.Second)   // Third retry
    // Test completes in milliseconds, not seconds
}

// Production: zero overhead
service := NewService(clockz.RealClock)

// Testing: full control
clock := clockz.NewFakeClockAt(time.Now())
service := NewService(clock)

ctx, cancel := clock.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
clock.Advance(6 * time.Second) // Context cancelled instantly
98%Test Coverage
A+Go Report
MITLicense
1.24+Go Version
v1.0.2Latest Release

Why Clockz?

Make time-dependent code testable without sleeps, flakiness, or rewrites.

Instant Tests

Advance hours in microseconds. Retry backoff tests that took seconds now complete instantly.

Mirrors time Package

Same API you already know. time.Now() becomes clock.Now(). No new patterns to learn.

Context-Aware Deadlines

WithTimeout and WithDeadline respect fake time. Contexts cancel when you advance past their deadline.

Full Timer Support

Timer, Ticker, AfterFunc — all with proper channel semantics matching the time package exactly.

Thread-Safe

Both RealClock and FakeClock handle concurrent use. Advance while goroutines wait on timers.

BlockUntilReady

Synchronize goroutine setup before advancing time. Eliminates the race between setup and assertion.

Capabilities

Two implementations of one interface — swap between real and fake time without changing your code.

FeatureDescriptionLink
Fake ClockManual time control with Advance() and SetTime(). Tests complete in microseconds regardless of duration logic.Concepts
Real ClockZero-overhead delegation to the time package. No allocations, no synchronization, no measurable cost.Quickstart
Timers & TickersChannel-based timing primitives that fire in chronological order when fake time advances.Concepts
Context IntegrationWithTimeout and WithDeadline create contexts that respect fake time, including early-return for expired deadlines.Testing
AfterFuncCallbacks execute synchronously during Advance() on FakeClock, in goroutines on RealClock.API
SynchronizationBlockUntilReady() and HasWaiters() ensure goroutines have registered their timers before you advance.Patterns

Articles

Browse the full clockz documentation.

Learn

Quick StartGet up and running with clockz in minutes
Core ConceptsUnderstanding clock selection and dependency injection in clockz

Guides

Testing PatternsStrategies for testing time-dependent code with clockz

Cookbook

Common PatternsRecipes for retry logic, rate limiting, and deadline management

Reference

API ReferenceComplete interface documentation for clockz