toolbench.onlineby Valkyron Labs

ID Generators

NanoID Generator

Generate NanoIDs online with a custom alphabet and length, in bulk. See collision probability and compare NanoID with UUID. Runs entirely in your browser.

NanoID Generator

Generate NanoIDs with a custom alphabet, length, bulk count, and collision estimate.

64 unique symbols

Collision probability

1% collision chance at 1,000 IDs per hour: ~149 billion years or 1,307,660T IDs.

126 random bits, similar to UUID v4 (122 bits). n = sqrt(2 × N × ln(1 / 0.99)), where N is the alphabet size to the power of the length.

NanoIDs

—

Output actions

Ready to copy output once your result appears.

NanoID Generator mini guide

Generate NanoIDs online with a custom alphabet and length, one at a time or in bulk. The page also estimates how long it takes, at a rate you choose, to reach a 1% chance of a collision. Everything runs in your browser. The identifiers are not uploaded.

How to use

  1. 1Leave the length at 21 or set another length from 1 to 255. 21 is the NanoID default and is the length this page opens with.
  2. 2Pick an alphabet preset — URL-safe, alphanumeric, lowercase, numbers, or no look-alikes — or replace the alphabet with your own symbols. Then set how many IDs to generate, from 1 to 1,000.
  3. 3Read the collision estimate, enter your own IDs-per-hour rate if 1,000 is not realistic, and select Generate. Copy the batch or download it as one ID per line.

What it is good for

  • • Creating short URL-safe identifiers for fixtures, tickets, and public links.
  • • Trying a smaller alphabet or a shorter length before you commit to it in code.
  • • Checking the collision window for the rate your service actually generates.

Example

Input

Length 21, URL-safe alphabet (64 symbols), 1,000 IDs per hour

Output

~149 billion years or 1,307,660T IDs

That is the time until a 1% chance that any two IDs collide. A generated ID at these settings is 21 characters drawn from A–Z, a–z, 0–9, underscore, and hyphen.

What is NanoID

NanoID is a small JavaScript library, and a specification of sorts, for random identifiers. The default call returns a string of 21 characters taken from a 64-symbol alphabet: digits, uppercase letters, lowercase letters, underscore, and hyphen. Those symbols are safe inside a URL path, a query string, a filename, and most HTML attributes without extra encoding. A default NanoID looks like V1StGXR8_Z5jdHi6B-myT. It is shorter than a hyphenated UUID, which is 36 characters, and it does not use characters that break when someone pastes the value into a URL.

The alphabet is not an encoding of a larger binary value that you can unpack. Each character is chosen independently. With 64 symbols, every character carries log2(64) = 6 bits of randomness. Twenty-one characters therefore carry 126 bits. A random UUID version 4 carries 122 bits, because 6 of its 128 bits are reserved for the version and the variant. The default NanoID is in the same range as UUID v4, packed into fewer characters, because the alphabet is larger than hexadecimal. Hex needs 32 digits for 128 bits. The URL-safe alphabet needs 21 characters for 126 bits.

Nothing in the string is a timestamp, a machine id, or a counter. Two NanoIDs created a millisecond apart are not ordered by that time, and you cannot read a creation time back out of one. That is the point of the design. If a client can see the identifier, they still cannot tell when it was minted or which process minted it. Systems that need time ordering use a different format. Systems that need an opaque public id use NanoID, UUID v4, or another random string.

This page does not call the nanoid package and it does not send the result to a server. It draws bytes with crypto.getRandomValues and maps them onto the alphabet you selected. The mapping rejects leftover byte values so that a symbol at the end of the alphabet is not slightly less likely than a symbol at the start. That is the same unbiased sampling the library uses. A batch is just that function repeated. The IDs in one batch are independent. This page does not keep a counter between them, and it does not coordinate with another browser tab.

Choosing length & alphabet

Length and alphabet together decide the keyspace. The number of possible IDs is the alphabet size raised to the length. The URL-safe preset has 64 symbols, so length 21 has 64^21 possible values, which is 2^126. The alphanumeric preset drops underscore and hyphen and has 62 symbols. Lowercase has 26. Numbers has 10. The no-look-alikes preset removes characters that people mix up when they read an ID aloud or type it from a screen: 0 and O, 1 and I and l, plus a few other pairs such as 2/Z and 5/S. Use that preset for codes a person will transcribe. Use numbers when the destination is a numeric field. Use lowercase when the store compares identifiers case-insensitively and you do not want A and a to be different IDs.

A custom alphabet is any string of 2 to 256 unique symbols. Duplicate symbols are removed before generation. If the letter a appeared twice, leaving both copies would make a more likely than its neighbors, which is a biased draw even when the random bytes themselves are fair. Symbols beyond the first 256 cannot be indexed by a single random byte without that kind of bias, so the field rejects them. Spaces and punctuation are allowed if you type them. They are also easy to break when the ID is copied into a URL or a shell, so prefer the URL-safe preset unless you have a reason to leave it.

