Minimal, monotonic, URL-safe, Client-first, reversible date-based IDs - just 7 chars for millisecond precision!
https://github.com/nrjdalal/msid.git
Minimal, monotonic, URL-safe, Client-first, reversible date-based IDs - just 7 chars for millisecond precision!
Encode any Date (or βnowβ) into the shortest possible, msid guarantees lexographically sortable and strictly increasing IDs when called in rapid succession string at ms, second, or day precision - and decode it back without loss.
// Millisecond precision (default)
msid()
// encoded - UqofYU9 ~ 7 chars
// current - 2025-07-13T08:18:15.597Z
// decoded - 2025-07-13T08:18:15.597Z
// Second precision
msid({ resolution: "second" })
// encoded - 1uaruZ ~ 6 chars
// current - 2025-07-13T08:18:15.597Z
// decoded - 2025-07-13T08:18:15.000Z
// Day precision
msid({ resolution: "day" })
// encoded - 05H8 ~ 4 chars
// current - 2025-07-13T08:18:15.597Z
// decoded - 2025-07-13T00:00:00.000Z
ms | second | day1970-01-01T00:00:00Z)0-9A-Za-z)msid(id) restores the exact instantbun add msid
# npm install msid
Based on the input type, it will either encode a Date to a string or decode a string back to a Date.
import msid from "msid"
// Encode current time
msid() // β UqofYU9
// Encode in resolution: "ms" default
msid({ resolution: "ms" }) // β UqofYU9
// Encode in resolution: "second"
msid({ resolution: "second" }) // β 1uaruZ
// Encode in resolution: "day"
msid({ resolution: "day" }) // β 05H8
// Decode in resolution: "ms" default
msid("UqofYU9") // β 2025-07-13T08:18:15.597Z
// Decode in resolution: "second"
msid("1uaruZ") // β 2025-07-13T08:18:15.000Z
// Decode in resolution: "day"
msid("05H8") // β 2025-07-13T00:00:00.000Z
// Custom epoch
msid({ epoch: "2000-01-01T00:00:00.000Z" }) // β EBT2bwj
// Custom alphabet
msid({ alphabet: "0123456789abcdef" }) // β 19802dd03ad
Platform: darwin
Architecture: arm64
CPU Model: Apple M2 Pro
CPU Cores: 12
Total Memory: 16.00 GB
Using hyperfine for benchmarking!
π Encode comparison (Node.js vs. Bun):
Benchmark 1: node ./test/bench.js msid
Time (mean Β± Ο): 352.0 ms Β± 3.7 ms [User: 333.6 ms, System: 10.2 ms]
Range (min β¦ max): 347.0 ms β¦ 366.1 ms 100 runs
Benchmark 2: bun ./test/bench.js msid
Time (mean Β± Ο): 319.0 ms Β± 3.8 ms [User: 313.5 ms, System: 14.3 ms]
Range (min β¦ max): 312.0 ms β¦ 329.7 ms 100 runs
Summary
bun ./test/bench.js msid ran
1.10 Β± 0.02 times faster than node ./test/bench.js msid
π Decode comparison (Node.js vs. Bun):
Benchmark 1: node ./test/bench.js decode
Time (mean Β± Ο): 92.7 ms Β± 2.0 ms [User: 80.4 ms, System: 6.3 ms]
Range (min β¦ max): 90.7 ms β¦ 108.2 ms 100 runs
Benchmark 2: bun ./test/bench.js decode
Time (mean Β± Ο): 53.4 ms Β± 1.9 ms [User: 54.1 ms, System: 9.5 ms]
Range (min β¦ max): 50.9 ms β¦ 65.4 ms 100 runs
Summary
bun ./test/bench.js decode ran
1.74 Β± 0.07 times faster than node ./test/bench.js decode
π MSID vs ULID encode time comparison:
Benchmark 1: node ./test/bench.js msid
Time (mean Β± Ο): 352.7 ms Β± 4.0 ms [User: 334.1 ms, System: 10.4 ms]
Range (min β¦ max): 347.8 ms β¦ 375.2 ms 100 runs
Benchmark 2: node ./test/bench.js ulid
Time (mean Β± Ο): 358.3 ms Β± 7.3 ms [User: 342.9 ms, System: 10.0 ms]
Range (min β¦ max): 329.8 ms β¦ 385.4 ms 100 runs
Summary
node ./test/bench.js msid ran
1.02 Β± 0.02 times faster than node ./test/bench.js ulid
MIT β LICENSE