It looks like a throwaway decision. Every row needs a unique ID, so you reach for whatever your framework defaults to and move on. But the type of identifier you pick ripples through index performance, URL security, and how easily your system scales across servers. It's worth five minutes of thought up front.
Auto-increment integers
The classic default: 1, 2, 3, and so on. They're compact, human-readable, and index beautifully because each new value slots neatly onto the end of a B-tree. For a single-database app, they're genuinely hard to beat.
- Upside: tiny (4–8 bytes), fast inserts, naturally ordered by creation.
- Downside: they leak information — /users/1042 tells anyone your rough user count and lets them guess neighbors.
- Downside: generating them requires coordination, which gets painful across multiple databases or in offline-first clients.
UUIDs
A UUID is a 128-bit value, usually shown as 36 characters like 3f2504e0-4f89-41d3-9a0c-0305e82c3301. The key advantage: any machine can generate one independently with effectively zero chance of collision — no central coordinator required.
v4 vs v7 — the version matters
UUIDv4 is fully random, which is why it scatters writes across your index and can hurt insert performance at scale. UUIDv7 embeds a timestamp prefix, so values sort roughly by creation time and behave far better as a database key. If you're choosing a UUID today, v7 is usually the one you want.
UUID Generator
Generate v4 UUIDs instantly — handy for seeding test data, config keys, or scratch identifiers.
ULIDs
A ULID tries to give you the best of both: it's a 128-bit ID like a UUID, but encoded as a compact 26-character string that's lexicographically sortable by time. Like UUIDv7, its timestamp prefix keeps index inserts orderly, and the shorter, case-insensitive encoding is friendlier in URLs and logs.
How to choose
- Single database, internal IDs, don't mind exposing counts → auto-increment integers. Simple and fast.
- Distributed systems, public-facing IDs, or client-generated records → UUIDv7 or ULID for coordination-free, non-guessable, index-friendly keys.
- Stuck on UUIDv4 already? It works fine at small-to-medium scale; consider v7 before it becomes an index bottleneck.
Never use a random ID as your only security layer
An unguessable UUID in a URL is not authorization. It raises the bar, but anyone who obtains the link still gets in. Always enforce real access checks on the server.
There's no universally correct answer — only the right trade-off for your system. But knowing why v7 sorts and v4 scatters, or when a leaked count actually matters, turns a reflexive default into a deliberate choice.