Command Palette

Search for a command to run…

ZarynZaryn
Core concepts·2 min read

Content-addressed storage

Every object is named by the hash of what's in it: why that makes storage safe and deduplicated.

Every object in a zev repository — a file's content, a directory tree, a commit — is identified by the cryptographic hash of its own bytes, not by a filename or a sequentially assigned ID. This is the foundation everything else in zev is built on. ## Why hash-as-identity If two files anywhere in history have identical content, they hash to the same value and are stored once. If a file reverts to a previous version, its hash matches the earlier object exactly and nothing new is written. Content-addressing gets this deduplication for free, as a direct consequence of the identity scheme, not as a separate feature that has to be implemented and kept in sync. ## Two hash schemes, for different reasons zev's client and server use different hash functions, deliberately: - **The client** (`zev`) identifies local objects by SHA-256, computed over a blob's original, uncompressed content. - **The server** (`zev-api`) identifies stored objects by BLAKE3. A push manifest maps between the two: each object entry carries both `local_hash` (the client's SHA-256 identity) and `server_hash` (the BLAKE3 identity the server actually stores it under). This separation exists because the two sides evolved independently and were verified independently — the client's object model was built and tested first, and the server's storage layer, including compression and later, chunking, was designed around BLAKE3 without requiring the client to change its own local identity scheme. ## Compression is transparent to identity Objects are stored zstd-compressed on disk, both client-side and server-side, but the hash that identifies an object is always computed over the original, uncompressed bytes. Compression is an implementation detail of storage; it never changes what an object's own identity is. ## What this enables Because identity is purely a function of content, two independently-built pieces of infrastructure — local chunking (see [Content-defined chunking](/docs/en/chunking)) and CI memoization (see [Memoized CI](/docs/en/memoized-ci)) — both work by computing a hash over some input and checking whether that exact hash has been seen before. Neither needed to invent its own notion of "has this changed" — content addressing already provides one, uniformly, everywhere in the system.