DEV Community

Cover image for Comparing Four Practical Ways to Generate UUIDs at Work
Tea-sip for Lizely

Posted on

Comparing Four Practical Ways to Generate UUIDs at Work

If you've ever needed a unique identifier — for a database row, an upload, a fixture, a session token, an event id — you've hit the same question every engineer faces: how do I actually get one? There are at least four common answers, and they each shine in different situations. This article walks through doing it by hand, using a spreadsheet, firing up a small script, and using a purpose-built web page. The goal is to help you pick the right approach for the job in front of you, not to crown a single winner.

Why the choice matters more than it looks

A universally unique identifier looks innocent — 550e8400-e29b-41d4-a716-446655440000 — but the way you mint one has real consequences. Copy-pasting from chat threads gives you duplicates. Spreadsheets re-roll values when you sort a column. Homegrown scripts may quietly drift toward a non-standard format. And a server-side AUTO_INCREMENT column masquerades as a unique id but leaks business data the moment it appears in a URL.

The official spec, RFC 4122, defines the structure, the version bits, and the variant bits that make a value universally unique. Reading just the first page is enough to see that the format isn't accidental: the version digit (the first character of the third group) tells you how the id was minted, and the variant digit (the first character of the fourth group) tells you which family it belongs to. Once you internalize that, the right generation strategy stops being a coin flip.

Approach 1: doing it by hand (or copy-pasting from chat)

When this is fine

If you need three or four values to seed a sample config, you can mint them by hand, paste them from a colleague's message, or grab them from a Stack Overflow answer. It's free, instant, and good enough for a one-off demo.

Where it falls apart

  • Duplicates are practically guaranteed once you pass ten values.
  • You have no idea which version (v1, v4, v7) you've produced.
  • The values aren't reproducible across teammates, so a bug report that says "this id crashes the parser" becomes impossible to reproduce.

Treat manual creation as a debugging scratchpad, not a workflow.

Approach 2: a spreadsheet

Why people reach for it

Spreadsheets are everywhere. A column full of formulas, drag-down fill, and you've got a hundred values in a minute. Teams that already live in Google Sheets for test data gravitate here without thinking.

The honest trade-offs

  • Most spreadsheet engines don't ship a true random source; many expose RAND() or UUID() (in newer versions) and call it a day. Check what your sheet actually offers before trusting it.
  • Sorting a column of generated values can re-trigger the formula on some engines and silently rewrite your data.
  • You can't easily switch between v4 and v7 without rebuilding the formula chain.
  • Sharing the workbook means everyone has the same generator version — good — but the workbook also carries formulas, formatting, and stale tabs — bad.

A spreadsheet is reasonable for a fixture file under five hundred rows that won't be sorted or shared widely. Beyond that, the maintenance cost eats the convenience.

Approach 3: a short script in your language of choice

What this looks like

In Node, you call crypto.randomUUID() and move on with your life. In Python, uuid.uuid4() or uuid.uuid7() (depending on your version). In Go, google/uuid. In Java, java.util.UUID. Each one returns a v4 by default and is backed by the operating system's secure randomness.

The case for scripting

  • Cryptographically strong randomness by default (MDN's crypto.randomUUID() reference documents the browser equivalent and the version-4 guarantee).
  • Reproducible across machines and CI runners.
  • Easy to plumb into seed scripts, migrations, and test fixtures.
  • Lets you choose v1, v4, v7, or nil based on your indexing strategy.

The case against

  • You need write access to a repo, a terminal, or a CI runner. Product managers and QA folks often don't have any of those.
  • The first-time setup cost — installing a runtime, picking a library, deciding on a format — is real, even if it's small.
  • Generated values disappear into stdout unless you remember to redirect them to a file.

If you already write code for a living, this is the right default. The deeper walkthrough, including the browser variant and edge cases, lives in this practical guide on generating identifiers in JavaScript.

Approach 4: a purpose-built web tool

Where it fits

There are moments when you don't want a terminal. Maybe you're producing fixtures for a manual QA pass, maybe you're pasting values into a ticket for a customer-support reproduction, or maybe you simply need twenty v7 strings in a copy-friendly format. A focused page that lets you pick a count, pick a version, and copy the output is exactly the right shape for those moments.

What to check before trusting one

A reliable page should:

  1. Let you pick v1, v4, v7, or nil rather than producing only one flavor.
  2. Run the entropy in your browser, not on a server, so nothing leaks.
  3. Offer bulk output (tens to thousands) with line, comma, or JSON delimiters.
  4. Be predictable — running the same request twice should produce the same count and format, even if the actual values differ.

Where it doesn't fit

  • Production traffic. If your service issues millions of identifiers per hour, you do that in code, in your service, with an audited library.
  • Compliance-sensitive flows where you must prove the randomness source. A webpage can't sign an attestation.

A browser-based generator is a force multiplier for the occasional, human-paced task. For everything else, prefer the script.

A quick recommendation matrix

Situation Best fit Why
One-off demo or blog post By hand Cheapest possible path
50–500 fixture rows in a shared sheet Spreadsheet Everyone already has access
CI fixtures, migrations, anything reproducible Script Strongest randomness, version control, deterministic pipeline
Manual QA, customer-repro tickets, bulk copy Web tool Zero setup, shareable output
High-throughput service Library in-process Performance, audit trail, no network round trip

Match the row to your real situation and you'll rarely regret the choice.

Operational checklist before you commit

Before you start producing values at scale, run through this list once. It takes a minute and prevents 90% of the "why do we have collisions" postmortems:

  1. Decide which version you need. v4 is the safe default; v7 is better when your database sorts by primary key.
  2. Confirm the generator runs locally (in-browser or in-process) rather than calling an external API.
  3. Agree on a delimiter — newline, comma, JSON array — so consumers can parse without guessing.
  4. Cap the count per request. If a teammate asks for 10 million values from a webpage, something is wrong upstream.
  5. Document the chosen version in the README next to the fixture file so the next engineer doesn't wonder.

Frequently asked questions

Which version should I default to in 2025?

For most application ids, version 4 is still the default choice. If your database is a B-tree store (Postgres, MySQL with InnoDB, SQLite) and you index the primary key, version 7 gives you roughly time-ordered values that insert near the end of the index and avoid page splits. See the version field definition in RFC 4122 §4.4 for the bit layout.

Are online generators safe to use?

It depends on what the page does. A trustworthy one runs the entropy in your browser and never sends your request to a backend. Look for client-side implementation details in the page source or a privacy note. Avoid tools that require login, upload, or "save your history" features for what should be a stateless operation.

Why does my spreadsheet sometimes show duplicate values?

Two common causes. First, some engines generate values via a non-cryptographic RAND() and reseed on each calculation, so sorting a column can produce collisions. Second, copy-paste between sheets sometimes flattens formulas to literal values, and a literal value reused across rows is, by definition, a duplicate. Switch to a deterministic script if either failure mode has bitten you.

Can I use these values as security tokens?

Version 4 ids produced by a cryptographically secure source (crypto.randomUUID() in browsers, uuid.uuid4() backed by /dev/urandom on Linux, google/uuid in Go) are suitable as opaque session or correlation tokens. Do not use a hand-typed or spreadsheet-generated value for anything security-relevant — the entropy is too low and the audit story is nonexistent.


This article was drafted with AI assistance and reviewed for technical accuracy before publishing.

Top comments (0)