SD System Design In Depth
0%
lesson system-designobject-storage

Metadata database for object storage

Module 2.3: Storage Engine Internals & Blob Systems Updated Sep 17, 2026
📄 Cheat Sheet
FAST '21 - Facebook's Tectonic Filesystem: Efficiency from Exascale
USENIX FAST '21 - Facebook's Tectonic Filesystem: Efficiency from Exascale Watch on YouTube ↗

Meta's FAST '21 Tectonic talk shows a real exabyte-scale design where metadata is disaggregated into name, file and block layers on a sharded key-value store, precisely this unit's concern.

0:00 / --:--

Under the Hood: High-Throughput Inode Engines

In an object storage system, object metadata (bucket, key, size, ETag, owner, ACLs, creation timestamp, and chunk pointers) is tiny (~500 bytes per object), but queries against it are astronomical. The metadata database must support millions of transactions per second, atomic key updates, and instantaneous lexicographical delimiter listings (e.g. GET /bucket?prefix=logs/2026/&delimiter=/).

Metadata Schema and Index Architecture

flowchart TD subgraph Request ["API Request"] Req["GET /photos/2026/march/beach.jpg"] end subgraph MetaDB ["Distributed Metadata Storage Tier (FoundationDB / CockroachDB)"] Schema["Primary Key: (bucket_id, object_prefix, object_name, version_id)"] Attributes["Columns: { size: 4194304, etag: 'a1b2c3d4', chunks: [chunk_id_1, chunk_id_2] }"] PrefixIdx["Inverted Prefix Index: 'photos/2026/march/' -> [beach.jpg, sunset.jpg]"] end Req --> Schema

Under the Hood: Lexicographical Prefix Traversal

Unlike traditional POSIX filesystems that represent directories as physical inode link trees (which require walking directory paths sequentially), object storage engines treat paths as flat string keys. By storing keys in a sorted B-tree or LSM-tree ordered by (bucket_id, key_name), listing the contents of a "virtual directory" reduces to an efficient range scan that starts at photos/2026/march/ and continues while keys still begin with that prefix.

Worked example: a delimiter listing

Index rows for bucket photos, in sorted order:

  • 2026/march/a.jpg
  • 2026/march/b.jpg
  • 2026/march/trip/c.jpg
  • 2026/march/trip/d.jpg
  • 2026/may/e.jpg

Request GET /photos?prefix=2026/march/&delimiter=/:

  1. Seek to the first key at or after 2026/march/.
  2. Return a.jpg and b.jpg as objects.
  3. 2026/march/trip/c.jpg contains another / after the prefix, so emit the common prefix 2026/march/trip/ once and skip ahead past every key starting with it.
  4. Stop at 2026/may/e.jpg, which no longer matches the prefix.

S3 returns up to 1,000 entries per page and an opaque continuation token that encodes where the scan stopped, so the next call resumes the range scan exactly there instead of starting over.

Sizing

100 billion objects at about 500 bytes of metadata each is 50 TB, or 150 TB with 3 replicas. At 1 million metadata operations per second and 50,000 operations per second per shard, you need at least 20 shards before headroom, and realistically hundreds to allow for hot spots.

Partitioning the metadata

ApproachListingHotspotsExample
Range partition on (bucket, key)Efficient range scansSequential names concentrate load; needs automatic splitsS3 index partitions by key prefix
Hash partition by directory idEfficient within one directoryVery hot directoriesTectonic name layer on ZippyDB
Hash partition by object or file idNeeds a separate name indexWell spreadTectonic file and block layers
Metadata stored in a general-purpose distributed DBDepends on schemaDepends on schemaColossus metadata in Bigtable

Failure modes

  • Commit ordering: write data first, then the metadata entry; otherwise readers see entries pointing at nothing.
  • Orphaned data: data written but metadata commit failed; needs garbage collection by scanning for unreferenced chunks.
  • Listing large prefixes: expensive scans; systems often offer inventory reports as an alternative.
Check yourself Question 1 of 3
Sorted metadata keys recall
From: Under the Hood: Lexicographical Prefix Traversal

Why must object metadata be ordered by (bucket, key) rather than hash-partitioned by the full key if the system supports prefix listing?

Key Takeaways

Object storage metadata treats directory paths as flat strings sorted lexicographically in distributed B-tree/LSM stores.
Virtual folder listing reduces to a single contiguous range scan over composite index keys.
Hyperscale storage systems keep metadata in strongly consistent, sorted distributed stores, but the engines differ (FoundationDB at Apple and Snowflake, Bigtable for Google Colossus, ZippyDB for Meta Tectonic, a purpose-built index for S3).
Was this lesson helpful? Spot an issue or have a suggestion? Let us know on GitHub.
Report an issue