hlc - Hybrid Logical Clock in Erlang

CIHex.pm

hlc implements the Hybrid Logical Clock outlined in Logical Physical Clocks and Consistent Snapshots in Globally Distributed Databases.

Hybrid logical clocks provide timestamps that combine both physical and logical components to support monotonic increments without degenerate cases causing timestamps to diverge from wall clock time. This is useful for distributed transactions and ordering events across a cluster.

Installation

Add hlc to your rebar.config dependencies:

{deps, [
    {hlc, "3.0.3"}
]}.

Or with mix:

{:hlc, "~> 3.0"}

Usage

Creating a Clock

1> {ok, C} = hlc:start_link().
{ok, <0.158.0>}

Getting Timestamps

Return a timestamp for the current time:

2> Now = hlc:now(C).
{timestamp, 1511564016030, 0}

By default, erlang:system_time(millisecond) is used for the physical time.

Updating from Remote Events

Update the clock when receiving timestamps from other cluster members:

3> {ok, UpdatedTS} = hlc:update(C, RemoteTimestamp).

Note: Clocks are not locked internally. Ensure only one process updates a clock at a time using now/1 or update/2.

Comparing Timestamps

Compare timestamps using hlc:less/2 or hlc:equal/2:

{MClock, MClockFun} = hlc:manual_clock(),
{ok, C} = hlc:start_link(MClockFun, 0),

A = hlc:timestamp(C),
B = hlc:timestamp(C),
true = hlc:equal(A, B),

hlc:set_manual_clock(MClock, 1),
B1 = hlc:now(C),
true = hlc:less(A, B1).

API Reference

Clock Management

Timestamps

Comparison

Configuration

Testing with Manual Clocks

For testing, you can create a manually controlled clock:

{MClock, MClockFun} = hlc:manual_clock(),
{ok, C} = hlc:start_link(MClockFun, 0),
hlc:set_manual_clock(MClock, 42),
hlc:stop_manual_clock(MClock).  % Clean up when done

Performance

Benchmark using hlc_harness:

1> hlc_harness:timed_generate(1000000).
generating timestamp: 2.586 s

License

Copyright (c) 2014-2026 Benoit Chesneau.

This project uses the MPL v2 license. See LICENSE for details.

Contributing

Contributions welcome! Please submit issues and pull requests on GitHub.

To run the test suite:

rebar3 eunit