[{"data":1,"prerenderedAt":466},["ShallowReactive",2],{"guide-uuid-vs-ulid":3},{"id":4,"title":5,"body":6,"date":456,"description":457,"extension":458,"meta":459,"navigation":460,"path":461,"readingTime":462,"seo":463,"stem":464,"__hash__":465},"guides\u002Fguides\u002Fuuid-vs-ulid.md","UUID vs ULID: Which Unique Identifier to Choose",{"type":7,"value":8,"toc":433},"minimark",[9,14,27,31,146,151,162,165,169,172,194,197,201,204,258,261,265,268,272,286,290,312,316,319,322,326,330,341,345,359,363,396,400,421,425],[10,11,13],"h2",{"id":12},"the-short-answer","The Short Answer",[15,16,17,18,22,23,26],"p",{},"Use ",[19,20,21],"strong",{},"UUID v7"," if you want broad ecosystem support with sortability. Use ",[19,24,25],{},"ULID"," if you want sortability plus a compact, URL-safe string. Both are better than UUID v4 for database-heavy applications.",[10,28,30],{"id":29},"format-comparison","Format Comparison",[32,33,34,51],"table",{},[35,36,37],"thead",{},[38,39,40,44,47,49],"tr",{},[41,42,43],"th",{},"Property",[41,45,46],{},"UUID v4",[41,48,21],{},[41,50,25],{},[52,53,54,70,85,100,116,131],"tbody",{},[38,55,56,62,65,67],{},[57,58,59],"td",{},[19,60,61],{},"Length",[57,63,64],{},"36 chars",[57,66,64],{},[57,68,69],{},"26 chars",[38,71,72,77,80,82],{},[57,73,74],{},[19,75,76],{},"Encoding",[57,78,79],{},"Hex + hyphens",[57,81,79],{},[57,83,84],{},"Crockford's Base32",[38,86,87,92,95,98],{},[57,88,89],{},[19,90,91],{},"Timestamp",[57,93,94],{},"None",[57,96,97],{},"48-bit ms",[57,99,97],{},[38,101,102,107,110,113],{},[57,103,104],{},[19,105,106],{},"Random bits",[57,108,109],{},"122",[57,111,112],{},"62",[57,114,115],{},"80",[38,117,118,123,126,129],{},[57,119,120],{},[19,121,122],{},"Sortable",[57,124,125],{},"No",[57,127,128],{},"Yes",[57,130,128],{},[38,132,133,138,141,143],{},[57,134,135],{},[19,136,137],{},"URL-safe",[57,139,140],{},"Mostly",[57,142,140],{},[57,144,145],{},"Yes (no hyphens)",[147,148,150],"h3",{"id":149},"visual-comparison","Visual Comparison",[152,153,158],"pre",{"className":154,"code":156,"language":157},[155],"language-text","UUID v4:  f47ac10b-58cc-4372-a567-0e02b2c3d479   (random)\nUUID v7:  0190a6a8-7b1c-7d3e-8f2a-5c9b1d3e4f5a   (time-prefixed)\nULID:     01ARZ3NDEKTSV4RRFFQ69G5FAV              (time-prefixed, compact)\n","text",[159,160,156],"code",{"__ignoreMap":161},"",[15,163,164],{},"Notice how v7 and ULID share the same timestamp prefix — both encode the generation time at the start of the identifier.",[10,166,168],{"id":167},"sortability-the-real-difference","Sortability: The Real Difference",[15,170,171],{},"UUID v4 generates identifiers in random order. When inserted into a B-tree index, each new row lands in a random leaf node, causing:",[173,174,175,182,188],"ul",{},[176,177,178,181],"li",{},[19,179,180],{},"Page splits",": Database constantly reorganizes index pages",[176,183,184,187],{},[19,185,186],{},"Cache misses",": Random page access defeats the buffer pool",[176,189,190,193],{},[19,191,192],{},"Write amplification",": Fragmented inserts trigger more I\u002FO",[15,195,196],{},"UUID v7 and ULID solve this by prefixing a timestamp. New rows append to the right edge of the index, just like auto-increment IDs.",[147,198,200],{"id":199},"benchmark-impact","Benchmark Impact",[15,202,203],{},"In PostgreSQL with 10M rows:",[32,205,206,218],{},[35,207,208],{},[38,209,210,213,215],{},[41,211,212],{},"Metric",[41,214,46],{},[41,216,217],{},"UUID v7 \u002F ULID",[52,219,220,233,246],{},[38,221,222,227,230],{},[57,223,224],{},[19,225,226],{},"Insert throughput",[57,228,229],{},"~35K rows\u002Fsec",[57,231,232],{},"~55K rows\u002Fsec",[38,234,235,240,243],{},[57,236,237],{},[19,238,239],{},"Index size",[57,241,242],{},"~1.4× larger",[57,244,245],{},"Baseline",[38,247,248,253,256],{},[57,249,250],{},[19,251,252],{},"Table size",[57,254,255],{},"Similar",[57,257,255],{},[15,259,260],{},"The exact numbers vary by hardware and configuration, but the pattern is consistent: time-ordered identifiers significantly outperform random ones at scale.",[10,262,264],{"id":263},"uuid-v7-vs-ulid-which-one","UUID v7 vs ULID: Which One?",[15,266,267],{},"Since both are time-ordered, the decision comes down to practical differences.",[147,269,271],{"id":270},"choose-uuid-v7-when","Choose UUID v7 When",[173,273,274,277,280,283],{},[176,275,276],{},"Your database has native UUID type support (PostgreSQL, Cassandra)",[176,278,279],{},"You want RFC-standardized identifiers",[176,281,282],{},"You rely on existing UUID parsing libraries",[176,284,285],{},"You store identifiers as 128-bit binary (16 bytes) rather than text",[147,287,289],{"id":288},"choose-ulid-when","Choose ULID When",[173,291,292,295,298,309],{},[176,293,294],{},"You want the most compact text representation (26 vs 36 characters)",[176,296,297],{},"Identifiers appear in URLs, logs, or user-facing strings",[176,299,300,301,304,305,308],{},"You need case-insensitive comparison (Crockford's Base32 avoids ambiguous characters like ",[159,302,303],{},"0","\u002F",[159,306,307],{},"O",")",[176,310,311],{},"You want monotonic generation within the same millisecond",[147,313,315],{"id":314},"monotonicity","Monotonicity",[15,317,318],{},"ULID's spec defines monotonic generation: within the same millisecond, each new ULID increments the random portion instead of regenerating it. This guarantees strict ordering even for sub-millisecond inserts.",[15,320,321],{},"UUID v7's spec allows monotonic generation but does not mandate it. Implementations vary — check your library.",[10,323,325],{"id":324},"migration-considerations","Migration Considerations",[147,327,329],{"id":328},"from-uuid-v4-to-uuid-v7","From UUID v4 to UUID v7",[173,331,332,335,338],{},[176,333,334],{},"Drop-in replacement in most systems — same 128-bit width, same text format",[176,336,337],{},"Existing v4 IDs remain valid; no data migration needed",[176,339,340],{},"Mixed v4\u002Fv7 columns still work; new rows simply benefit from sortability",[147,342,344],{"id":343},"from-uuid-to-ulid","From UUID to ULID",[173,346,347,350,353,356],{},[176,348,349],{},"Column type may need to change (UUID → text or binary)",[176,351,352],{},"String length changes (36 → 26), affecting foreign keys and indexes",[176,354,355],{},"Existing UUID data must be migrated or stored alongside new ULIDs",[176,357,358],{},"Higher migration cost — plan accordingly",[10,360,362],{"id":361},"practical-recommendations","Practical Recommendations",[364,365,366,372,378,384,390],"ol",{},[176,367,368,371],{},[19,369,370],{},"New project, PostgreSQL",": Use UUID v7 — native type support keeps storage at 16 bytes",[176,373,374,377],{},[19,375,376],{},"New project, MySQL\u002FSQLite",": Use ULID — text encoding avoids binary column complexity",[176,379,380,383],{},[19,381,382],{},"Existing project with UUID v4",": Switch new inserts to UUID v7 — zero migration cost",[176,385,386,389],{},[19,387,388],{},"High-throughput logging",": Use ULID — compact strings reduce I\u002FO and storage",[176,391,392,395],{},[19,393,394],{},"Client-generated IDs",": Either works; ULID's shorter string is easier to pass in URLs",[10,397,399],{"id":398},"related-guides","Related Guides",[173,401,402,409,415],{},[176,403,404],{},[405,406,408],"a",{"href":407},"\u002Fguides\u002Fuuid-versions-explained","UUID Versions Explained",[176,410,411],{},[405,412,414],{"href":413},"\u002Fguides\u002Funique-identifiers-guide","Unique Identifiers Guide",[176,416,417],{},[405,418,420],{"href":419},"\u002Fguides\u002Fhashing-algorithms-explained","Hashing Algorithms Explained",[10,422,424],{"id":423},"try-it-yourself","Try It Yourself",[15,426,427,428,432],{},"Generate and compare UUID v4, v7, and ULID formats instantly with our free ",[405,429,431],{"href":430},"\u002Ftools\u002Fuuid-generator","UUID Generator",". See sortability in action — paste a batch of v4 vs v7 IDs and watch the ordering difference.",{"title":161,"searchDepth":434,"depth":434,"links":435},2,[436,437,441,444,449,453,454,455],{"id":12,"depth":434,"text":13},{"id":29,"depth":434,"text":30,"children":438},[439],{"id":149,"depth":440,"text":150},3,{"id":167,"depth":434,"text":168,"children":442},[443],{"id":199,"depth":440,"text":200},{"id":263,"depth":434,"text":264,"children":445},[446,447,448],{"id":270,"depth":440,"text":271},{"id":288,"depth":440,"text":289},{"id":314,"depth":440,"text":315},{"id":324,"depth":434,"text":325,"children":450},[451,452],{"id":328,"depth":440,"text":329},{"id":343,"depth":440,"text":344},{"id":361,"depth":434,"text":362},{"id":398,"depth":434,"text":399},{"id":423,"depth":434,"text":424},"2026-05-27","Compare UUID and ULID identifiers. Learn about sortability, database performance, and when ULID is the better choice.","md",{"immutable":460},true,"\u002Fguides\u002Fuuid-vs-ulid",6,{"title":5,"description":457},"guides\u002Fuuid-vs-ulid","wrSdPEj95kU_6bCgiCnJa7vMymn_NZa2FBaqVm5FPyc",1780401325804]