Shorter IDs are easier to read and cheaper to store. They also shrink the keyspace by the alphabet size for every character you remove. On the 64-symbol alphabet, dropping one character divides the number of possible IDs by 64, and the collision time falls by the square root of 64, which is 8. Length 21 at a modest rate is astronomical. Length 10 is a human timescale if you generate quickly, and length 8 is shorter still. The estimate under the form is the way to check a specific pair of settings. Do not copy a length from a blog post that assumed a different alphabet or a different creation rate.

Match the alphabet to the system that will store the ID. A database collation that ignores case will treat a lowercase NanoID and an uppercase one as the same key if they differ only by case, and it will also fold two different mixed-case IDs together. If the column is case-insensitive, generate lowercase only. If the ID is embedded in a URL, stay inside the URL-safe set so you do not have to percent-encode it. If a person will read the ID over the phone, use no look-alikes and keep the length only as long as the collision estimate still looks comfortable.

Collision probability explained

A collision is two independently generated IDs that happen to be the same string. NanoID does not check a database before it returns a value, and neither does this page. Uniqueness is a probability. The usual model is the birthday problem: you are not waiting for one particular ID to repeat, you are waiting for any two IDs in the whole set to match. That happens much sooner than the size of the keyspace suggests. The count n at which the chance of at least one collision reaches a probability p is approximately n = sqrt(2 × N × ln(1 / (1 − p))), where N is the number of possible IDs. This page uses p = 0.01, the same 1% threshold as the NanoID collision calculator.

N is the alphabet size raised to the length. Equivalently, N = 2^(length × log2(alphabet size)). For the defaults, alphabet size 64 and length 21, that exponent is exactly 126, and n is about 1.31 × 10^18 IDs. The form asks for a rate in IDs per hour because that is how people describe production traffic. The calculator converts the rate to IDs per second by dividing by 3,600, divides n by that speed, and floors the result to whole seconds. Those seconds are then shown in minutes, hours, days, or years. At 1,000 IDs per hour the default settings land on about 149 billion years, or about 1,307,660 trillion IDs, before a 1% chance of any collision. The example above is that result. Change the length, the alphabet, or the rate and the same formula runs again.

The estimate assumes every ID is drawn independently and uniformly, and that you count every ID ever created in that namespace, including ones you later delete. It is not a promise that a particular database constraint will hold, and it is not a model of IDs that include a timestamp or a counter. A clock-based identifier can collide for a different reason: two processes in the same millisecond with a weak random suffix. The birthday formula does not describe that. It also assumes the alphabet size you see in the estimate. Duplicate characters have already been removed. If your application uses a different alphabet than the one on screen, the number does not apply.

Use the rate you might hit at a peak, not a quiet average. A service that creates 1,000 IDs an hour and a service that creates 1,000 IDs a second are not in the same regime, even with the same length. One thousand per second is 3,600,000 per hour. Enter that figure. If the resulting time is measured in days or years rather than in billions of years, lengthen the ID or widen the alphabet before you ship the format. Raising the length by one URL-safe character multiplies N by 64 and multiplies the time by 8. That is usually cheaper than discovering a collision in production.

NanoID vs UUID v4

UUID version 4 is a 128-bit value written as 36 characters: 32 hex digits and 4 hyphens, in the shape 8-4-4-4-12. Six bits are fixed, so 122 bits are random. A default NanoID is 21 characters and about 126 random bits, with no hyphens. Both are random. Neither sorts by creation time. Neither can be decoded into a timestamp. The practical differences are the text shape, the alphabet, and where the value is already understood. Databases, ORMs, and APIs often have a UUID type. They rarely have a NanoID type, so a NanoID is stored as text. A UUID column will not accept a NanoID, and a parser that expects hyphens and hex will reject one.

Choose NanoID when you want a compact URL-safe string and you control both the writer and the reader. Choose UUID v4 when another system already stores UUIDs, when a standard library must parse the value, or when you want the identifier to look familiar in logs that already contain GUIDs. Choose UUID v7 or ULID when new rows should sort by creation time and you can accept that the time is visible to anyone who can see the ID. Choose a MongoDB ObjectID when the document lives in MongoDB and you want the 12-byte default _id, including the second-resolution timestamp in the first four bytes. A longer comparison of the time-ordered formats is in the guide UUID v4 vs UUID v7 vs ULID. Generate the other shapes with the UUID generator, the ULID generator, and the ObjectID generator.

Size is the comparison people quote, and it is real: 21 characters against 36, or 21 bytes of UTF-8 against 36, for a similar amount of randomness. The savings shows up in URLs, JSON payloads, and indexes of string keys. It is not a reason to shorten a NanoID to 8 characters without looking at the collision estimate. A UUID v4 shortened by hand is no longer a UUID. A NanoID shortened on purpose is still a NanoID, and the collision math moves with it. If you need both a standard UUID and a short public token, generate them as two fields. Do not strip the hyphens off a UUID and call the result a NanoID. The alphabets and the lengths will not match, and a reader cannot tell which format you meant.

Code snippets

Applications should generate IDs on the server, or in the client that owns the record, using a maintained library. This page is for trying lengths and alphabets and for making a batch of fixture values. The default call in the nanoid package is a single import. customAlphabet builds a function locked to your symbols and your length, which is what you want once you have picked something other than the defaults. Keep that function next to the rest of the ID code so a later change does not silently switch alphabets.

The strings below are the calls to copy into a Node or bundler project that depends on the nanoid package. They are not executed by this page. The first returns a 21-character URL-safe ID. The second returns a 10-character ID from a hexadecimal alphabet. Check the collision estimate for that second alphabet before you use length 10 in production: 16 symbols at length 10 is a much smaller keyspace than 64 symbols at length 21. The package and this page both refuse to bias the draw. If you implement your own loop, do not use byte modulo alphabet length. Use rejection sampling, or call the library.

import { nanoid } from 'nanoid'
nanoid()

import { customAlphabet } from 'nanoid'
const nanoid = customAlphabet('1234567890abcdef', 10)
nanoid()

Rules and limitations

Length is a whole number from 1 to 255. The field opens at 21. Count is a whole number from 1 to 1,000. A count outside that range is pulled back to the nearest allowed value. Each generated line uses only the current alphabet and is exactly the requested length.

The URL-safe preset is the 64-character NanoID alphabet. Alphanumeric is digits plus both letter cases, without underscore or hyphen. Lowercase is a–z. Numbers is 0–9. No look-alikes removes 0, O, 1, I, l, and other pairs that are easy to misread. Custom is whatever you type, with duplicate symbols removed and a maximum of 256 unique symbols.

The collision line uses p = 0.01 and the birthday approximation n = sqrt(2 × N × ln(1 / 0.99)), with N equal to the unique alphabet size raised to the length. The rate is IDs per hour and is converted to IDs per second by dividing by 3,600. The result is a probability model, not a scan of a database. Copy and download apply to the generated batch only.

Common problems

An ID that contains a character outside the alphabet, or that has the wrong length, was not produced by the current settings. UUID text, with hyphens and a fixed shape, is not a NanoID. An ObjectID is 24 hex characters. A ULID is 26 Crockford Base32 characters. If a store compares case-insensitively, switch the preset to lowercase before you generate a batch you plan to insert.

A collision estimate measured in days means the length or the alphabet is too small for the rate you entered. Increase one of them and read the line again. The estimate does not become safer because you generate the IDs on this website, and it does not include IDs your production service created last year. Count the lifetime of the namespace. A custom alphabet with a space or a quote will break in URLs and shells even when the collision math looks fine.

Frequently asked questions

Is NanoID secure?

It is a cryptographic random string when it is drawn from crypto.getRandomValues, or from the operating-system generator the nanoid package uses, and when the alphabet and length are large enough for your threat model. This page uses crypto.getRandomValues and rejection sampling so each symbol has an equal chance. A short ID or a 10-symbol alphabet can still be guessed by searching. NanoID is not a password hash and it is not a signature. Do not treat a short public ID as the only authorization check.

Is NanoID sortable?

No. NanoID is random. Sorting a list of NanoIDs does not sort them by creation time, and two IDs created in order are not in that order as text. If you need identifiers that sort by time, use ULID or UUID v7. Those formats put a timestamp in front of the random bits, which also means anyone who can see the ID can see the time.

Can a NanoID be decoded?

No. A NanoID does not encode a timestamp, a machine, a counter, or a payload. There is nothing to decode. You can check that the string uses the alphabet and the length you expect, and you can look it up in your own database. You cannot recover when it was created from the characters alone.

How short can a NanoID be?

As short as the collision estimate allows for your rate. The default, 21 URL-safe characters at 1,000 IDs per hour, stays under a 1% collision chance for about 149 billion years. Each character you remove on that alphabet divides that time by 8. Set the length and the IDs-per-hour field on this page and read the line before you pick a shorter ID for production.

Is my input uploaded or saved?

This tool processes input in your browser and does not save its input or output to local storage. Copy and download are user actions. The site uses analytics for page and action metadata and may use ads and production error reporting; see the Privacy Policy for those services.

About this tool

Maintained by Toolbench. For large or deeply nested files, split the input into smaller batches and verify representative results before using them in an import or application. Report reproducible problems through Contact.

Guides

Next steps

Related tools

Continue the workflow with nearby tools for formatting, publishing, debugging, or follow-up checks.

Trust

Policies, contact, and answers

Clear pages for how Toolbench works, what we collect, and how to reach us.