NanoID Generator Tool

Generate compact random NanoIDs with customizable formatting.

Format:
Encoding:
?
?
?
    

Use these GUIDs at your own risk! No guarantee of their uniqueness or suitability is given or implied.

Your Daily Fortune

NanoID: Engineering Guide to Compact IDs

If you've ever looked at a URL and wondered why some sites use 36-character hyphenated strings while others use short, punchy, random-looking codes, you're looking at the difference between UUIDv4 and NanoID. For many developers, the transition to NanoID is about moving away from the "standard but bulky" approach toward something that balances security, collision resistance, and a better user experience.

This guide explores the technical trade-offs of NanoID, specifically for those of us managing databases, designing APIs, and optimizing for scale.

What is NanoID?

NanoID is a compact, URL-friendly, unique string ID generator. While it's often lumped in with the "UUID" family, it's fundamentally different. A UUID is a 128-bit binary number usually represented in hexadecimal. NanoID, on the other hand, is a string generator that uses a larger alphabet (by default, Base64-ish) to pack more entropy into fewer characters.

The "magic" of NanoID is that it allows you to customize the alphabet and the length. Because it uses a larger character set than the 16 characters of hex (0-9, a-f), it can achieve the same probability of collision as a UUIDv4 but with a significantly shorter string. It's designed to be fast, secure (using CSPRNG), and extremely lightweight.

Who uses it, and how is it used at PlanetScale?

NanoID is primarily used by Full-Stack Developers, Frontend Engineers, and Systems Architects.

  • Frontend Engineers use it for generating stable keys for React/Vue components or temporary IDs for client-side state management where a full UUID is overkill.
  • API Architects use it to generate public-facing resource identifiers that are unguessable and clean.
  • QA/Testers often use NanoID-based identifiers in test data generators to ensure that simulated records don't collide during massive parallel test runs.

The PlanetScale Context At PlanetScale, the focus is on scaling MySQL to an extreme degree using Vitess. In a sharded database environment, the "identity problem" is a major architectural hurdle. You can't use a standard auto-incrementing integer because every shard would have its own sequence, leading to collisions the moment you try to aggregate data or move records between shards.

PlanetScale and the engineers who use it often employ "random" identifiers (similar to the logic of NanoID) to ensure global uniqueness across distributed shards. By using a high-entropy string as a lookup key, they can distribute data across a cluster without needing a central "ID authority" that would otherwise become a bottleneck. However, as discussed later in the database section, they are careful about how these are physically stored to avoid killing the performance of the underlying MySQL engine.

How is it used?

In a typical implementation, NanoID is used as a "Public ID."

The workflow usually looks like this:

  1. Generation: The application generates a NanoID (e.g., V1StGXR8_Z5jdL4K-myT6) at the moment of record creation.
  2. Exposure: This ID is placed in the URL: example.com/project/V1StGXR8_Z5jdL4K-myT6.
  3. Lookup: When a request hits the server, the app queries the database for the record associated with that specific NanoID string.

Because the library is so small, it's often used on the client-side to generate an ID before the data is even sent to the server, allowing the frontend to track the object immediately without waiting for a database round-trip.

Why was it created?

NanoID was created to solve the "UUID Fatigue" problem. UUIDv4 is great for uniqueness, but it has three major flaws in a web context:

  1. Size: A 36-character string is simply too long for a clean URL.
  2. Encoding: Hexadecimal is inefficient. If you use more characters (A-Z, a-z, 0-9), you can represent the same amount of randomness in a much shorter string.
  3. Rigidity: The UUID standard is strict. You can't just decide to make a "10-character UUID." NanoID provides a tunable dial where you can trade off length for collision probability.

Is it suitable for databases?

This is where we need to be honest: NanoID is a fantastic application-level identifier, but a dangerous database primary key.

