Snowflake epoch

Do all Fauna instances use the same epoch for Snowflake generation? I’m getting different results in each of my samples.

The query:

[ NewId(), Now() ]

The results:

id: 303416870958006851
date: 2021-07-07T01:02:06+00:00
timestamp: 72340219249
epoch: 2019-03-22T18:31:47Z

id: 303417171513442883
date: 2021-07-07T01:06:53+00:00
timestamp: 72340290907
epoch: 2019-03-22T18:35:22Z

id: 303424697617351237
date: 2021-07-07T03:06:30+00:00
timestamp: 72342085270
epoch: 2019-03-22T20:05:05Z

Same day, but different times.

The id is from the NewId() query.
The date is from the Now() query.
The timestamp is retrieved with id >> 22.
The epoch is retrieved with date - timestamp.

Fauna uses Unix Epoch (January 1, 1970) as the basis for all time computation. Fauna document IDs are, indeed, created with the help of the Snowflake algorithm, but they encode more information than just time.

What are you hoping to achieve by manipulating the document IDs in this way?

What are you hoping to achieve by manipulating the document IDs in this way?

My goal is to get the creation date from the Snowflake identifier.

The first 22 bits of a Snowflake identifier should be the timestamp. Fauna follows that convention, right? Yet it appears that the Snowflake epoch is 2019-03-22, which is not the UNIX epoch, of course. And as I pointed out before, the times of each Snowflake identifier are different for some reason. Am I missing something?

Hi Alec,

Why not use the ts on the create event for the document? For instance, you could run something like this:

Select("ts",Select(0,Paginate(Events(Ref(Collection("foo"), "300940002788901385")))))

Since the create event should always be the first event it will be in the first position of the pagination of all events; the ts field for that document will show the creation time in milliseconds since the epoch for it.

Cory

As I mentioned, while we use Snowflake, the document ID encodes additional information. While it could be possible to compute the creation date based on the document ID, we don’t recommend it, and we’re not going to provide enough information to do so.

To capture a document’s creation date, the simplest thing to do is to use Now. For example:

Create(
  Collection("documents"),
  {
    data: {
      created: Now(),
      // ...
    }
  }
) 

If you don’t want to store the creation timestamp, then you could explore the document’s history to find the creation event:

Paginate(Events(<document reference>), { size: 1 })

Which would give a result similar to:

{
  after: {
    ts: 1621013699360000,
    action: "update",
    document: Ref(Collection("Status"), "1")
  },
  data: [
    {
      ts: 1621013672170000,
      action: "create",
      document: Ref(Collection("Status"), "1"),
      data: {
        foo: "bar",
        scores: [53, 27, 9]
      }
    }
  ]
}

From such a response, you can use the ts field’s value as the creation date.

2 Likes

Hi @aleclarson,

Do you have any followup questions on this one? Or did Ewan’s answer resolve your problem?

Cory