NanoID Generator

Generate compact, URL-friendly NanoIDs with custom formatting, encoding, and bulk export (up to 1,000).
Format:
Encoding:
    

Fast, reliable, and built for developers. We don't store the UUIDs you generate.

Tools, UUID Versions Guide, dozens of articles in UUIDs In Databases & Engineering Blog.

NanoID: Engineering Guide to Compact IDs

NanoID is a compact, configurable identifier generator designed for applications that need short random IDs. Its default configuration produces 21-character identifiers using a 64-character URL-safe alphabet.

Unlike UUIDs, NanoID is not a fixed 128-bit identifier format. Its length and alphabet can be configured, allowing developers to choose the size of the identifier space based on the application's requirements.

NanoID is particularly useful for public-facing identifiers in URLs, APIs, database records, client-side objects, and other places where a shorter identifier is preferable to a conventional UUID string.

The main trade-off is straightforward: NanoID gives you compact random identifiers, but it does not provide chronological ordering and its random distribution can be less favorable for database index locality than sequential or time-ordered identifiers.

What Is NanoID?

NanoID is a small library and identifier format for generating random strings.

The default NanoID configuration uses:

  • 21 characters
  • A 64-character URL-safe alphabet
  • A cryptographically secure random number generator
  • 126 bits of information in the resulting identifier

The 126-bit figure comes from the default configuration:

21 × log2(64) = 126 bits

Unlike UUID v4, NanoID does not reserve bits for a version or variant. It is also configurable, so the length, alphabet, and resulting collision resistance can be changed by the application.

For example, a developer can choose a shorter identifier when a smaller collision space is acceptable, or a longer identifier when a larger identifier space is required.

This flexibility is one of NanoID's main advantages over fixed-format identifiers.

Who Uses NanoID?

NanoID is useful for developers who need compact identifiers without depending on a central ID generator.

Common users and use cases include:

  • Backend developers use NanoID for public resource identifiers, database records, API objects, and generated application data.
  • Frontend developers can generate temporary identifiers for client-side objects before those objects are sent to a server.
  • API developers use NanoID when resource URLs need shorter identifiers than conventional UUID strings.
  • Test engineers can use NanoID to generate large quantities of independent test data.
  • System architects can use NanoID when distributed components need to create identifiers without coordinating through a central sequence.

NanoID is not limited to high-scale systems. It can be useful in a small application simply because a 21-character identifier is more convenient in a URL than a 36-character UUID.

How Is NanoID Used?

A common pattern is to use NanoID as a public identifier.

For example:

https://example.com/projects/V1StGXR8_Z5jdL4K-myT6

The application can generate the identifier when the project is created and store it with the corresponding record.

A typical workflow is:

  1. Generation: The application generates a NanoID when an object is created.
  2. Storage: The identifier is stored with the object or record.
  3. Exposure: The identifier is returned through an API or placed in a URL.
  4. Lookup: A subsequent request uses the identifier to locate the associated record.

NanoID can also be generated on the client before an object is sent to a server. This is useful when a frontend needs an identifier immediately rather than waiting for the database to create one.

The identifier itself does not require a round trip to a central database sequence.

Why Was NanoID Created?

NanoID addresses a practical problem with conventional identifiers: sometimes developers need a random identifier, but a standard UUID string is unnecessarily long for the application's interface.

A canonical UUID string contains 36 characters:

550e8400-e29b-41d4-a716-446655440000

The default NanoID is only 21 characters:

V1StGXR8_Z5jdL4K-myT6

The difference comes primarily from the alphabet used to represent the identifier. Hexadecimal UUID strings use only 16 possible characters per position, while the default NanoID alphabet provides 64 possible characters.

A larger alphabet allows more information to be represented in each character.

NanoID also makes the length configurable. Developers can therefore choose an identifier size appropriate for the application's collision requirements instead of being locked into a fixed 128-bit format.

How Many Bits Does NanoID Have?

NanoID does not have one fixed number of bits because its length and alphabet are configurable.

The default NanoID contains 21 characters selected from a 64-character alphabet.

Because 64 is 2^6, each character represents 6 bits of information:

21 × 6 = 126 bits

Therefore, the default NanoID has a 126-bit identifier space.

That gives:

2^126

possible combinations, or approximately:

8.5 × 10^37

possible identifiers.

This is a very large space. Accidental collisions are extremely unlikely when NanoID is correctly generated and used at its default length.

However, the probability of a collision depends on how many identifiers are generated. It also depends directly on the chosen length and alphabet.

A 10-character NanoID does not have the same collision resistance as the default 21-character NanoID.

Is NanoID Secure?

NanoID uses a cryptographically secure random number generator in its standard implementation, which makes properly generated identifiers difficult to predict.

That makes NanoID useful when an application wants public identifiers that are impractical to enumerate.

However, unguessable is not the same as secure authorization.

