What it is
The uuid crate generates and parses universally unique identifiers, supporting versions 4 through 8 including the time-ordered v7.
Generate v4 for pure randomness or v7 when the value will be a database key. Parsing, formatting and Serde integration are all provided.
Installation
cargo add uuid --features v4,v7,serdeGetting started
The smallest useful thing you can do with it, and what each part means.
rust
use uuid::Uuid;
let random = Uuid::new_v4(); // fully random
let ordered = Uuid::now_v7(); // timestamp-prefixed, sorts by creation
let text = ordered.to_string(); // 0192f5c1-...
let parsed: Uuid = text.parse()?;
// Compact form for URLs and headers.
let simple = ordered.simple().to_string(); // no hyphens
#[derive(Serialize, Deserialize)]
struct Book { id: Uuid, title: String }Advanced usage
Where the library earns its place over a simpler alternative.
rust
// v4 values are random, so inserts land at random points in a B-tree
// index. Every insert dirties a different page, which fragments the
// index and hurts write throughput on large tables.
let v4 = Uuid::new_v4();
// v7 values increase over time, so inserts append to the rightmost
// page — the same access pattern as an auto-increment integer, while
// keeping the coordination-free property of a UUID.
let v7 = Uuid::now_v7();
// Deterministic identifiers derived from a name, for idempotency.
let ns = Uuid::NAMESPACE_URL;
let stable = Uuid::new_v5(&ns, b"https://example.com/books/42");
// Same input always yields the same UUID.Errors and fixes
The failures you are most likely to hit, and what actually resolves them.
- invalid length or invalid character when parsing
- The input is not a valid UUID. Use Uuid::try_parse and handle the error rather than unwrapping user input.
- Write performance degrades as the table grows
- Random v4 keys fragmenting the index. Migrate new rows to v7.
Best practices
- Prefer v7 for database primary keys; it avoids the index fragmentation v4 causes.
- Use v4 where the identifier must not reveal when it was created.
- Store as the native UUID type in PostgreSQL, not as text — it is half the size and faster to compare.
- Enable only the version features you use to keep compile times down.
Background
Why it exists, and what it was reacting to.
UUIDs are the default identifier for distributed systems because they need no coordination. Version 7 addresses their main drawback — random v4 values fragment database indexes badly.
