{"id":18295410,"url":"https://github.com/spiderpig86/jayflake","last_synced_at":"2026-02-23T21:35:48.282Z","repository":{"id":164932438,"uuid":"633275454","full_name":"Spiderpig86/jayflake","owner":"Spiderpig86","description":":snowflake: Snowflake ids for Java.","archived":false,"fork":false,"pushed_at":"2025-01-19T06:25:39.000Z","size":157,"stargazers_count":2,"open_issues_count":4,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-19T07:29:45.129Z","etag":null,"topics":["gradle","java","java-lib","java-library","kotlin","snowflake-id","snowflake-twitter"],"latest_commit_sha":null,"homepage":"","language":"Java","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/Spiderpig86.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-04-27T06:42:58.000Z","updated_at":"2025-01-19T06:24:45.000Z","dependencies_parsed_at":null,"dependency_job_id":"5c2b4315-0b7f-4091-af80-05f23e314fe0","html_url":"https://github.com/Spiderpig86/jayflake","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Spiderpig86%2Fjayflake","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Spiderpig86%2Fjayflake/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Spiderpig86%2Fjayflake/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Spiderpig86%2Fjayflake/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Spiderpig86","download_url":"https://codeload.github.com/Spiderpig86/jayflake/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238937646,"owners_count":19555378,"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":["gradle","java","java-lib","java-library","kotlin","snowflake-id","snowflake-twitter"],"created_at":"2024-11-05T14:35:10.326Z","updated_at":"2025-10-30T06:30:59.113Z","avatar_url":"https://github.com/Spiderpig86.png","language":"Java","readme":"# ❄ Jayflake\n\nA Java implementation similar to Twitter's now deprecated [Snowflake ID](https://blog.twitter.com/engineering/en_us/a/2010/announcing-snowflake) \nthat is thread-safe. Note that this is only the library for \ngenerating the ids. It does not include a service that provides ids to calling backend services.\n\n\u003e Note: This project does not include a backend service for id generation.\n \n## Usage\n\n```java\n// Default generator\nSnowflakeGenerator generator = SnowflakeGenerator.getDefault();\n\n// Generator with custom configurations\nSnowflakeGenerator generator = SnowflakeConfiguration.builder()\n      .withTimestampBits(41)\n      .withDatacenterBits(8)\n      .withWorkerBits(2)\n      .withSequenceBits(12)\n      .build(),\n    GeneratorConfiguration.builder()\n      .withDataCenter(1L)\n      .withWorker(6L)\n      .withOverflowStrategy(OverflowStrategy.SPIN_WAIT)\n      .build(),\n    new DefaultTime(Clock.systemDefaultZone(), Instant.now()));\n```\n\n## Installation\n\n\u003e Java 9 or above is required.\n\n### Maven\n\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003eio.github.spiderpig86\u003c/groupId\u003e\n  \u003cartifactId\u003ejayflake\u003c/artifactId\u003e\n  \u003cversion\u003e0.1\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n### Gradle\n\n```groovy\nimplementation 'io.github.spiderpig86:jayflake:0.1'\n```\n\n## How it works\n\nBelow is a diagram depicting the structure of a default Snowflake id.\n\n- The first bit is unused to make ordering easier across both signed and unsigned values.\n- The next 41 bits are the timestamp, or the number of ticks since the epoch. By default, this can store a range of \n  69 years from the epoch where the tick duration is 1 millisecond.\n- The next 4 bits store an id indicating the data center of which the machine lives in.\n- The next 6 bits store an id of the worker generating the id.\n- The last 12 bits store a count representing the sequence to handle any collisions.\n\n```\n+------------+---------------------+-----------+---------+----------------------+\n| 1 Bit      | 41 Bit              | 4 Bit     | 6 Bit   | 12 Bit               |\n| Unused     | Timestamp           | Data Ctr  | Worker  | Sequence Number      |\n+------------+---------------------+-----------+---------+----------------------+\n```\n\n| Unused bit | Timestamp                                       | Data center | Worker | Sequence        |\n|------------|-------------------------------------------------|-------------|--------|-----------------|\n| 0          | 00000000000 00000000001 00111111010 01010010010 | 0000        | 000101 | 000000001011    |\n\nBased on the example above which shows id `21941452820491` in binary, we know the following:\n- `5231250` ticks passed since the _epoch_.\n- The data center is `0`.\n- The worker is `5`.\n- The sequence id is `11`.\n\n## Customization\n\nOne of the strengths of this implementation is that you are not tied down to the default configuration. There are 3 \nmain types of classes that determine the generator's behavior.\n\n### `SnowflakeConfiguration`\n\nThe structure of the Snowflake id's bits is controlled by the `SnowflakeConfiguration`, a centralized place that \ndetermines which bits are reserved for what functionality.\n\nFor example, if you think the data center bits are unnecessary and want to copy the original Snowflake id's format \nof a 41 bit timestamp, 10 bit worker id, and 12 bit sequence id, you can do the following:\n\n```java\nSnowflakeGenerator generator =\n    SnowflakeGenerator.create(\n        SnowflakeConfiguration.builder()\n        .withTimestampBits(41)\n        .withDatacenterBits(0)\n        .withWorkerBits(10)\n        .withSequenceBits(12)\n        .build(),\n    GeneratorConfiguration.builder()\n        .withDataCenter(0L)\n        .withWorker(5L)\n        .withOverflowStrategy(OverflowStrategy.SLEEP_WITH_JITTER)\n        .build(),\n    DefaultTime.getDefault(c));\n```\n\n### `GeneratorConfiguration`\n\nThe `GeneratorConfiguration` houses all the settings used while generating the ids themselves, such as the data \ncenter, worker id, and overflow strategy.\n\n```java\nGeneratorConfiguration.builder()\n    .withDataCenter(0L)\n    .withWorker(5L)\n    .withOverflowStrategy(OverflowStrategy.SLEEP_WITH_JITTER)\n    .build()\n```\n\n### Classes extending `Time`\n\nThese classes are the source of truth of the `epoch` (similar to the UNIX epoch) and the length of each tick.\nThe `DefaultTime` class is provided out of the box which uses a tick duration of `1ms`.\n\nYou can increase the duration of the tick to whatever duration you want to extend how much time the id can span. \n_Keep in mind that this can increase the number of ids that are generated with the same timestamp which runs the \nrisk of overflowing the `sequence` bits_.\n\nBelow is an example Time class which uses `1s` as the tick duration.\n\n```java\npublic class OneSecondTime extends Time {\n\n  private final long tickDurationMs;\n\n  public OneSecondTime(@Nonnull final Clock clock, @Nonnull final Instant epoch) {\n    super(clock, epoch);\n    this.tickDurationMs = 1000L;\n  }\n\n  @Override\n  public long getTickDurationMs() {\n    return tickDurationMs;\n  }\n}\n```\n\n## Overflows\n\nSnowflake ids are no strangers to overflow situations, especially if the bits are configured improperly. Even if \nthey are, with high enough QPS, we may run out of numbers.\nIn the event this happens, you can set a specific `OverflowStrategy` for when values overflow.\n\n- `SLEEP` - SnowflakeGenerator will sleep for a provided duration in milliseconds.\n- `SLEEP_WITH_JITTER` - SnowflakeGenerator will sleep for a provided duration plus a random jitter in milliseconds.\n- `SPIN_WAIT` - SnowflakeGenerator will provide a system hint to allow other threads to be scheduled and while two provided values are equal.\n- `THROW_EXCEPTION` - SnowflakeGenerator will throw an exception when encountering an overflow.\n\nCurrently, this applies to the `sequence` bits. If the timestamp overflows, you have a much bigger problem on your \nhands.\n\n## License\n\nThis project is licensed under the MIT license. Please see the [license](./LICENSE) for more details.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspiderpig86%2Fjayflake","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fspiderpig86%2Fjayflake","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspiderpig86%2Fjayflake/lists"}