Exnowflake

Exnowflake is an Elixir application used to generate decentralized, unique, time based IDs. It's inspired on Twitter's Snowflake.

Description

This app generates 64 bit integers, based on a timestamp, worker ID and a sequence:

  • timestamp (milliseconds) - 42 bits
  • worker - 10 bits (0 - 1023)
  • sequence - 12 bits (0 - 4095)

The worker ID can be an arbitrary integer between 0-1023, optionally a Redis connection should be configured to register/unregister nodes in order to get the worker number.

Example

=> {:ok, id} = Exnowflake.generate()
{:ok, 9522559057920}

=> Exnowflake.timestamp(id)
1565636645355

Configuration

Example:

config :exnowflake,
  worker_id: {:system, "WORKER_ID"}, # Must be an integer between 0-1023
  epoch: 1234567890 # custom epoch in milliseconds
* Warning: if a custom epoch timestamp is given, it should not be reaplaced later or IDs overlap can occur.

If no :worker_id configuration option is given, Exnowflake will attempt to connect to Redis with the given defaults which you can override:

config :exnowflake,
  host: "127.0.0.1",
  port: 6379,
  database: 0

You can also add the following options to redis connection:

config :exnowflake,
  # ...other config options
  password: {:system, "REDIS_PWD"},
  ssl: true, # defaults to false
  sync_connect: false #defaults to true

For more info check Redix Documentation.

Usage

Generating an ID is very simple:

=> {:ok, id} = Exnowflake.generate()
{:ok, 234527838437376}

We can also retrieve the timestamp inside the ID:

=> Exnowflake.timestamp(id)
1574524265794

Or the internal timestamp, which returns how many milliseconds since epoch passed when ID was generated:

=> Exnowflake.internal_timestamp(id)
55915794

To get the current node worker ID, you can call:

=> Exnowflake.worker_id()
0

Benchmarks

Benchmarks can be run with: mix bench.

These benchmarks were run with a Redis worker registry (no static worker ID given), on an iMac 4 GHz Intel Core i7 w/ 32GB RAM.

Name                ips        average  deviation         median         99th %
generate       283.71 K        3.52 μs   ±414.17%           3 μs           5 μs
worker_id      622.99 K        1.61 μs   ±429.14%           2 μs           2 μs