This document defines the binary format specification for LibraVDB segment files (SSTables) version 1.
Segment files are immutable, sorted collections of vector entries stored on disk. They form the foundation of LibraVDB's LSM-tree storage architecture.
┌─────────────────────────────────────────────────────────────────┐
│ File Header │ (32 bytes)
├─────────────────────────────────────────────────────────────────┤
│ Data Blocks │ (variable)
├─────────────────────────────────────────────────────────────────┤
│ Index Block │ (variable)
├─────────────────────────────────────────────────────────────────┤
│ Bloom Filter │ (variable)
├─────────────────────────────────────────────────────────────────┤
│ Metadata │ (variable)
├─────────────────────────────────────────────────────────────────┤
│ Footer │ (32 bytes)
└─────────────────────────────────────────────────────────────────┘
The file header appears at the beginning of every segment file:
Offset | Size | Field | Description
-------|------|-----------------|----------------------------------
0 | 4 | Magic | Magic number: 0x4C565342 ("LVSB")
4 | 2 | Version | Format version (1)
6 | 2 | Flags | Feature flags (see below)
8 | 4 | Compression | Compression algorithm ID
12 | 4 | BlockSize | Data block size in bytes
16 | 4 | EntryCount | Total number of entries
20 | 4 | Dimension | Vector dimension
24 | 4 | HeaderChecksum | CRC32 of header bytes 0-23
28 | 4 | Reserved | Reserved for future use
- Value:
0x4C565342(ASCII: "LVSB" - LibraVDB Segment Binary) - Purpose: File format identification and corruption detection
- Value:
1for this specification - Purpose: Format version for backward compatibility
Bit | Description
----|------------------------------------------
0 | Has Quantization (1 if vectors are quantized)
1 | Has Metadata (1 if entries contain metadata)
2 | Has Bloom Filter (1 if bloom filter is present)
3 | Compressed Data Blocks (1 if data blocks are compressed)
4 | Compressed Index (1 if index block is compressed)
5-15| Reserved (must be 0)
ID | Algorithm
---|----------
0 | None
1 | LZ4
2 | Zstd
3 | Snappy
4 | Reserved
Data blocks contain the actual vector entries, organized for efficient access:
┌─────────────────────────────────────────────────────────────────┐
│ Block Header │ (16 bytes)
├─────────────────────────────────────────────────────────────────┤
│ Entry Data │ (variable)
├─────────────────────────────────────────────────────────────────┤
│ Block Footer │ (8 bytes)
└─────────────────────────────────────────────────────────────────┘
Offset | Size | Field | Description
-------|------|-----------------|----------------------------------
0 | 4 | EntryCount | Number of entries in this block
4 | 4 | UncompressedSize| Size before compression
8 | 4 | CompressedSize | Size after compression (0 if uncompressed)
12 | 4 | FirstKeyLength | Length of first key in block
Each entry within a data block follows this format:
┌─────────────────────────────────────────────────────────────────┐
│ Entry Header │ (variable)
├─────────────────────────────────────────────────────────────────┤
│ Vector Data │ (dimension * 4 bytes)
├─────────────────────────────────────────────────────────────────┤
│ Metadata │ (variable, optional)
└─────────────────────────────────────────────────────────────────┘
Offset | Size | Field | Description
-------|------|-----------------|----------------------------------
0 | 2 | KeyLength | Length of entry ID string
2 | 2 | Flags | Entry flags (see below)
4 | 4 | VectorOffset | Offset to vector data within entry
8 | 4 | MetadataOffset | Offset to metadata (0 if none)
12 | 4 | MetadataLength | Length of metadata (0 if none)
Bit | Description
----|------------------------------------------
0 | Has Metadata (1 if metadata is present)
1 | Quantized Vector (1 if vector is quantized)
2 | Deleted (1 if entry is tombstone)
3-15| Reserved (must be 0)
Unquantized Vectors:
┌─────────────────────────────────────────────────────────────────┐
│ float32[0] │ float32[1] │ ... │ float32[dimension-1] │
└─────────────────────────────────────────────────────────────────┘
Quantized Vectors:
┌─────────────────────────────────────────────────────────────────┐
│ Quantization │ Quantized │ Quantized │ ... │ Quantized │
│ Header │ Subvector │ Subvector │ │ Subvector │
│ (8 bytes) │ 1 │ 2 │ │ N │
└─────────────────────────────────────────────────────────────────┘
Offset | Size | Field | Description
-------|------|-----------------|----------------------------------
0 | 1 | Type | Quantization type (1=PQ, 2=SQ)
1 | 1 | Codebooks | Number of codebooks (PQ only)
2 | 1 | Bits | Bits per code
3 | 1 | Reserved | Reserved
4 | 4 | OriginalSize | Size of original vector in bytes
Metadata is stored as MessagePack-encoded key-value pairs:
┌─────────────────────────────────────────────────────────────────┐
│ MessagePack Data │
└─────────────────────────────────────────────────────────────────┘
Offset | Size | Field | Description
-------|------|-----------------|----------------------------------
0 | 4 | BlockChecksum | CRC32 of entire block (excluding footer)
4 | 4 | Reserved | Reserved for future use
The index block provides fast key lookup within the segment:
┌─────────────────────────────────────────────────────────────────┐
│ Index Header │ (16 bytes)
├─────────────────────────────────────────────────────────────────┤
│ Key Index │ (variable)
├─────────────────────────────────────────────────────────────────┤
│ Block Index │ (variable)
└─────────────────────────────────────────────────────────────────┘
Offset | Size | Field | Description
-------|------|-----------------|----------------------------------
0 | 4 | KeyIndexSize | Size of key index in bytes
4 | 4 | BlockIndexSize | Size of block index in bytes
8 | 4 | IndexChecksum | CRC32 of index data
12 | 4 | Reserved | Reserved
The key index maps entry IDs to their locations:
┌─────────────────────────────────────────────────────────────────┐
│ Entry Count (4 bytes) │
├─────────────────────────────────────────────────────────────────┤
│ Key Entry 1 │
├─────────────────────────────────────────────────────────────────┤
│ Key Entry 2 │
├─────────────────────────────────────────────────────────────────┤
│ ... │
├─────────────────────────────────────────────────────────────────┤
│ Key Entry N │
└─────────────────────────────────────────────────────────────────┘
Offset | Size | Field | Description
-------|------|-----------------|----------------------------------
0 | 2 | KeyLength | Length of key string
2 | 2 | BlockIndex | Index of containing data block
4 | 4 | BlockOffset | Offset within data block
8 | 4 | EntrySize | Total size of entry
The block index provides metadata about each data block:
┌─────────────────────────────────────────────────────────────────┐
│ Block Count (4 bytes) │
├─────────────────────────────────────────────────────────────────┤
│ Block Entry 1 │
├─────────────────────────────────────────────────────────────────┤
│ Block Entry 2 │
├─────────────────────────────────────────────────────────────────┤
│ ... │
├─────────────────────────────────────────────────────────────────┤
│ Block Entry N │
└─────────────────────────────────────────────────────────────────┘
Offset | Size | Field | Description
-------|------|-----------------|----------------------------------
0 | 4 | BlockOffset | Offset of block in file
4 | 4 | BlockSize | Size of block in bytes
8 | 2 | FirstKeyLength | Length of first key in block
10 | 2 | LastKeyLength | Length of last key in block
12 | 4 | EntryCount | Number of entries in block
The bloom filter enables fast negative lookups:
┌─────────────────────────────────────────────────────────────────┐
│ Bloom Filter Header │ (16 bytes)
├─────────────────────────────────────────────────────────────────┤
│ Bit Array │ (variable)
└─────────────────────────────────────────────────────────────────┘
Offset | Size | Field | Description
-------|------|-----------------|----------------------------------
0 | 4 | BitArraySize | Size of bit array in bytes
4 | 4 | HashFunctions | Number of hash functions used
8 | 4 | ExpectedItems | Expected number of items
12 | 4 | FilterChecksum | CRC32 of bit array
The bit array is stored as a sequence of 64-bit words in little-endian format.
The metadata section contains segment-level information:
┌─────────────────────────────────────────────────────────────────┐
│ Metadata Header │ (32 bytes)
├─────────────────────────────────────────────────────────────────┤
│ Statistics │ (variable)
├─────────────────────────────────────────────────────────────────┤
│ Schema Information │ (variable)
├─────────────────────────────────────────────────────────────────┤
│ Custom Properties │ (variable)
└─────────────────────────────────────────────────────────────────┘
Offset | Size | Field | Description
-------|------|-----------------|----------------------------------
0 | 8 | CreationTime | Unix timestamp (nanoseconds)
8 | 8 | ModificationTime| Unix timestamp (nanoseconds)
16 | 4 | StatisticsSize | Size of statistics section
20 | 4 | SchemaSize | Size of schema section
24 | 4 | PropertiesSize | Size of properties section
28 | 4 | MetadataChecksum| CRC32 of metadata sections
┌─────────────────────────────────────────────────────────────────┐
│ Min Key Length (4 bytes) │
├─────────────────────────────────────────────────────────────────┤
│ Max Key Length (4 bytes) │
├─────────────────────────────────────────────────────────────────┤
│ Total Uncompressed Size (8 bytes) │
├─────────────────────────────────────────────────────────────────┤
│ Total Compressed Size (8 bytes) │
├─────────────────────────────────────────────────────────────────┤
│ First Key (variable length, null-terminated) │
├─────────────────────────────────────────────────────────────────┤
│ Last Key (variable length, null-terminated) │
└─────────────────────────────────────────────────────────────────┘
Schema information is stored as JSON:
{
"version": 1,
"dimension": 768,
"distance_metric": "cosine",
"quantization": {
"type": "product",
"codebooks": 8,
"bits": 8
},
"metadata_schema": {
"title": "string",
"category": "string",
"tags": "string_array"
}
}The footer appears at the end of the file:
Offset | Size | Field | Description
-------|------|-----------------|----------------------------------
0 | 8 | IndexOffset | Offset to index block
8 | 8 | BloomOffset | Offset to bloom filter (0 if none)
16 | 8 | MetadataOffset | Offset to metadata section
24 | 4 | FileChecksum | CRC32 of entire file (excluding this field)
28 | 4 | FooterMagic | Magic number: 0x4C565346 ("LVSF")
All checksums use CRC32 (IEEE 802.3 polynomial):
- Header Checksum: CRC32 of header bytes 0-23
- Block Checksum: CRC32 of block data (excluding footer)
- Index Checksum: CRC32 of key index + block index
- Filter Checksum: CRC32 of bloom filter bit array
- Metadata Checksum: CRC32 of all metadata sections
- File Checksum: CRC32 of entire file excluding the checksum field itself
When compression is enabled:
- Data Blocks: Each block is compressed independently
- Index Block: The entire index block may be compressed
- Metadata: Metadata sections may be compressed
Compression is applied after serialization but before checksum calculation.
All multi-byte integers are stored in little-endian format.
- All offsets are 4-byte aligned
- Vector data is 16-byte aligned for SIMD optimization
- Blocks are padded to maintain alignment
This specification defines version 1 of the segment format. Future versions will:
- Increment the version number in the header
- Maintain backward compatibility for reading
- Add new features through flag bits
- Use reserved fields for new functionality
Offset | Size | Section
----------|-------|------------------
0 | 32 | File Header
32 | 4096 | Data Block 1
4128 | 4096 | Data Block 2
8224 | 2048 | Index Block
10272 | 512 | Bloom Filter
10784 | 256 | Metadata
11040 | 32 | Footer
- Reading: Always validate checksums before processing data
- Writing: Calculate checksums after all data is written
- Corruption: Any checksum failure should trigger error handling
- Performance: Use memory mapping for large files when possible
- Concurrency: Multiple readers are safe; writers must coordinate
This specification ensures data integrity, efficient access patterns, and extensibility for future enhancements to LibraVDB's storage format.