Skip to main content
Back to Numbers generators

Numbers

ULID Batch Generator

Used by developers, writers, and creators worldwide.

A ULID batch generator is the fastest way to produce spec-compliant, lexicographically sortable identifiers without spinning up a library or runtime. ULIDs are 26-character strings built from a 48-bit millisecond timestamp and 80 bits of Crockford Base32 randomness — sortable by creation time, URL-safe, and free of hyphens. Unlike UUID v4, sequential ULIDs cluster naturally in B-tree indexes, keeping write performance stable under load. Developers reach for them in event-sourced systems, distributed microservices, and any schema where random primary keys cause index fragmentation. Generate a batch of any size, choose uppercase (canonical per the spec) or lowercase to match your codebase, then paste directly into a seed file, migration script, or test fixture.

Loading usage…

Free forever — no account required

How to use

  1. Choose your options above
  2. Click Generate
  3. Copy your result

Detailed instructions

  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 CHAR(26) primary key column before running Knex.js or Flyway migrations
  • Pre-assigning parent and child record IDs to maintain referential integrity across a multi-table seed script
  • Populating Jest or Vitest fixtures with realistic sortable IDs for event-sourcing unit tests
  • Generating correlation IDs for OpenTelemetry spans across distributed microservice traces
  • Creating stable object keys for S3 or R2 buckets where chronological sort order matters

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

how is ulid different from uuid v4 for database primary keys

UUID v4 is entirely random, so each insert lands at an unpredictable position in a B-tree index, causing page splits and fragmentation over time. ULIDs start with a millisecond timestamp, so sequential inserts cluster near each other and keep your indexes compact. They're also 26 characters with no hyphens, versus UUID's 36, which saves space at scale.

can two ulids generated at the same millisecond collide

The timestamp prefix will be identical, but uniqueness falls to the 80-bit random suffix — roughly 1.21 × 10²⁴ possible values per millisecond. Collisions are effectively impossible for any real-world workload. If you need strict monotonic ordering within a millisecond, use a ULID library that increments the random component rather than pre-generated IDs.

should i store ulids as text or binary in postgres or mysql

Store as CHAR(26) or TEXT if readability and portability matter most — this is the common choice. For maximum compactness, some teams store the 16-byte binary representation using a BYTEA or BINARY(16) column. Both approaches sort correctly; CHAR(26) is easier to inspect in query results and log output without a decode step.