Yesterday's logs are queried constantly; last quarter's, almost never, yet the law says keep them. The economics of observability are decided by what happens to data after its first week. This essay follows an index from its busy youth to its very cheap old age.
A clean document needs an address, and for logs the address is a data stream: one stable name to write to, backed by a rolling series of hidden indices. When the current backing index gets too big or too old (the built-in logs policy says 50 GB per primary shard or 30 days), the stream rolls over: a fresh index silently takes the writes and the old one is sealed, never to be written again, which is exactly what the lifecycle machinery below needs. Run a month of logging:
And then time does its work. Remember the opening asymmetry: the newest data gets almost every query, the oldest almost none. So index lifecycle management migrates aging indices across hardware tiers, from fast expensive disks to object storage that costs almost nothing, while everything stays searchable. Drag time:
The frozen tier deserves a sentence of awe: those indices live as searchable snapshots in object storage, and are queried directly there, with local caching of just the blocks a query touches. Sealed, immutable indices (thank segments) are what make that safe. And the newest chapter of this story is storing the log data columnar from birth: Columnar logs, stored once.
An index sharded six ways made sense when it was ingesting a firehose; a week later the same index is read-only and those six shards are just overhead: each one is a Lucene index with its own segments, its own memory footprint, its own entry in every cluster-state update. The warm phase can shrink it:
The coldest data doesn't live on the node at all: it lives in object storage, and the node keeps only a cache of the pieces recent queries actually touched. Whether that feels like local disk or like the cloud depends on one ratio: