Observability Storage Architecture Overview: From Gorilla to Parquet

Introduction

Observability has become a core infrastructure pillar of the cloud-native era. The five signals—Metrics, Logs, Traces, RUM, and Profiling—each generate massive volumes of data, and their storage efficiency directly determines platform cost boundaries and query performance. On the collection side, eBPF technology is reshaping how data is acquired. Behind all of this, storage architecture evolution is the foundation that enables observability to scale in production.

mermaid
flowchart TD
    A[Five Signals of<br/>Observability] --> B[Metrics]
    A --> C[Logs]
    A --> D[Traces]
    A --> E[RUM + Profiling]

    style A fill:#9C27B0,color:#fff
    style B fill:#2196F3,color:#fff
    style C fill:#2196F3,color:#fff
    style D fill:#2196F3,color:#fff
    style E fill:#2196F3,color:#fff
mermaid
flowchart TD
    G[Storage Evolution<br/>Convergent Paths] --> H[Proprietary Format<br/>→ Columnar Standard]
    G --> I[Index Bloat<br/>→ Weak Index + Object Store]

    style G fill:#FF9800,color:#fff
    style H fill:#4CAF50,color:#fff
    style I fill:#4CAF50,color:#fff

Figure: The five observability signals each produce data with different characteristics, yet their storage evolution converges on two core themes across all signals: the shift from proprietary storage formats to Parquet/Arrow columnar standards, and the move from full-field inverted indexes to weak-index strategies with object storage.

This opening post starts with the two storage evolution threads, then delves into the Gorilla compression algorithm—the shared theoretical foundation of all modern TSDBs—surveys the key technical consensus, and outlines three major evolution trends, setting the stage for subsequent deep-dives into each signal.

Beginner’s Cheat Sheet — Five Signals in One Line

SignalAnalogyExample Data
MetricsSystem’s “heart monitor”CPU=80%, QPS=12k, mem=6GB
LogsSystem’s “work diary”[ERROR] 10:03 connection timeout
TracesRequest’s “delivery tracking”gateway → order → payment → inventory
RUMUser’s “experience report”FCP=3.2s, CLS=0.05
ProfilingCode’s “X-ray scan”function call stack flame graph

If you’re new to observability, don’t be intimidated by the jargon—essentially it’s about examining your system from five different angles, with one core goal: when something breaks, you can quickly find out why.

采集 Collect — 从应用、系统、网络中收集可观测性数据
处理 Process — 数据清洗、聚合、打标、格式化
存储 Store — 时序数据库、列式存储、索引优化
查询 Query — PromQL、SQL、Trace 查询、可视化

Two Storage Evolution Threads

Following an in-depth survey of over a dozen systems—InfluxDB, Prometheus, VictoriaMetrics, TimescaleDB, Loki, Elasticsearch, ClickHouse, Tempo, Pyroscope, and more—two clear threads emerge in observability storage technology:

Evolution ThreadPain PointConsensus SolutionRepresentative Migrations
Proprietary → Columnar StandardHomegrown formats lock in engines, closed ecosystemApache Parquet + Arrow becomes de facto standard[E11]InfluxDB TSM→Parquet (3.0 FDAP); Tempo flatbuffer→Parquet; Pyroscope V2 columnar segment; FrostDB
Index Bloat → Weak Index + Object StorageFull-field inverted index costs explode with data volumeIndex only key labels + sequential scan + column pruning + object storageLoki (labels only); Tempo (TraceID only); VictoriaLogs (auto-index + extreme compression)

These two threads are not independent—columnar formats naturally support efficient sequential scanning and column pruning, providing the underlying capability for weak-index strategies; while the low cost of object storage makes “scanning instead of seeking” economically viable.

Beginner Analogy: Imagine recording daily temperatures. Uncompressed, each entry stores “2026-06-14 10:00:00 → 25.3°C” as a long string. But if the temperature barely changes, you’d naturally say “same as yesterday” — that’s compression in essence. Gorilla pushes this intuition to the extreme: timestamps are replaced with “same interval as before,” values with “nearly identical to the previous one.” The animation below demonstrates this process.

Theoretical Foundation: Gorilla Compression Algorithm

Gorilla is an in-memory time series database published by Facebook at VLDB 2015. Its compression algorithm is the foundation of modern TSDB compression technology, widely adopted by Prometheus, InfluxDB, VictoriaMetrics, TimescaleDB, and others[1][16]. Gorilla compresses time series to an average of 1.37 bytes per data point, achieving a 12x compression ratio[1].

Timestamp Compression: Delta-of-Delta Encoding

A key property of time series data is that collection intervals are typically fixed. Gorilla exploits this by encoding timestamps using “delta of delta”[1][2]:

1
Formula: D = (t_n - t_{n-1}) - (t_{n-1} - t_{n-2})

Variable-length encoding rules[2][5]:

Delta-of-Delta RangeBitsDescription
D = 01 bitSingle flag bit ‘0’, most common with fixed intervals
D ∈ [-63, 64]9 bits2-bit header + 7-bit value
D ∈ [-255, 256]12 bits3-bit header + 9-bit value
D ∈ [-2047, 2048]16 bits4-bit header + 12-bit value
Other36 bits4-bit header + 32-bit value

Real-world effect: For a 15-second fixed-interval collection, the first timestamp stores the full value (64 bits), the second stores the delta (14 bits), and every subsequent timestamp needs only 1 bit[2]. A single collection delay incurs an extra 32 bits of overhead, making consistent collection intervals critical to compression efficiency.

Gorilla Delta-of-Delta Encoding (15s fixed interval)SampleTimestampDeltaDelta-of-DeltaEncoded Bitst₁10064 bitst₂1151514 bitst₃1301501 bitt₄1451501 bitt₅1601501 bitUncompressed: 5 × 64 = 320 bitsGorilla: 64 + 14 + 1 + 1 + 1 = 81 bitsLonger fixed intervals → higher ratio, theoretical max 64x

Animation: The loop above shows 5 samples collected at fixed 15-second intervals being encoded with delta-of-delta. Note that from t₃ onward, each row requires only 1 bit (green highlight) — because delta-of-delta is 0, a single flag bit suffices. This is the core principle behind Gorilla’s 12x compression ratio.

Floating-Point Value Compression: XOR Encoding

Consecutive floating-point values are typically similar (e.g., CPU utilization 47.2%, 47.3%), and XOR operations produce many leading/trailing zeros[1][2]:

XOR ResultEncodingBits
XOR = 0 (same value)Flag bit ‘0’1 bit
XOR ≠ 0, same leading zeros pattern as previous‘10’ + meaningful bits2 + meaningful bits
XOR ≠ 0, different leading zeros pattern‘11’ + 5-bit leading zeros + 6-bit trailing zeros + meaningful bits13 + meaningful bits

Production statistics (Facebook measurements)[2]:

XOR ResultProportionAverage Bits
All zeros (identical values)51%1 bit
Similar (few meaningful bits)30%~26.6 bits
Different (value jumps)19%~36.9 bits
Weighted average100%~9.5 bits/value
Gorilla XOR Float Compression (CPU Utilization Example)Samples47.2%47.3%47.3%01000100... (64-bit float64)01000100... (only last bits differ)01000100... (identical)XOR Result51% → all zeros (1 bit)when values match30% → similar (~27 bits)last few bits differ19% → different (~37 bits)when value jumpsWeighted average: ~9.5 bits/value (uncompressed: 64 bits)Combined with timestamp compression → 1.37 bytes/point (12x ratio)

Animation: The loop above shows XOR compression of consecutive float values like CPU utilization. Key insight: adjacent samples are typically nearly identical (47.2% → 47.3% → 47.3%), and XOR produces all zeros 51% of the time (just 1 flag bit), with only a few meaningful bits in 30% of cases. This is the core of Gorilla’s value compression — it doesn’t compress individual values, it compresses the differences between consecutive values.

Overall Compression Results and Limitations

MetricBits
Average timestamp~1.5 bits
Average value~9.5 bits
Total per data point~11 bits ≈ 1.37 bytes
Uncompressed16 bytes (8B timestamp + 8B float64)
Compression ratio~12x

Data is grouped into chunks, each with fixed overhead (base timestamp 64 bits + first value 64 bits). Short chunks yield poor compression[2][3].

mermaid
flowchart TD
    TS[Timestamp Sequence] --> DD{Compute delta-of-delta}
    DD -->|D=0| B1[1 bit encoding]
    DD -->|"D ∈ -63~64"| B2[9 bits encoding]
    DD -->|"D ∈ -255~256"| B3[12 bits encoding]
    DD -->|Other| B4[36 bits encoding]

    style TS fill:#FF9800,color:#fff
    style DD fill:#2196F3,color:#fff
    style B1 fill:#4CAF50,color:#fff
    style B2 fill:#4CAF50,color:#fff
    style B3 fill:#4CAF50,color:#fff
    style B4 fill:#4CAF50,color:#fff

Figure: Gorilla timestamp encoding decision flow. The core assumption of delta-of-delta encoding is stable collection intervals—when D=0 (fixed intervals), each timestamp requires only 1 bit, which is the key to achieving a 12x compression ratio. If collection intervals are irregular, D=0 cases drop significantly, and the compression ratio falls from 12x to 5-7x.

Algorithm limitations[2]:

LimitationImpact
Sequential decodingEach sample depends on the previous one, preventing random access within a chunk
Irregular timestampsRandom intervals mean delta-of-delta is rarely zero, reducing compression from 12x to 5-7x
No metadata compressionHandles only value pairs; labels and metadata require separate inverted indexes

Key Technical Consensus

Through cross-validation across multiple sources, the following technical consensus has emerged in observability storage[1][3][E25]:

Key ConsensusDescription
Gorilla compressiondelta-of-delta + XOR, the compression foundation of all modern TSDBs, ~12x ratio
Columnar storageThe fundamental solution to high-cardinality—traditional label-set models break down at millions of series
Object storage + compute-storage separationS3/GCS has become the default for cloud-native observability backends
OpenTelemetry unified data modelResource + Signal model drives cross-signal correlation from UI layer to storage layer
eBPF collection-side aggregationKernel-space filtering, a pre-processing strategy for reducing data volume

Three Major Evolution Threads

Synthesizing trends across all signal domains, observability storage is evolving along three main threads[E25][E27][E11]:

ThreadCore ParadigmRepresentative Solutions
① eBPF Collection-Side AggregationKernel-space filtering + collection-side aggregation + short-term in-memory storage + on-demand query result transfer, controlling data volume at the sourcePixie, Hubble, Inspektor Gadget
② Storage from Siloed to UnifiedLGTM per-signal DB (one DB per signal + UI correlation) → ClickHouse unified columnar (single engine + SQL JOIN); object storage + compute-storage separation; compression/tiering/pre-aggregation replace aggressive samplingClickHouse unified columnar storage
③ Data Model StandardizationOpenTelemetry unified model (Resource + InstrumentationScope + Signal) + exemplar + trace_id injection, pushing cross-signal correlation from UI layer to storage layerOpenTelemetry

Series Reading Guide

This series consists of 8 posts, best read in the following order:

#TitlePrimary SignalRecommendation
1Storage Architecture Overview (this post)AllRequired reading, establish global context
2TSDB StorageMetricsCore TSDB technology stack
3Log StorageLogsLargest data volume, most challenging storage design
4Tracing StorageTracesDistributed tracing storage strategies
5RUM StorageRUMUnique requirements of front-end monitoring
6Profiling StorageProfilingLatest columnar storage practices
7eBPF & Unified Architecture TrendsCross-signalFuture direction of collection and storage
8Storage Selection GuideAllScenario-based selection recommendations

Posts 2-6 can be read selectively based on interest. Posts 7-8 depend on technical background from preceding posts.

References

[1] [Official] Gorilla: A Fast, Scalable, In-Memory Time Series Database (VLDB 2015): https://www.vldb.org/pvldb/vol8/p1816-teller.pdf

[2] [Secondary] Gorilla Compression (Delta-of-Delta + XOR) Detailed Analysis: https://crackingwalnuts.com/distributed-systems/gorilla-compression

[3] [Secondary] Time-Series Database Internals: InfluxDB 3, TimescaleDB, and QuestDB Under the Hood: https://iotdigitaltwinplm.com/time-series-database-internals-influxdb-timescale-questdb-2026/

[5] [Official] InfluxDB Time Series Index (TSI) Details: https://docs.influxdata.com/enterprise_influxdb/v1/concepts/tsi-details/

[16] [Secondary] CHIMP: Efficient Lossless Floating Point Compression for Time Series Databases (VLDB 2022): https://vldb.org/pvldb/vol15/p3058-liakos.pdf

[E11] [Official] Grafana: The open and composable observability platform: https://grafana.com/

[E25] [Official] OpenTelemetry — Overview (specs): https://opentelemetry.io/docs/specs/otel/overview/

[E27] [Secondary] What is OpenTelemetry? (Dash0): https://www.dash0.com/knowledge/what-is-opentelemetry