MonoLexID is a time-ordered and sortable Universally Unique Identifier (UUID) generator written in Object Pascal (Free Pascal), producing identifiers structurally compatible with the RFC 9562 UUIDv7 layout while privileging intra-millisecond monotonicity.
-
Lexicographic Monotonicity: Identifiers are time-ordered at millisecond precision, ensuring natural sequential sorting, preventing index fragmentation and optimising database insertion performance.
-
Time Integrity: The generator privileges clock-dependent chronological truth. Should the system exhaust the sequence counter (4,096 allocations per millisecond) or detect a retrograde clock shift, generation is suspended via an adaptive spin/yield loop. It yields (pauses) until physical time advances, so that identifiers are not generated with a fictitious-future time.
-
Cryptographic Uniqueness: To preclude collisions in distributed environments, the remainder of the string payload is populated using OS-native, cryptographically secure pseudorandom number generators to minimise collision risk.
-
Fail-Closed Under Clock Rollback: MonoLexID is intentionally fail-closed under retrograde clock conditions. If the system clock is stepped backwards and remains so, generation will suspend until physical time catches up or the configurable spin timeout (
MonoLexIDSpinTimeoutMS, default 5000 ms) is exceeded. Applications that require fail-open UUID generation under clock instability should not rely on MonoLexID’s time integrity guarantees.
MonoLexID generates a 36-character string (xxxxxxxx-xxxx-7xxx-xxxx-xxxxxxxxxxxx), which breaks down as follows:
- Chars 1-8: UNIX Timestamp in Milliseconds (Part 1)
- Char 9: Hyphen
- - Chars 10-13: UNIX Timestamp in Milliseconds (Part 2)
- Char 14: Hyphen
- - Chars 15-18: Version Identifier (
7) + 12-bit Sequence Counter - Char 19: Hyphen
- - Chars 20-23: Variant Identifier (
8,9,a, orb) + Random Data - Char 24: Hyphen
- - Chars 25-36: Secure Random Data
MonoLexID is contained entirely within a single unit with no external dependencies. To integrate it, download the latest version from the Releases page, include MonoLexID.pas in the project directory, and add it to the uses clause.
To generate a standard 36-character string format:
uses
MonoLexID;
var
NewID: String;
begin
NewID := NewMonoLexID;
end;Alternatively, to retrieve the raw 16-byte array:
uses
MonoLexID;
var
RawBytes: TMonoLexIDBytes;
begin
RawBytes := NewMonoLexIDBytes;
end;MonoLexID offers two concurrency modes.
Default: Per-Thread Monotonicity (threadvar mode)
State is managed per thread using threadvar. IDs generated on the same thread are strictly monotonic. IDs generated concurrently across different threads are individually monotonic per thread but are not guaranteed to be globally monotonic across threads. This mode has near-zero lock contention and is suitable for the vast majority of applications.
Global Monotonicity Mode (MONOLEXID_GLOBAL_MONOTONIC)
All threads share a single protected generator state, with strict process-local lexicographic monotonicity across every thread. It can be enabled by passing -dMONOLEXID_GLOBAL_MONOTONIC in the project compiler options or by adding {$DEFINE MONOLEXID_GLOBAL_MONOTONIC} at the top of MonoLexID.pas, as indicated in the comment block within the unit. This mode introduces a critical section per generation call and is recommended for distributed systems where global ordering across all threads is required.
Fork Safety
MonoLexID is safe for use in applications that fork. On POSIX systems, it registers a three-stage pthread_atfork handler that acquires all internal locks before the fork, releases them in the parent, and fully reinitialises the generator state, entropy source, and session nonce in the child. A PID-change detection fallback provides secondary protection. MonoLexIDReinitialize is available as an explicit application-callable reinitialisation for fork-aware applications that manage their own fork handlers.
MonoLexID provides both exception-raising and safe non-raising APIs.
Exception-raising (recommended for most use cases):
var
NewID: String;
begin
NewID := NewMonoLexID;
end;Safe non-raising (recommended for critical or high-availability use cases):
var
NewID: String;
begin
if TryNewMonoLexID(NewID) then
WriteLn('Generated ID: ', NewID)
else
WriteLn('Error: ', MonoLexIDGetLastError);
end;Generation may fail under the following conditions: CSPRNG unavailability, /dev/urandom inaccessibility on POSIX systems, spin timeout exceeded due to severe clock instability, or subsystem initialisation failure. In all cases the failure reason is retrievable via MonoLexIDGetLastError.
| Identifier | Kind | Description |
|---|---|---|
NewMonoLexID |
function: String |
Generates a new ID as a 36-character string. Raises on failure. |
TryNewMonoLexID |
function(out ID: String): Boolean |
Generates a new ID. Returns False on failure without raising. |
NewMonoLexIDBytes |
function: TMonoLexIDBytes |
Generates a new ID as a raw 16-byte array. Raises on failure. |
TryNewMonoLexIDBytes |
function(out IDBytes: TMonoLexIDBytes): Boolean |
Generates a new ID as bytes. Returns False on failure without raising. |
MonoLexIDFlushState |
procedure |
Flushes unpersisted generator state via MonoLexIDSaveState if assigned. Safe to call at application shutdown. |
MonoLexIDReinitialize |
function: Boolean |
Explicitly reinitialises the subsystem. Returns False and populates MonoLexIDInitError on failure. Useful after fork or following a failed initialisation. |
MonoLexIDGetLastError |
function: String |
Returns the most recent error message from a failed Try call or persistence failure. Thread-safe. |
MonoLexIDGetTimeMS |
var |
Pluggable time source. Defaults to the highest-resolution wall-clock available on the platform. |
MonoLexIDYieldThread |
var |
Pluggable yield function called during spin waits. Defaults to SwitchToThread on Windows and Sleep(0) on POSIX. |
MonoLexIDSaveState |
var |
Optional persistence callback. Called periodically and at flush. nil by default. |
MonoLexIDLoadState |
var |
Optional state restoration callback. Called on generator initialisation. nil by default. |
MonoLexIDInitError |
var String |
Populated with the reason if initialisation or reinitialisation fails. |
MonoLexIDSpinTimeoutMS |
var Int64 |
Maximum wall-clock milliseconds any spin loop will wait before raising. Default 5000. |
MonoLexIDVersionMajor/Minor/Patch |
const Integer |
Version constants. |
MonoLexID compiles and runs on:
- Windows (x86, x86-64)
- Linux (x86, x86-64, ARM, ARM64, and all FPC 3.2.2 or later supported targets)
- macOS (x86-64, ARM64)
- Any POSIX platform supported by FPC 3.2.2 or later with
/dev/urandomavailable
The project has benefited significantly from the assistance of Google’s Gemini 3.1 Pro and Anthropic’s Claude Sonnet 4.6 for collaborative ideation, code generation, refactoring, and debugging.
The project is under the BSD 3-Clause License and is provided “as-is”, without any warranties. Please see the LICENSE file for details.