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
- Choose your options above
- Click Generate
- Copy your result
Detailed instructions
- Set the Count field to how many ULIDs you need — up to a large batch for seeding or testing.
- Choose Uppercase for spec-compliant output or Lowercase to match your codebase's ID conventions.
- Click Generate to produce the full list of unique, timestamp-encoded ULIDs.
- 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.