a3kov

a3kov

Stamp is a fast and flexible Snowflake-flavored ID generator based on 8-byte integers with optional encoding.

The original Snowflake supported BigTech-scale numbers (e.g. 1024 workers each inserting up to 4,096,000 records per second). With BEAM favoring vertical (rather than horizontal) scaling and hardware getting more powerful every year it is reasonable to assume that we can leverage the bits in the ID more effectively than Twitter did back in 2010, especially if the application never reaches Twitter’s scale.

Features

  • works both with and without Ecto
  • BlazingFast™ sequences on top of process-free atomic counters
  • no global configuration - uses per-field configuration and runtime values
  • user-configurable number of bits for every part of the ID
  • some parts can be disabled, freeing up the bits for other parts
  • optional encoding of the integers to string versions
  • optional Stripe-style prefix to easily distinguish IDs of different models/schemas
  • optional range-based partitioning and sharding (experimental)

How stamps look

Type Stamp
Raw, no partitioning 5406450851512320
Base62 "Ol6XKJ8oy"
Base62 + prefix "u_Ol6XKJ8oy"
Integer codec (always a string) "5406450851512320"
Integer + prefix "u_5406450851512320"
Raw, 256 partitions, p255 (worst case) 9187364417633648640
256 partitions, p255, Base62 "AwgE2gA8mq8"

Stamp vs Alternatives

UUID fields have become more popular recently, but they are expensive for use in indexes and especially primary keys. UUIDv7 improves upon v4 and other versions in some ways, but the size hasn’t changed. There are also exotic alternatives like KSUID and ULID, but they share some issues of UUID.

Stamp Serial/Identity UUID
generated in the application :white_check_mark: :cross_mark: :white_check_mark:
globally unique with distributed generation :cross_mark: :cross_mark: :white_check_mark:
compact in terms of storage and RAM :white_check_mark: :white_check_mark: :cross_mark:
composite PK/indexes without bloat :white_check_mark: :white_check_mark: :cross_mark:
looks good and is short both raw/encoded :white_check_mark: :white_check_mark: :cross_mark:
efficient BTree index operations :white_check_mark: :white_check_mark: :white_check_mark: in v7
may remove the need for extra time field :white_check_mark: :cross_mark: :white_check_mark: in v7
bulk inserts :eight_spoked_asterisk: sequence nuances[1] :white_check_mark: :white_check_mark:
range partitioning/sharding (not by time) :white_check_mark: :cross_mark: :cross_mark:
keeps creation time secret :cross_mark: :eight_spoked_asterisk: guessable[2] :cross_mark: not in v7
keeps number of records secret :white_check_mark: :cross_mark: barely[3] :white_check_mark:
next id is unpredictable :eight_spoked_asterisk: depends[4] :cross_mark: :white_check_mark:
easy to set up and use :red_question_mark: planning, setup[5] :white_check_mark: :white_check_mark:

[1] If an insert overflows the sequence, time goes into the future. This does not limit the insertion,
but forces timestamp accuracy trade-offs. In the worst case scenario you can have more accurate version of creation time in a separate field. See Important details and caveats section in the docs for more info.

[2] Because there is only 1 sequence correlated with creation, one could roughly estimate the
creation time of a record by comparing the number with other records, where the time may be known.

[3] Under normal conditions 1 used sequence number corresponds to 1 record. If we can observe
sequence growth, we can estimate or even know precisely how many records are created in a
period of time.
With total number of records it’s a bit different. Some applications set initial sequence
number high to help with the issue, but it’s only a half measure. If it’s possible to observe random ids inside the application, one can notice the gap and guess that it’s empty.

[4] Stamp is monotonic for a combination of partition, node number, sequence id. If you can generate ids for this combination, you can predict next id. Some randomness can be added by randomly picking from a pool of node numbers on each generation. In general, Stamp is definitely not as unpredictable as UUID simply because of the size difference.

[5] The library provides good defaults tuned for “average project scale” rather than “Twitter
scale”, but learning about the available configuration parameters to get the most benefits is still encouraged.

Project on Hex
Docs

Showing Posts 1 to 2

dimitarvp

dimitarvp

One thing that would help your post here is to substantiate the “looks good” claim with examples.

Also most people want UUIDs because next ID is unpredictable. Can you clarify what does “it depends” means here?

a3kov

a3kov OP

Sure! I’ll add examples.

Total keyspace is big enough, but it’s monotonic for a combination of partition, node, sequence id. If you can generate ids for this combination, you can predict next id. So it really depends on the generator params, parallel generations, partitioning etc. It’s definitely not as unpredictable as UUID. It’s also better than serial/identity (which is just 1 sequence).

— All posts loaded —

Where Next? Top

Trending in Announcing Top

woylie
Flop is an Elixir library that applies filtering, ordering and pagination parameters to your Ecto queries. offset-based pagination with...
New
MRdotB
I needed to reuse React components from my Chrome extension in my Phoenix/LiveView backend. I noticed that for Svelte/Vue, there are live...
New
woylie
I released Doggo, a collection of unstyled Phoenix components. https://github.com/woylie/doggo Features Unstyled Phoenix components....
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
anuaralfetahe
Hello Published a new library - ProcessHub! ProcessHub is a library designed to manage process distribution within the Elixir cluster. ...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
webofbits
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself. My main conc...
#ai
New
sergio
It’s not that it’s vocabulary is too advanced. It’s something worse. I get lost trying to follow even a paragraph written by Claude. It’...
New
AstonJ
This showed up on my feed.. anyone heard of it? Just hype? Ox Alpha is a reasoning model designed for coding, sustained ag...
New
bartblast
Hey folks, I just published a post about Hologram’s funding and where the project goes next - the short version: Curiosum as Main Spons...
New
sorenone
Today we’re releasing Oban for Python. Not an Oban client in Python. Not a pythonx wrapper embedded in Elixir. Nope, it’s a fully operati...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews