Numbers

ULID Batch Generator

The ULID Batch Generator creates Universally Unique Lexicographically Sortable Identifiers in bulk, giving you production-ready IDs in seconds. Unlike UUIDs, each ULID encodes a millisecond-precision timestamp in its first 10 characters using Crockford Base32, followed by 16 cryptographically random characters — making them both globally unique and naturally sortable by creation time. That combination is rare and valuable. When you insert UUID-based primary keys into a B-tree index, random ordering causes page splits and index fragmentation over time. ULIDs avoid that problem because sequential inserts cluster naturally, keeping your indexes lean and your write performance stable. This makes them a compelling choice for high-throughput event streams, audit logs, and distributed systems where multiple nodes generate IDs independently. The generator lets you produce anywhere from a single ULID to a full batch, with a choice of uppercase or lowercase output to match your codebase's conventions. Uppercase is the canonical format defined by the ULID spec; lowercase works well in systems where identifiers are case-sensitive and you prefer visual consistency with hex-based IDs. Use this tool to pre-generate IDs for database seeding scripts, test fixtures, or migration files — anywhere you need real, spec-compliant ULIDs without spinning up a library or runtime environment.

How to Use

  1. Set the Count field to how many ULIDs you need — up to a large batch for seeding or testing.
  2. Choose Uppercase for spec-compliant output or Lowercase to match your codebase's ID conventions.
  3. Click Generate to produce the full list of unique, timestamp-encoded ULIDs.
  4. Copy the output and paste directly into your seed file, migration script, or test fixture.

Use Cases

  • Seeding a PostgreSQL table with pre-generated primary keys
  • Generating IDs for test fixtures in a Node.js or Go project
  • Creating unique identifiers for distributed microservice events
  • Replacing auto-increment IDs in a database migration script
  • Populating mock API responses with realistic, sortable record IDs
  • Assigning stable IDs to Kafka messages or event-sourcing records
  • Generating IDs for Firestore or DynamoDB documents without collision risk
  • Building a batch of unique correlation IDs for distributed tracing

Tips

  • Generate IDs before writing your migration so you can hard-code parent and child IDs with correct foreign key references.
  • Uppercase ULIDs sort identically to lowercase in case-insensitive databases, but choose one format and stay consistent across your whole schema.
  • If your ORM expects a specific ID format, check whether it accepts CHAR(26) — storing as binary(16) saves space but requires decoding at query time.
  • Batch-generate a few extra IDs when seeding test data; having spares avoids re-running the generator if you add more fixtures later.
  • ULIDs expose creation time — if your IDs are public-facing and you want to obscure timing, consider hashing or encrypting them before exposure.
  • Combine this tool with a JSON generator to build complete mock API payloads with realistic, sortable record IDs already embedded.

FAQ

What is a ULID and how does it work?

A ULID is a 26-character identifier built from two parts: a 48-bit millisecond timestamp encoded in the first 10 characters, and 80 bits of randomness in the remaining 16 characters. Both parts use Crockford Base32, which avoids ambiguous characters like I, L, O, and U. The result is a string that sorts chronologically and is unique across distributed systems.

How is ULID different from UUID?

UUID v4 is entirely random, so inserting UUIDs as database primary keys causes random index placement and fragmentation. ULIDs start with a timestamp, so sequential inserts land near each other in a B-tree index, improving write performance. ULIDs are also 26 characters versus UUID's 36 (including hyphens), and they use a URL-safe character set with no hyphens.

Can I use ULIDs as database primary keys?

Yes, and it's one of their best use cases. Because ULIDs sort lexicographically in the same order they were created, they avoid the index fragmentation caused by random UUIDs. They work well in PostgreSQL, MySQL, SQLite, MongoDB, and DynamoDB. Store them as CHAR(26) or TEXT — some teams also store the raw 16-byte binary representation for compactness.

Are ULIDs globally unique across multiple servers?

With very high probability, yes. The 80-bit random component gives you roughly 1.21 × 10²⁴ possible values per millisecond. Collisions are astronomically unlikely even across hundreds of nodes generating IDs simultaneously. For absolute collision guarantees, you'd need a centralized ID server — but for most distributed systems, ULIDs are more than sufficient.

Should I use uppercase or lowercase ULIDs?

The official ULID specification defines uppercase as canonical. Use uppercase unless your system is case-sensitive and your existing identifiers are lowercase, or you're storing IDs in a context where lowercase is convention (e.g., some GraphQL schemas or JSON APIs). Both forms are functionally identical and sort the same way since Crockford Base32 uses only digits and letters A–Z.

Can two ULIDs generated in the same millisecond collide?

In theory, two ULIDs generated within the same millisecond share an identical timestamp prefix, so uniqueness depends entirely on the 80-bit random suffix. The chance of a collision is about 1 in 10²⁴ — effectively zero for any real-world application. Some ULID libraries optionally increment the random component monotonically within a millisecond for strict ordering guarantees.

How do I use pre-generated ULIDs in a migration script?

Generate the batch here, copy the list, then paste it directly into your SQL INSERT statements or seed file. For example, in a Knex.js seed or Rails db/seeds.rb, assign each ID to a record manually. This is useful when you need referential integrity across tables — you can assign a parent ID and use it in child records before any database writes occur.

Are ULIDs URL-safe?

Yes. Crockford Base32 uses only digits 0–9 and letters A–Z (excluding I, L, O, U to avoid visual ambiguity). No special characters, no hyphens, no slashes. This makes ULIDs safe to use directly in URLs, filenames, S3 object keys, and HTTP headers without encoding.