[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"tools-page-uuid-v7-generator":3},{"page":4,"related":197,"variants":215},{"path":5,"name":6,"title":7,"description":8,"checkedAt":9,"sources":10,"faq":53,"related":72,"nuxter":76,"body":79,"tool":195,"preset":196},"\u002Ftools\u002Fuuid-v7-generator","UUID v7 generator","UUID v7 Generator and Decoder, with ULID and NanoID","A UUID v7 generator and decoder for RFC 9562 IDs, with ULID, NanoID and UUIDv4 to compare, a monotonic bulk mode, and Postgres 18, Drizzle and D1 code.","2026-10-06",[11,14,17,20,23,26,29,32,35,38,41,44,47,50],{"label":12,"url":13},"RFC 9562, Universally Unique IDentifiers (UUIDs)","https:\u002F\u002Fwww.rfc-editor.org\u002Frfc\u002Frfc9562",{"label":15,"url":16},"ULID specification","https:\u002F\u002Fgithub.com\u002Fulid\u002Fspec",{"label":18,"url":19},"Nano ID","https:\u002F\u002Fgithub.com\u002Fai\u002Fnanoid",{"label":21,"url":22},"PostgreSQL 18 docs, UUID functions","https:\u002F\u002Fwww.postgresql.org\u002Fdocs\u002F18\u002Ffunctions-uuid.html",{"label":24,"url":25},"PostgreSQL 18 docs, UUID type","https:\u002F\u002Fwww.postgresql.org\u002Fdocs\u002F18\u002Fdatatype-uuid.html",{"label":27,"url":28},"PostgreSQL 18 release notes","https:\u002F\u002Fwww.postgresql.org\u002Fdocs\u002F18\u002Frelease-18.html",{"label":30,"url":31},"Cloudflare D1 docs, SQL statements","https:\u002F\u002Fdevelopers.cloudflare.com\u002Fd1\u002Fsql-api\u002Fsql-statements\u002F",{"label":33,"url":34},"SQLite, Datatypes in SQLite","https:\u002F\u002Fsqlite.org\u002Fdatatype3.html",{"label":36,"url":37},"SQLite, Built-in scalar SQL functions","https:\u002F\u002Fsqlite.org\u002Flang_corefunc.html",{"label":39,"url":40},"Drizzle docs, PostgreSQL column types","https:\u002F\u002Form.drizzle.team\u002Fdocs\u002Fcolumn-types\u002Fpg",{"label":42,"url":43},"Drizzle docs, SQLite column types","https:\u002F\u002Form.drizzle.team\u002Fdocs\u002Fcolumn-types\u002Fsqlite",{"label":45,"url":46},"Drizzle docs, Indexes and constraints","https:\u002F\u002Form.drizzle.team\u002Fdocs\u002Findexes-constraints",{"label":48,"url":49},"Cloudflare Workers docs, Performance and timers","https:\u002F\u002Fdevelopers.cloudflare.com\u002Fworkers\u002Fruntime-apis\u002Fperformance\u002F",{"label":51,"url":52},"MDN, Crypto.getRandomValues()","https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FAPI\u002FCrypto\u002FgetRandomValues",[54,57,60,63,66,69],{"question":55,"answer":56},"What is UUID v7?","UUIDv7 is the time-ordered UUID version that RFC 9562 defined in May 2024. It starts with a Unix timestamp in milliseconds and fills the rest with random bits, so IDs made later sort after earlier ones and any machine can make them without coordination. It fits every column and library that accepts a UUID.",{"question":58,"answer":59},"Should I use UUIDv7 or UUIDv4 for primary keys?","UUIDv7, in most cases. RFC 9562 notes that random UUIDs such as v4 have poor index locality, because each insert lands at a random place in the B-tree, while a v7 key lands near the end the way an auto-increment key does. Pick v4 when an ID must not reveal when it was made.",{"question":61,"answer":62},"UUIDv7 or ULID: which should I use?","Both put a millisecond Unix time in front of random bits, in 128 bits. UUIDv7 is an IETF standard that fits the Postgres uuid type and every UUID library, while ULID is shorter as text and sorts as a string. Choose v7 when the column or the library expects a UUID, and ULID when the text form matters more.",{"question":64,"answer":65},"Does Postgres support UUIDv7?","Yes, from PostgreSQL 18, which added uuidv7() beside gen_random_uuid() and a new uuidv4() alias. uuidv7() takes an optional interval that shifts its timestamp, and uuid_extract_timestamp() reads the time back out. On PostgreSQL 17 or earlier, make the ID in your application and store it in a uuid column.",{"question":67,"answer":68},"How do I generate UUIDv7 IDs for Cloudflare D1?","In your Worker. D1 runs SQLite, whose built-in functions include no UUID generator, and D1's docs list none among its extensions. Copy the uuidv7() function from the Drizzle, D1 code above and hand it to Drizzle's $defaultFn, or call it before each insert.",{"question":70,"answer":71},"Can you get the creation time from a UUIDv7?","Yes. The first twelve hex digits are the Unix time in milliseconds, so anyone holding the ID can read when it was made, and the decoder above prints it. Don't use v7 where that time is private, and never as a secret.",[73,74,75],"cloudflare-d1-pricing-calculator","secret-key-generator","nuxt-environment-variables",{"body":77,"to":78},"Nuxter already stamps each analytics session with a UUIDv7, and its Drizzle schema runs on Postgres through Cloudflare Hyperdrive.","\u002Ffeatures",{"type":80,"value":81,"toc":186},"minimark",[82,87,91,94,98,121,124,128,143,146,150,153,162,166,176],[83,84,86],"h2",{"id":85},"what-uuidv7-is","What UUIDv7 is",[88,89,90],"p",{},"A UUIDv7 puts a Unix timestamp in milliseconds at the front and random bits behind it, with the version and variant bits in their usual places. RFC 9562 defined it in 2024, and the RFC asks implementations to prefer it over the older time-based versions 1 and 6. Because the time comes first, v7 IDs sort by creation in plain byte order or text order, with no parsing.",[88,92,93],{},"That ordering is the point. RFC 9562 notes that random UUIDs have poor index locality: each new v4 key lands at a random place in a B-tree, and the RFC calls the cost to those indexes dramatic. A v7 key lands near the end of the index, the way an auto-increment key does, and any server can still make one without asking the database.",[83,95,97],{"id":96},"how-it-compares-with-uuidv4-ulid-and-nanoid","How it compares with UUIDv4, ULID and NanoID",[99,100,101,109,115],"ul",{},[102,103,104,108],"li",{},[105,106,107],"strong",{},"UUIDv4"," is random apart from its version and variant. It reveals nothing, which makes it the right choice when creation time must stay private, and it scatters writes across an index.",[102,110,111,114],{},[105,112,113],{},"ULID"," has the same shape as UUIDv7, a millisecond time and then randomness, written in Crockford base32. It sorts as text, but it is a community spec rather than an IETF standard, and its bits are not a valid UUIDv7 because the version and variant bits are random too.",[102,116,117,120],{},[105,118,119],{},"NanoID"," is a short random string in a URL-safe alphabet. It carries no time, so it suits public IDs in URLs better than primary keys.",[88,122,123],{},"The table further down gives each format's length and bit counts, with a source for each.",[83,125,127],{"id":126},"uuidv7-as-a-primary-key-in-postgres-and-d1","UUIDv7 as a primary key in Postgres and D1",[88,129,130,131,135,136,139,140,142],{},"PostgreSQL 18 makes v7 a column default with ",[132,133,134],"code",{},"uuidv7()",". Its ",[132,137,138],{},"uuid"," type holds the 128-bit value rather than text, which is what RFC 9562 recommends for databases. On an older Postgres, keep the ",[132,141,138],{}," column and make the ID in your application: the type accepts any version.",[88,144,145],{},"D1 is SQLite, which has no UUID type, so each column stores IDs as TEXT or as a BLOB. TEXT reads well in queries and logs, and a BLOB is smaller. Keep one form per column, since SQLite never treats a TEXT value as equal to a BLOB. Within TEXT, keep one letter case too: digits sort below letters in either case, so all-lowercase and all-uppercase IDs each sort by time, but a mix does not.",[83,147,149],{"id":148},"what-a-v7-id-gives-away","What a v7 ID gives away",[88,151,152],{},"Anyone holding a v7 ID can read when it was made: the first twelve hex digits are the timestamp, and the decoder above prints it. That is harmless for most records, but it tells the world when a user signed up if their ID appears in a URL.",[88,154,155,156,161],{},"RFC 9562 is plain about security. UUIDs must not be used as security capabilities, and where an identifier plays any part in security, the RFC says to use v4. For a session token, a reset link or an API key, use a value from the ",[157,158,160],"a",{"href":159},"\u002Ftools\u002Fsecret-key-generator","secret key generator"," instead.",[83,163,165],{"id":164},"generating-v7-in-a-worker","Generating v7 in a Worker",[88,167,168,169,172,173,175],{},"Workers have ",[132,170,171],{},"crypto.getRandomValues",", so the ",[132,174,134],{}," function in the Worker code runs unchanged. One behaviour matters: as a guard against Spectre, a Worker's clock advances only after I\u002FO, so every ID made between two I\u002FO calls in a request carries the same millisecond. Their random bits keep them unique, but not in order.",[88,177,178,179,181,182,185],{},"When the order inside a request matters, count within the millisecond. RFC 9562 section 6.2 describes three methods, and this page's monotonic mode uses the first. Its counter starts at a random value with its top bit clear, which leaves it room to count, and if it does run out, the timestamp moves a millisecond ahead, which the RFC allows. Postgres's ",[132,180,134],{}," uses the third method and fills ",[132,183,184],{},"rand_a"," with time finer than a millisecond.",{"title":187,"searchDepth":188,"depth":188,"links":189},"",2,[190,191,192,193,194],{"id":85,"depth":188,"text":86},{"id":96,"depth":188,"text":97},{"id":126,"depth":188,"text":127},{"id":148,"depth":188,"text":149},{"id":164,"depth":188,"text":165},"uuid-v7-generator",null,[198,204,209],{"path":199,"tool":73,"name":200,"title":201,"description":202,"summary":203,"checkedAt":9},"\u002Ftools\u002Fcloudflare-d1-pricing-calculator","Cloudflare D1 pricing calculator","Cloudflare D1 Pricing Calculator and Batch Limits","Cloudflare D1 pricing calculator. Turn users and queries into rows read and written, check the Free plan's daily limits, and size batch inserts under D1's caps.","Rows read and written, storage and the Free plan's daily limits, plus batch sizes that fit D1's caps.",{"path":159,"tool":74,"name":205,"title":206,"description":207,"summary":208,"checkedAt":9},"Secret key generator","Secret Key Generator for .env, JWT and Webhooks","Generate random secret keys in your browser for NUXT_SESSION_PASSWORD, Better Auth, JWT and webhook signing, as hex, base64, base64url or letters and digits.","Secrets for NUXT_SESSION_PASSWORD, Better Auth, JWT and webhooks, as hex, base64 or base64url, with the .env and Wrangler lines.",{"path":210,"tool":75,"name":211,"title":212,"description":213,"summary":214,"checkedAt":9},"\u002Ftools\u002Fnuxt-environment-variables","Nuxt environment variables","Nuxt Environment Variables: runtimeConfig to NUXT_","Paste a nuxt.config to get the Nuxt environment variables that override each runtimeConfig key, the type each value arrives as and the names that collide.","Paste a nuxt.config and get the NUXT_ variable for every runtimeConfig key, the type it arrives as and the names that collide.",[]]