{"slug": "ulid", "name": "ULID", "category": "dev-libs", "category_name": "Libraries and frameworks", "description": "", "recommenders": 3, "commenters": 5, "warners": 0, "score": 2.991, "rising": 0.35, "first": "2025-12-09", "latest": "2026-10-24", "why": "I've been using ULIDs [0] in prod for many years now, and I love them.", "why_is_quote": true, "has_verdict": false, "sentiment": {"recommend": 3, "neutral": 0, "compare": 2, "warn": 0}, "spark": [0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], "listed": true, "loved": [], "caveat": "", "short_quote": "I've been using ULIDs [0] in prod for many years now, and I love them.", "icon": true, "domain": null, "github_repo": "github.com/ulid/spec", "official_url": "https://github.com/ulid/spec", "pricing": "", "aliases": ["ULID"], "verdict": null, "praise": [{"label": "", "summary": "", "quotes": [{"id": 803536256, "item_id": 50221016, "url": "https://news.ycombinator.com/item?id=50221016", "by": "cpburns2009", "date": "2026-10-24", "stance": "recommend", "quote": "ULID is what I use.", "excerpt": "ULID is what I use. I convert it to UUID before storing in PostgreSQL. Technically it's an invalid serialization but it works. The system predates UUIDv7. I also like ULID's shorter representation.", "context": "", "use_case": "IDs stored in PostgreSQL", "switched_from": "", "story": "UUIDv7: Timestamps aren\u2019t time-ordered and other oddities"}, {"id": 740468016, "item_id": 46279251, "url": "https://news.ycombinator.com/item?id=46279251", "by": "kortex", "date": "2025-12-15", "stance": "recommend", "quote": "I've been using ULIDs [0] in prod for many years now, and I love them.", "excerpt": "I've been using ULIDs [0] in prod for many years now, and I love them. I just use string encoding, though if I really wanted to squeeze out every last MB, I could do some conversion so it is stored as 16 bytes instead of 26 chars. In practice it's never mattered, and the simplicity of just string IDs everywhere is nice. Sometimes I have to talk to legacy systems, all my APIs have str IDs, and I encode int IDs as just", "context": "", "use_case": "primary keys / IDs", "switched_from": "sequential int IDs", "story": "Avoid UUID Version 4 Primary Keys in Postgres"}, {"id": 740427120, "item_id": 46276695, "url": "https://news.ycombinator.com/item?id=46276695", "by": "sneak", "date": "2025-12-15", "stance": "recommend", "quote": "This is why ULID exists and why I use them in my ext_id columns.", "excerpt": "This is why ULID exists and why I use them in my ext_id columns. For the actual relational IDs internal to the db I use smaller/faster data types.", "context": "", "use_case": "external IDs in database", "switched_from": "", "story": "Avoid UUID Version 4 Primary Keys in Postgres"}]}], "caveats": [], "who": [], "tags": [], "use_cases": ["ids stored in postgresql", "sortable ids", "primary keys / ids", "external ids in database", "unique identifiers"], "compared": [{"slug": "postgresql", "name": "PostgreSQL", "co": 2, "switched_from": 0, "switched_to": 0}], "makers": [], "threads": [{"url": "https://news.ycombinator.com/item?id=50211746", "title": "UUIDv7: Timestamps aren\u2019t time-ordered and other oddities", "mentions": 2}, {"url": "https://news.ycombinator.com/item?id=46272487", "title": "Avoid UUID Version 4 Primary Keys in Postgres", "mentions": 2}, {"url": "https://news.ycombinator.com/item?id=46112965", "title": "ULID: Universally Unique Lexicographically Sortable Identifier", "mentions": 1}], "sentiment_by_month": {"2025-11": {}, "2025-12": {"compare": 1, "recommend": 2}, "2026-01": {}, "2026-02": {}, "2026-03": {}, "2026-04": {}, "2026-05": {}, "2026-06": {}, "2026-07": {}, "2026-08": {}, "2026-09": {}, "2026-10": {"compare": 1, "recommend": 1}}, "quotes": [{"id": 803536256, "item_id": 50221016, "url": "https://news.ycombinator.com/item?id=50221016", "by": "cpburns2009", "date": "2026-10-24", "stance": "recommend", "quote": "ULID is what I use.", "excerpt": "ULID is what I use. I convert it to UUID before storing in PostgreSQL. Technically it's an invalid serialization but it works. The system predates UUIDv7. I also like ULID's shorter representation.", "context": "", "use_case": "IDs stored in PostgreSQL", "switched_from": "", "story": "UUIDv7: Timestamps aren\u2019t time-ordered and other oddities"}, {"id": 803457809, "item_id": 50216113, "url": "https://news.ycombinator.com/item?id=50216113", "by": "rcoder", "date": "2026-10-23", "stance": "compare", "quote": "Older designs like ULIDs (https://github.com/ulid/spec) and Snowflake IDs", "excerpt": "If you really need monotonic, secure/unguessable IDs, there are options like CUID2 (github.com/paralleldrive/cuid2). Older designs like ULIDs (https://github.com/ulid/spec) and Snowflake IDs (https://en.wikipedia.org/wiki/Snowflake_ID) have similar properties to UUIDv7, and potentially some advantages w.r.t. length/encoding/runtime cost/etc. But UUIDv7 has one key advantage none of those do: you can store them in a U", "context": "", "use_case": "sortable IDs", "switched_from": "", "story": "UUIDv7: Timestamps aren\u2019t time-ordered and other oddities"}, {"id": 740468016, "item_id": 46279251, "url": "https://news.ycombinator.com/item?id=46279251", "by": "kortex", "date": "2025-12-15", "stance": "recommend", "quote": "I've been using ULIDs [0] in prod for many years now, and I love them.", "excerpt": "I've been using ULIDs [0] in prod for many years now, and I love them. I just use string encoding, though if I really wanted to squeeze out every last MB, I could do some conversion so it is stored as 16 bytes instead of 26 chars. In practice it's never mattered, and the simplicity of just string IDs everywhere is nice. Sometimes I have to talk to legacy systems, all my APIs have str IDs, and I encode int IDs as just", "context": "", "use_case": "primary keys / IDs", "switched_from": "sequential int IDs", "story": "Avoid UUID Version 4 Primary Keys in Postgres"}, {"id": 740427120, "item_id": 46276695, "url": "https://news.ycombinator.com/item?id=46276695", "by": "sneak", "date": "2025-12-15", "stance": "recommend", "quote": "This is why ULID exists and why I use them in my ext_id columns.", "excerpt": "This is why ULID exists and why I use them in my ext_id columns. For the actual relational IDs internal to the db I use smaller/faster data types.", "context": "", "use_case": "external IDs in database", "switched_from": "", "story": "Avoid UUID Version 4 Primary Keys in Postgres"}, {"id": 739373936, "item_id": 46210871, "url": "https://news.ycombinator.com/item?id=46210871", "by": "sblom", "date": "2025-12-09", "stance": "compare", "quote": "The cryptographic strength tradeoffs (against UUIDv7) seem rough for a lot of applications, though.", "excerpt": "I love the aesthetics. The cryptographic strength tradeoffs (against UUIDv7) seem rough for a lot of applications, though.", "context": "", "use_case": "unique identifiers", "switched_from": "", "story": "ULID: Universally Unique Lexicographically Sortable Identifier"}]}