Class UniqueIdGenerator

java.lang.Object
com.cedarsoftware.util.UniqueIdGenerator

public final class UniqueIdGenerator extends Object
Generates guaranteed unique, time-based, monotonically increasing IDs within a distributed environment. Each ID encodes three pieces of information:
  • Timestamp - milliseconds since epoch (1970)
  • Sequence number - counter for multiple IDs within same millisecond
  • Server ID - unique identifier (0-99) for machine/instance in cluster

Cluster Support

Server IDs are determined in the following priority order:
  1. Environment variable JAVA_UTIL_CLUSTERID (0-99)
  2. Kubernetes Pod ID (extracted from metadata)
  3. VMware Tanzu instance ID
  4. Cloud Foundry instance index (CF_INSTANCE_INDEX)
  5. Hash of hostname modulo 100
  6. Random number (0-99) if all else fails

Available APIs

Two ID generation methods are provided with different characteristics:
 getUniqueId()
 - Format: timestampMs(13-14 digits).sequence(3 digits).serverId(2 digits)
 - Rate: Up to 1,000 IDs per millisecond
 - Range: Until year 5138
 - Example: 1234567890123456.789.99

 getUniqueId19()
 - Format: timestampMs(13 digits).sequence(4 digits).serverId(2 digits)
 - Rate: Up to 10,000 IDs per millisecond
 - Range: Until year 2286 (positive values)
 - Example: 1234567890123.9999.99
 

Guarantees

The generator provides the following guarantees:
  • IDs are unique across JVM restarts on the same machine
  • IDs are unique across machines when proper server IDs are configured
  • IDs are strictly monotonically increasing (each ID > previous ID)
  • System clock regression is handled gracefully
  • High sequence numbers cause waiting for next millisecond
Author:
John DeRegnaucourt ([email protected]), Roger Judd (@HonorKnight on GitHub) for adding code to ensure increasing order Copyright (c) Cedar Software LLC

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

License

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
  • Field Details

  • Method Details

    • getUniqueId

      public static long getUniqueId()
      Generates a unique, monotonically increasing ID with millisecond precision that's cluster-safe.

      ID Format

      The returned long value contains three components:
       [timestamp: 13-14 digits][sequence: 3 digits][serverId: 2 digits]
       Example: 1234567890123456.789.99 (dots for clarity, actual value has no dots)
       

      Characteristics

      • Supports up to 1,000 unique IDs per millisecond (sequence 000-999)
      • Generates positive values until year 5138
      • Guaranteed monotonically increasing even across millisecond boundaries
      • Thread-safe through internal locking
      • Handles system clock regression gracefully
      • Blocks when sequence number exhausted within a millisecond
      Returns:
      A unique, time-based ID encoded as a long value
      See Also:
    • getUniqueId19

      public static long getUniqueId19()
      Generates a unique, monotonically increasing 19-digit ID optimized for higher throughput.

      ID Format

      The returned long value contains three components:
       [timestamp: 13 digits][sequence: 4 digits][serverId: 2 digits]
       Example: 1234567890123.9999.99 (dots for clarity, actual value has no dots)
       

      Characteristics

      • Supports up to 10,000 unique IDs per millisecond (sequence 0000-9999)
      • Generates positive values until year 2286 (after which values may be negative)
      • Guaranteed monotonically increasing even across millisecond boundaries
      • Thread-safe through internal locking
      • Handles system clock regression gracefully
      • Blocks when sequence number exhausted within a millisecond

      Performance Comparison

      This method is optimized for higher throughput compared to getUniqueId():
      • Supports 10x more IDs per millisecond (10,000 vs 1,000)
      • Trades timestamp range for increased sequence capacity
      • Recommended for high-throughput scenarios through year 2286
      Returns:
      A unique, time-based ID encoded as a long value
      See Also:
    • getDate

      public static Date getDate(long uniqueId)
      Extracts the date-time from an ID generated by getUniqueId().
      Parameters:
      uniqueId - A unique ID previously generated by getUniqueId()
      Returns:
      The Date representing when the ID was generated, accurate to the millisecond
      Throws:
      IllegalArgumentException - if the ID was not generated by getUniqueId()
    • getDate19

      public static Date getDate19(long uniqueId)
      Extracts the date-time from an ID generated by getUniqueId19().
      Parameters:
      uniqueId - A unique ID previously generated by getUniqueId19()
      Returns:
      The Date representing when the ID was generated, accurate to the millisecond
      Throws:
      IllegalArgumentException - if the ID was not generated by getUniqueId19()
    • getInstant

      public static Instant getInstant(long uniqueId)
      Extracts the date-time from an ID generated by getUniqueId().
      Parameters:
      uniqueId - A unique ID previously generated by getUniqueId()
      Returns:
      The Instant representing when the ID was generated, accurate to the millisecond
      Throws:
      IllegalArgumentException - if the ID was not generated by getUniqueId()
    • getInstant19

      public static Instant getInstant19(long uniqueId19)
      Extracts the date-time from an ID generated by getUniqueId19().
      Parameters:
      uniqueId19 - A unique ID previously generated by getUniqueId19()
      Returns:
      The Instant representing when the ID was generated, accurate to the millisecond
      Throws:
      IllegalArgumentException - if the ID was not generated by getUniqueId19()