If you use a NanoID as your Clustered Index (the physical ordering of data on disk), you are creating a performance nightmare. Because NanoIDs are random, new rows are inserted into random pages. This causes "B-Tree Fragmentation" or "Page Splits." The database has to constantly shift data around on the disk to insert the new random ID, which tanks your write throughput and increases I/O latency.

Here is the breakdown by engine:

  • MySQL (InnoDB): Not suitable as a Primary Key. Use a BIGINT AUTO_INCREMENT as the clustered key and store the NanoID in a VARCHAR column with a UNIQUE index.
  • PostgreSQL: More tolerant. Postgres handles TEXT keys better than MySQL handles random strings, but at high scale, you'll still see a performance dip compared to sequential keys.
  • SQL Server: Not suitable as the Clustered Index. Use UNIQUEIDENTIFIER (if you want UUIDs) or an integer, and keep NanoID as a non-clustered secondary key.
  • Oracle & SQLite: Same story. Avoid using random strings for physical storage ordering.
  • Amazon RDS / Azure SQL / Google Cloud SQL: Since these are managed versions of the above, the same physics apply. Random inserts = high I/O = higher cost and lower performance.

Is it suitable for URLs?

Absolutely. This is its primary purpose.

NanoID is designed specifically for the URL. It uses a URL-safe alphabet (no characters that require % encoding) and is significantly shorter than a UUID. Furthermore, it prevents ID Enumeration. If your URL is myapp.com/invoice/1001, any competitor can just try 1002 to see your other invoices. A NanoID like myapp.com/invoice/kS9_2mPzL is impossible to guess.

Is it sortable?

No.

NanoID is entirely random. There is no timestamp, no sequence, and no logic to its ordering. If you need to sort your records by "Date Created," you cannot use the NanoID. You must include a created_at timestamp column and index it. If you need an ID that is both unique and sortable, you should look at UUIDv7 or ULID instead.

Comparison vs other UUID types

When choosing an ID, you're balancing three things: Collision Resistance, Database Performance, and URL Aesthetics.

  • UUIDv1: Time-based. Sortable, but leaks the MAC address of the server. Not used much in modern web apps.
  • UUIDv4: The gold standard for randomness. 128-bit. Great for uniqueness, but bulky (36 chars) and terrible for DB indexes.
  • UUIDv7: The new king of DB keys. It's time-sorted, meaning it doesn't fragment the index, but it's still 36 characters long.
  • ULID: Similar to UUIDv7. Sortable and uses a more compact Base32 encoding.
  • NanoID: The winner for URLs. Not sortable, potentially fragments DBs if used as a primary key, but provides the best user experience and flexibility.

Comparison Table

Identifier Bit Length Sortable DB Performance URL Friendly Encoding
UUIDv4 128 No Poor Medium Hex
UUIDv7 128 Yes Excellent Medium Hex
ULID 128 Yes Excellent High Base32
UULID 128 Yes Excellent Medium Hex
NanoID Variable No Poor Excellent Alphabet

Final Engineering Summary

If you are a developer trying to decide which ID to use, follow this rule of thumb:

  1. Need a primary key for a massive SQL table? Use UUIDv7 or a BigInt.
  2. Need a public-facing ID for a URL? Use NanoID.
  3. Need a globally unique ID that doesn't matter for sorting? Use UUIDv4.

The biggest mistake I see is developers using NanoID as the only key in their database. Don't do that. Use a sequential integer for your database's internal "physical" identity and use the NanoID as the "logical" identity for your API and users. This gives you the best of both worlds: blazing fast database writes and clean, secure, professional URLs.


What is the Nano ID Text Layout?

A-Za-z0-9_- 21 Random Characters
Alphabet: A-Z a-z 0-9 _ -
Length: 21 characters (default)
Bits per character: 6
Total entropy: 126 random bits

What is the Nano ID Binary Bit Layout?

126 Random Bits 21 × 6-bit characters
Total: 126 bits (default)
Random: 126 bits
Reserved: None
Version: None
Variant: None