A NanoID should be treated as an identifier, not as an authentication credential.

For example, an API should not assume that a user is authorized to access:

/api/invoices/V1StGXR8_Z5jdL4K-myT6

simply because the identifier is difficult to guess.

The server should authenticate the request and verify that the authenticated user or service has permission to access the referenced resource.

For password-reset tokens, session credentials, API secrets, and other security-sensitive values, use a purpose-built token mechanism rather than relying on an identifier format.

Is NanoID Suitable for Databases?

Yes, but the answer depends on how the identifier is used.

NanoID can be stored as a database key, including a primary key. However, because NanoIDs are normally randomly distributed, they do not provide the chronological locality of UUID v7, ULID, or sequential numeric identifiers.

In a B-tree index, random keys can cause inserts to occur throughout the index rather than primarily near the newest pages. At sufficient scale and write volume, this can increase page splits, reduce cache locality, and increase index maintenance.

That does not mean NanoID is automatically a bad database key.

For a small or moderately sized application, the difference may be insignificant. For a large, write-heavy table, it is worth benchmarking random NanoID keys against sequential or time-ordered alternatives.

The database engine and schema also matter.

MySQL and InnoDB

InnoDB uses the primary key as the clustered index. Random NanoIDs can therefore result in less favorable insertion locality than sequential or time-ordered keys.

For workloads where this matters, one option is to use a sequential or time-ordered internal key and maintain a unique NanoID as the public identifier.

PostgreSQL

PostgreSQL can use text or binary representations for NanoIDs. Random insertion can still affect B-tree locality, but the actual impact depends on the table size, workload, indexes, hardware, and PostgreSQL configuration.

NanoID can be perfectly reasonable for many PostgreSQL applications.

SQL Server

SQL Server can store NanoIDs as character or binary data. If the NanoID is used as the clustered key, its random ordering can have similar locality considerations to other random identifiers.

An application can instead use a sequential internal key and maintain the NanoID as a unique non-clustered identifier.

Oracle and SQLite

Both can store NanoIDs using text or binary representations. Whether a random identifier creates a meaningful performance problem depends on the schema and workload.

Should NanoID Be the Database Primary Key?

There is no universal answer.

A useful architecture is to distinguish between an internal database key and a public identifier.

For example:

Internal database key:  BIGINT
Public identifier:      NanoID

The database can use the internal key where sequential ordering and compact indexing are valuable, while the NanoID is exposed through APIs and URLs.

This approach has several advantages:

  • The database can use a compact sequential key.
  • Public URLs don't expose sequential record numbers.
  • The public identifier can be generated independently.
  • The database schema is less dependent on the format of the external identifier.

However, maintaining two identifiers also adds schema and application complexity. For smaller applications, using NanoID directly as the primary key may be entirely reasonable.

The correct choice depends on actual workload rather than a blanket rule that NanoID should or should not be a primary key.

Is NanoID Suitable for URLs?

Yes. URLs are one of NanoID's strongest use cases.

The default NanoID uses a URL-safe alphabet and produces only 21 characters.

For comparison:

UUID v4:
550e8400-e29b-41d4-a716-446655440000

NanoID:
V1StGXR8_Z5jdL4K-myT6

NanoID therefore provides a shorter public identifier without requiring percent-encoding for its standard alphabet.

It also makes simple sequential enumeration impractical.

For example:

/orders/10001
/orders/10002
/orders/10003

can be trivially enumerated.

A NanoID-based URL does not expose an obvious sequence:

/orders/V1StGXR8_Z5jdL4K-myT6

That is useful for public identifiers, but it should not be confused with authorization. The server must still verify access to the requested resource.

Is NanoID Sortable?

No.

NanoID is designed to produce random identifiers. It does not contain a timestamp or sequence number.

Sorting NanoIDs therefore does not provide chronological ordering.

If an application needs to sort records by creation time, it should store a separate timestamp such as:

created_at

and index that column when appropriate.

If the identifier itself needs to provide chronological ordering, consider a time-ordered identifier such as UUID v7 or ULID.

Does NanoID Reveal Creation Time?

No.

Unlike ULID and UUID v7, NanoID does not deliberately encode a timestamp.

This can be an advantage when public identifiers should not reveal approximately when a record was created.

For example, a ULID contains a timestamp in its most significant bits, whereas a NanoID does not expose creation time through its identifier structure.

This makes NanoID attractive when compactness and random-looking public identifiers are more important than chronological sorting.

NanoID vs UUID v4

NanoID and UUID v4 are both commonly used for random identifiers, but they make different trade-offs.

UUID v4 provides a fixed 128-bit identifier with 122 random bits after accounting for the UUID version and variant fields.

NanoID provides a configurable identifier. The default configuration provides 126 bits of information in 21 characters.

The main advantage of NanoID is compactness.

The main advantage of UUID v4 is standardization and broad native support across programming languages, databases, libraries, and infrastructure.

Choose UUID v4 when UUID compatibility is important.

Choose NanoID when a shorter configurable representation is more useful.

NanoID vs UUID v7

UUID v7 and NanoID solve different problems.

UUID v7 provides:

  • 128-bit identifiers
  • A Unix timestamp
  • Chronological ordering
  • UUID/RFC compatibility
  • Better index locality than randomly distributed UUID v4 values in many workloads

NanoID provides:

  • Configurable length
  • Configurable alphabet
  • Compact text representation
  • Random identifiers
  • No embedded timestamp
  • URL-friendly output

If the identifier needs to sort by creation time or integrate with an existing UUID-based architecture, UUID v7 is usually the more natural choice.

If the main goal is a short random public identifier, NanoID is often more attractive.

NanoID vs ULID

ULID and NanoID are both popular compact identifiers, but they have very different structures.

ULID is a 128-bit time-ordered identifier consisting of a 48-bit timestamp and 80 bits of random data. Its canonical representation is 26 Crockford Base32 characters.

NanoID is configurable and does not contain a timestamp. Its default representation is 21 characters using a 64-character URL-safe alphabet.

Choose ULID when chronological sorting is important.

Choose NanoID when compact random identifiers are the priority.

Comparison With Other Identifiers

The major identifier formats differ primarily in their approach to randomness, ordering, representation, and standardization.

  • UUID v4: Fixed 128-bit random identifier. Widely supported and standardized.
  • UUID v7: Time-ordered UUID with a Unix timestamp and additional generation data.
  • ULID: 128-bit time-ordered identifier with an 80-bit random component and compact Base32 representation.
  • NanoID: Configurable random identifier optimized for compactness and URL-friendly output.
  • UUID v1: Older time-based UUID format containing timestamp and node-related information.
  • UUID v6: Time-ordered UUID based on the UUID v1 information model, rearranged for improved ordering.

Comparison Table

Identifier Bit Length Random Bits Time Component Sortable Default Text Length Encoding
UUID v4 128 122 No No 36 Hex
UUID v7 128 Up to 74* Yes Yes 36 Hex
ULID 128 80 Yes Yes 26 Crockford Base32
NanoID Configurable Configurable No No 21** URL-safe alphabet
  • UUID v7 provides 74 bits in its rand_a and rand_b fields. Implementations may use these fields for random data, counters, additional timestamp precision, or combinations of these.

** The default NanoID configuration uses 21 characters. Applications can choose a different length.

When Should You Use NanoID?

NanoID is a strong choice when you need:

  • Short public identifiers
  • URL-friendly IDs
  • Random identifiers without embedded timestamps
  • Configurable identifier length
  • Client-side ID generation
  • Distributed ID generation without a central sequence
  • Readable API resource identifiers

For example:

/projects/V1StGXR8_Z5jdL4K-myT6
/users/8Qm4Kp2xTz7NvL1sR5cWd
/orders/f3K8mQz2P7xL9nT4vR6sB

When Should You Choose Something Else?

NanoID may not be the best choice when:

  • The identifier needs to be chronologically sortable.
  • The database workload strongly benefits from sequential or time-ordered keys.
  • Your ecosystem already has extensive UUID support.
  • You need a fixed 128-bit standardized identifier.
  • The identifier itself needs to contain creation-time information.
  • You need deterministic identifiers derived from names or other values.

UUID v7 is worth considering when you need a standardized, time-ordered UUID.

ULID is worth considering when you want time ordering together with a compact Base32 representation.

UUID v4 remains useful when you specifically want a standardized random identifier without a timestamp.

Final Engineering Takeaway

NanoID is best understood as a compact, configurable random identifier, not as a replacement for UUID in every situation.

Its biggest advantage is flexibility. The default 21-character NanoID provides 126 bits of identifier space in a URL-friendly representation, but applications can change the length and alphabet when their requirements differ.

For URLs and public API identifiers, NanoID is an excellent option. It is short, easy to transmit, and does not expose creation time.

For database primary keys, the decision is more nuanced. Random NanoIDs can have less favorable index locality than sequential or time-ordered identifiers, particularly in large write-heavy workloads. That does not make NanoID universally unsuitable, but it does make the database workload an important part of the decision.

A practical rule is:

  • Short random public ID: NanoID
  • Standardized random UUID: UUID v4
  • Time-ordered standardized UUID: UUID v7
  • Compact time-ordered ID: ULID
  • Sequential database key: Integer or BIGINT

The right identifier is ultimately determined by the application's requirements. Optimize for the properties you actually need rather than assuming that one identifier format is universally better than the others.


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

Related Tools and Guides

Need some UUIDs for testing? Try our tools for generating UUIDv4   UUIDv7   ULID   NanoID and decoding validating.
For a detailed comparison of UUID versions, visit our Complete Guide to UUID Versions.