{"id":13713294,"url":"https://github.com/T-PWK/go-flakeid","last_synced_at":"2025-05-06T23:31:35.048Z","repository":{"id":57506892,"uuid":"149972463","full_name":"T-PWK/go-flakeid","owner":"T-PWK","description":"A decentralized, k-ordered id generation library in Golang","archived":false,"fork":false,"pushed_at":"2021-03-13T14:53:40.000Z","size":7,"stargazers_count":11,"open_issues_count":0,"forks_count":3,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-11-14T00:33:46.858Z","etag":null,"topics":["flake","flake-ids","go","golang","identifier","uniq","unique","unique-id","unique-identifier","uniqueness"],"latest_commit_sha":null,"homepage":"https://godoc.org/github.com/T-PWK/go-flakeid","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/T-PWK.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-09-23T10:06:16.000Z","updated_at":"2024-08-16T07:23:51.000Z","dependencies_parsed_at":"2022-08-29T20:01:31.786Z","dependency_job_id":null,"html_url":"https://github.com/T-PWK/go-flakeid","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/T-PWK%2Fgo-flakeid","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/T-PWK%2Fgo-flakeid/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/T-PWK%2Fgo-flakeid/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/T-PWK%2Fgo-flakeid/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/T-PWK","download_url":"https://codeload.github.com/T-PWK/go-flakeid/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252787518,"owners_count":21804278,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["flake","flake-ids","go","golang","identifier","uniq","unique","unique-id","unique-identifier","uniqueness"],"created_at":"2024-08-02T23:01:31.733Z","updated_at":"2025-05-06T23:31:30.033Z","avatar_url":"https://github.com/T-PWK.png","language":"Go","funding_links":[],"categories":["Repositories"],"sub_categories":[],"readme":"# Flake - decentralized, k-ordered identifier generation in Go\n\n[![Build Status](https://travis-ci.com/T-PWK/go-flakeid.svg?branch=master)](https://travis-ci.com/T-PWK/go-flakeid)\n[![GitHub issues](https://img.shields.io/github/issues/T-PWK/go-flakeid.svg)](https://github.com/T-PWK/go-flakeid/issues)\n[![Go Report Card](https://goreportcard.com/badge/github.com/T-PWK/go-flakeid)](https://goreportcard.com/report/github.com/T-PWK/go-flakeid)\n[![Coverage Status](https://coveralls.io/repos/github/T-PWK/go-flakeid/badge.svg?branch=master)](https://coveralls.io/github/T-PWK/go-flakeid?branch=master)\n[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](http://blog.abelotech.com/mit-license)\n\nFlake ID generator produces 64-bit, k-ordered, conflict-free ids in a distributed environment.\n\nTo install\n\n```\ngo get -u github.com/t-pwk/go-flakeid\n```\n\n## Flake Numbers Format\n\nThe Flake ID is made up of: `timestamp`, `datacenter`, `worker` and `counter`. Examples in the following table:\n\n```\n+-------------+------------+--------+---------+--------------------+\n|  Timestamp  | Datacenter | Worker | Counter | Flake ID           |\n+-------------+------------+--------+---------+--------------------+\n| 0x8c20543b0 |   00000b   | 00000b |  0x000  | 0x02308150ec000000 |\n+-------------+------------+--------+---------+--------------------+\n| 0x8c20543b1 |   00000b   | 00000b |  0x000  | 0x02308150ec400000 |\n+-------------+------------+--------+---------+--------------------+\n| 0x8c20543b1 |   00000b   | 00000b |  0x001  | 0x02308150ec400001 |\n+-------------+------------+--------+---------+--------------------+\n| 0x8c20543b1 |   00000b   | 00000b |  0x002  | 0x02308150ec400002 |\n+-------------+------------+--------+---------+--------------------+\n| 0x8c20543b1 |   00000b   | 00000b |  0x003  | 0x02308150ec400003 |\n+-------------+------------+--------+---------+--------------------+\n| 0x8c20c0335 |   00011b   | 00001b |  0x000  | 0x02308300cd461000 |\n+-------------+------------+--------+---------+--------------------+\n| 0x8c20c0335 |   00011b   | 00001b |  0x001  | 0x02308300cd461001 |\n+-------------+------------+--------+---------+--------------------+\n```\n\n- `timestamp`, a 42 bit long number of milliseconds elapsed since 1 January 1970 00:00:00 UTC\n- `datacenter`, a 5 bit long datacenter identifier. It can take up to 32 unique values (including 0)\n- `worker`, a 5 bit long worker identifier. It can take up to 32 unique values (including 0)\n- `counter`, a 12 bit long counter of ids in the same millisecond. It can take up to 4096 unique values.\n\nExample of a breakdown of bits for an identifier `5828128208445124609` (counter is `1`, datacenter is `7` and worker `3`) is as follows:\n\n```\n 010100001110000110101011101110100001000111 00111 00011 000000000001\n                                                       |------------| 12 bit counter\n                                                 |-----|               5 bit worker\n                                           |-----|                     5 bit datacenter\n                                           |----- -----|              10 bit generator identifier\n|------------------------------------------|                          42 bit timestamp\n```\n\nNote that composition of `datacenter id` and `worker id` makes 1024 unique generator identifiers. By modifying datacenter and worker id we can get up to 1024 id generators on a single machine (e.g. each running in a separate process) or have 1024 machines with a single id generator on each.\n\n## Usage\n\nFlake ID Generator returns 64-bit long unsigned integer. Every time you call `FlakeID.NextID` you get a k-ordered, conflict-free identifier.\n\n```go\npackage  main\n\nimport (\n  \"fmt\"\n  \"github.com/t-pwk/go-flakeid\"\n)\n\nfunc main() {\n  g := flakeid.FlakeID{}\n\n  fmt.Printf(\"%x\\n\", g.NextID()) // 1530d02cb005000\n  fmt.Printf(\"%x\\n\", g.NextID()) // 1530d02cb005001\n\n  fmt.Printf(\"%b\\n\", g.NextID()) // 101010011000011010000001011001011000000000101000000000010\n  fmt.Printf(\"%b\\n\", g.NextID()) // 101010011000011010000001011001011000000000101000000000011\n}\n```\n\nIf you want to assign different worker or datacenter identifiers, you can do it during a generator creation or after.\n\n```go\npackage  main\n\nimport (\n  \"fmt\"\n  \"github.com/t-pwk/go-flakeid\"\n)\n\nfunc main() {\n  g1 := flakeid.FlakeID{WorkerID: 7, DatacenterID: 7}\n\n  g2 := flakeid.FlakeID{}\n  g2.WorkerID = 7\n  g2.DatacenterID = 7\n}\n```\n\nIf your generator works in a single environment and you would like to use 1024 unique workers, you can convert the worker identifier into the generator's datacenter and worker id in the following way:\n\n```go\npackage main\n\nimport (\n  \"fmt\"\n  \"github.com/t-pwk/go-flakeid\"\n)\n\nconst (\n  mask = 0x1F\n)\n\nfunc main() {\n  var worker uint64 = 1022\n\n  g := flakeid.FlakeID{WorkerID: worker \u0026 mask, DatacenterID: (worker \u003e\u003e 5) \u0026 mask}\n  fmt.Printf(\"W: %b, D: %b\\n\", g.WorkerID, g.DatacenterID) // W: 11110, D: 11111\n}\n```\n\nYou can also slightly reduce range of the generated identifiers by providing the `Epoc` parameter value. That value is to reduce timestamp (number of milliseconds elapsed since 1 January 1970 00:00:00 UTC) value when building identifiers.\n\n```go\npackage main\n\nimport (\n  \"fmt\"\n  \"time\"\n  \"github.com/t-pwk/go-flakeid\"\n)\n\nfunc main() {\n  g1 := flakeid.FlakeID{}\n\n  g2 := flakeid.FlakeID{Epoc: flakeid.Epoc1Jan2000}\n\n  epoc := time.Date(2018, time.January, 1, 0, 0, 0, 0, time.UTC).UnixNano() / int64(time.Millisecond)\n  g3 := flakeid.FlakeID{Epoc: uint64(epoc)}\n\n  fmt.Printf(\"%x\\n\", g1.NextID()) // 597edbca22c00000\n  fmt.Printf(\"%b\\n\", g1.NextID()) // 101100101111110110110111100101000100010110000000000000000000001\n\n  fmt.Printf(\"%x\\n\", g2.NextID()) // 226427df22c00000\n  fmt.Printf(\"%b\\n\", g2.NextID()) // 10001001100100001001111101111100100010110000000000000000000001\n\n  fmt.Printf(\"%x\\n\", g3.NextID()) // 1531aa622c00000\n  fmt.Printf(\"%b\\n\", g3.NextID()) // 101010011000110101010011000100010110000000000000000000001\n}\n```\n\nAs you can see, the range values varied depending on the value added to the `Epoc` parameter. Please note that the `epoc` parameter must be the same for all identifiers. Otherwise, a generator will not be able to generate k-ordered, conflict-free ids. Hence, you should never use current time or a value that changes from execution to execution for an epoch. Always use some constants, or do not use that feature at all.\n\n### Formatting\n\nFlakeID generator returns uint64 number. You can use different formats, using for example `fmt` package or convert an identifier to Base64 format.\n\n```js\npackage  main\n\nimport (\n  \"encoding/base64\"\n  \"encoding/binary\"\n  \"fmt\"\n  \"github.com/t-pwk/go-flakeid\"\n)\n\nfunc main() {\n  g := flakeid.FlakeID{WorkerID: 7, DatacenterID: 7}\n\n  fmt.Printf(\"%d\\n\", g.NextID())   // 6448828961128345600\n  fmt.Printf(\"%x\\n\", g.NextID())   // 597ed7c5d54e7001\n  fmt.Printf(\"0x%x\\n\", g.NextID()) // 0x597ed7c5d54e7002\n  fmt.Printf(\"%X\\n\", g.NextID())   // 597ED7C5D54E7003\n  fmt.Printf(\"%b\\n\", g.NextID())   // 101100101111110110101111100010111010101010011100111000000000100\n\n  b := make([]byte, 8)\n  binary.LittleEndian.PutUint64(b, g.NextID())\n  fmt.Println(base64.StdEncoding.EncodeToString(b)) // BXDOxnfZflk=\n}\n```\n\n## Documentation\n\n[Documentation](https://godoc.org/github.com/T-PWK/go-flakeid) is hosted at GoDoc project.\n\n## Author\n\nWritten by Tom Pawlak - [Blog](https://blog.abelotech.com)\n\n## License\n\nCopyright (c) 2018 Tom Pawlak\n\nMIT License : https://blog.abelotech.com/mit-license/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FT-PWK%2Fgo-flakeid","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FT-PWK%2Fgo-flakeid","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FT-PWK%2Fgo-flakeid/lists"}