{"id":50893982,"url":"https://github.com/pmarreck/uuidv7","last_synced_at":"2026-06-15T23:01:23.350Z","repository":{"id":361950526,"uuid":"1256582007","full_name":"pmarreck/uuidv7","owner":"pmarreck","description":"RFC 9562 UUIDv7 generator in LuaJIT: time-ordered, sortable, monotonic counter","archived":false,"fork":false,"pushed_at":"2026-06-01T23:24:43.000Z","size":15,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"yolo","last_synced_at":"2026-06-02T01:14:33.532Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Shell","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/pmarreck.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-01T23:10:00.000Z","updated_at":"2026-06-01T23:24:46.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/pmarreck/uuidv7","commit_stats":null,"previous_names":["pmarreck/uuidv7"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/pmarreck/uuidv7","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pmarreck%2Fuuidv7","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pmarreck%2Fuuidv7/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pmarreck%2Fuuidv7/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pmarreck%2Fuuidv7/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pmarreck","download_url":"https://codeload.github.com/pmarreck/uuidv7/tar.gz/refs/heads/yolo","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pmarreck%2Fuuidv7/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34383468,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-15T02:00:07.085Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2026-06-15T23:01:22.405Z","updated_at":"2026-06-15T23:01:23.344Z","avatar_url":"https://github.com/pmarreck.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# uuidv7\n\nA small, fast [UUIDv7](https://www.rfc-editor.org/rfc/rfc9562) generator written in\n[LuaJIT](https://luajit.org/). UUIDv7 values are **time-ordered**, so they sort\nchronologically and make excellent database primary keys (far better index locality\nthan random UUIDv4).\n\nRFC 9562 compliant: 48-bit millisecond Unix timestamp, version/variant bits, and a\n12-bit monotonic counter so that multiple UUIDs minted within the same millisecond\nremain strictly ordered and unique.\n\n## Features\n\n- **Strictly monotonic \u0026 time-ordered** — lexicographic order == chronological order,\n  with no reliance on randomness for ordering\n- **True nanosecond precision on Linux *and* macOS** — `clock_gettime(CLOCK_REALTIME)`\n  (macOS ≥ 10.12), not microsecond `gettimeofday`\n- **Sub-millisecond ordering for free** — the low 20 bits of the nanosecond-within-ms go\n  into `rand_a` + the top of `rand_b` (RFC 9562 Method 3), giving ~1 ns ordering\n  resolution; per-millisecond monotonicity comes from the clock, not a counter\n- **54-bit monotonic counter** in the rest of `rand_b` — random-initialized each\n  nanosecond tick, incremented only on a same-nanosecond collision (so in practice every\n  UUID still carries ~53 bits of fresh entropy). Cross-process via System V shared memory\n  (Linux) or a `flock`'d file (macOS), both under `$TMPDIR`\n- **Clock-rollback safe** — freeze-and-increment keeps monotonicity regardless of how far\n  the wall clock jumps back (the 54-bit counter can't overflow in any real window)\n- **Hyphenated or compact** output; **zero heavy deps** — just LuaJIT\n- **Reversible timestamps** — recover the exact epoch time encoded in a UUIDv7 (this\n  tool's nanosecond precision included) with `--extract-timestamp[-ms|-ns]`, independent\n  of the counter/random bits\n\n### Behavior \u0026 environment\n\n- `uuidv7 \u003cnanoseconds\u003e` uses an explicit timestamp (honored *exactly* — 64-bit-parsed,\n  not rounded through a double), useful for testing/reproducibility.\n- `TMPDIR` — where the cross-process counter state lives (default `/tmp`).\n- `UUIDV7_SILENCE_INSECURE_RANDOM=1` — mute the red stderr warning that fires if no secure\n  RNG (`getrandom`/`getentropy`/`/dev/urandom`) is available and it must fall back to the\n  non-cryptographic `math.random`.\n- `UUIDV7_NS_EXTRACT_OK=1` (or `--mute-warning`) — mute the stderr warning that\n  `--extract-timestamp-ns` prints, reminding that sub-millisecond bits are only\n  meaningful for UUIDs generated by this tool.\n\n## Usage\n\n```sh\nuuidv7                      # 019e8570aa20718baaf95dbc246169f9\nuuidv7 --hyphen             # 019e8570-aa29-7367-9482-75b33fab32b6\nuuidv7 -                    # short form for --hyphen\nuuidv7 1234567890123456789  # use a static timestamp (nanoseconds from epoch)\n\n# Recover the original timestamp from a UUIDv7 (hyphenated or compact, any case):\nuuidv7 --extract-timestamp-ms 017f22e2-79b0-77ff-bfc9-0c9a45e78a47  # 1645557742000\nuuidv7 --extract-timestamp-ns 017f22e279b077ffbfc90c9a45e78a47      # 1645557742000524287\nuuidv7 --extract-timestamp    017f22e279b077ffbfc90c9a45e78a47      # defaults to ms\n```\n\nRun `uuidv7 --help` for the full list.\n\n## Daemon\n\n`uuidv7 --daemon` runs a single-threaded, `poll(2)`-based **Unix-domain-socket** server\n(`${XDG_RUNTIME_DIR:-$TMPDIR}/uuidv7.sock`, mode `0600`). Because it's one process, the\ncounter is in-memory and strictly monotonic with no cross-process coordination at all.\nThe plain `uuidv7` CLI **transparently uses the daemon** for live generation when its\nsocket is reachable (no auto-spawn). When a daemon *is* reachable it is authoritative: the\nCLI gets the UUID from it and **never silently generates locally** — local generation uses\nthe separate fs/SysV counter, so a silent fallback could emit a UUID that sorts out of\norder against the daemon's in-memory stream, breaking strict monotonicity. If the daemon\nmomentarily won't serve, the CLI retries with tiny exponential backoff (50\u0026nbsp;µs base,\n~1.5× with jitter), tagging each retry with `R\u003cattempt\u003e`/`W\u003cµs-waited\u003e` tokens the daemon\nlogs, then **errors** once the attempt cap (`UUIDV7_DAEMON_RETRIES`, default 20) or the\nwait timeout (`UUIDV7_DAEMON_RETRY_TIMEOUT_US`, default 2000) is hit. `UUIDV7_DAEMON_NO_RETRY=1`\nerrors on the first failure instead of retrying. Local generation happens only when **no**\ndaemon answers the socket (the normal standalone mode) — that's not a fallback.\n\nIt's a line-based protocol (newline-terminated, no spaces), so it's `nc -U`-friendly:\n\n```\n\u003cempty\u003e     one compact UUID            c\u003cN\u003e     N UUIDs\n-           hyphenated                  tn\u003cns\u003e   explicit nanosecond time\ntm\u003cms\u003e      explicit millisecond time   *        ephemeral (with tn/tm): isolated\nR\u003cn\u003e        retry attempt # (telemetry)   W\u003cus\u003e    microseconds waited (telemetry)\nexample: c5-tm1700000000000\n\nPING -\u003e OK   s -\u003e status (text)   sj -\u003e status (JSON)   l -\u003e log stats\nr -\u003e restart (re-exec, zero-downtime)   +++ -\u003e shutdown   h or ? -\u003e help\nhandshake (no newline): SYN(0x16) -\u003e SYNACK(0x16 0x06) -\u003e ACK(0x06)\n```\n\nGuards: batch capped at `UUIDV7_MAX_BATCH` (default 1000); request lines ≤ 64 bytes;\nexplicit timestamps more than 1 s in the future are rejected unless `*` (ephemeral) is\ngiven. Activity (start / restart / shutdown / stats / errors) is logged as **JSONL** —\none JSON object per line, every byte escaped, so the log is `jq`-friendly and\ninjection-proof. Log location: `$XDG_STATE_HOME/uuidv7/uuidv7.log`, else\n`~/Library/Logs/uuidv7.log` on macOS, else `~/.local/state/uuidv7/uuidv7.log`.\n\n## Performance\n\nSingle-threaded, in-process generation sustains **~490,000 unhyphenated UUIDv7/s\n(~2.0 µs each)**. It's syscall-bound, not compute-bound: every UUID does a\n`clock_gettime` for the timestamp and — on each new-nanosecond tick — a\n`getrandom`/`getentropy` to random-seed the 54-bit counter, so ~2 syscalls/UUID is the\nfloor. The benchmark also verifies its output is strictly increasing (unique + sorted)\nand valid (`ver=7`, `variant=10xx`).\n\nMeasured on an **Apple M4 Max** (12P+4E, 128 GB), macOS 26.5, LuaJIT 2.1. Reproduce:\n\n```sh\nbench/uuidv7_bench            # default 2,000,000\nbench/uuidv7_bench 1000000    # custom count\n```\n\n(The daemon adds UDS round-trip overhead per request, but batching — `c\u003cN\u003e` — amortizes\nit, so a single `c1000000` request produces a million at close to the in-process rate.)\n\n## Install\n\n### Nix (flake)\n\n```sh\nnix run github:pmarreck/uuidv7\nnix profile install github:pmarreck/uuidv7\n```\n\n### Manual\n\nPut `bin/` on your `PATH`. Requires `luajit` on your `PATH`.\n\n## Development\n\n```sh\ndirenv allow      # or: nix develop\n./test            # run the suite\nnix flake check   # hermetic CI check (also what Garnix runs)\n```\n\n`./test` runs eight suites: the JSON writer, the core generator, the RFC bit-layout\ncontract, the daemon black-box test (which starts a real daemon and drives it — no\nsleeps; it synchronizes on the daemon's readiness line and on stdout EOF), timestamp\nextraction, the daemon retry / no-silent-fallback policy, a **load test** (many parallel\nclients; gates on correctness invariants only — zero duplicates, strictly-ascending\nper-connection streams, client↔server count reconciliation, no crashes — never on\ntiming), and a **fuzz test** (hostile/malformed/partial protocol input; seeded and\nreproducible). All eight also run under `nix flake check` (and Garnix, including\nx86_64-linux). Raw throughput/latency lives in `bench/uuidv7_bench`, kept out of the\npass/fail suites so loaded CI never makes them flaky.\n\n## Layout\n\n```\nbin/uuidv7                  thin CLI (also `--daemon`); auto-uses a running daemon\nlib/uuidv7_core.lua         generation core: bit layout + counter backends (single source of truth)\nlib/uuidv7_daemon.lua       the UDS daemon (poll loop, protocol, stats, JSONL log, re-exec)\nlib/uuidv7_client.lua       UDS client (CLI fast-path + test driver)\nlib/uuidv7_json.lua         minimal, escape-everything JSON encoder\ntests/uuidv7_{json,test,layout,daemon,extract,fallback,load,fuzz}_test   the eight CI suites\ntests/uuidv7_sysv_counter_test                Linux-only SysV test (reference; not in CI)\nalternates/uuidv7.{bash,sh}                   pure-bash / POSIX-sh references (not installed)\nflake.nix                   dev shell, packaged + wrapped binary, and CI check\ntest                        test runner\n```\n\nThe `alternates/` implementations are earlier takes kept for lineage/comparison. They\nare not installed.\n\n## License\n\nMIT © Peter Marreck\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpmarreck%2Fuuidv7","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpmarreck%2Fuuidv7","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpmarreck%2Fuuidv7/lists"}