<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://tech.uvoo.io/index.php?action=history&amp;feed=atom&amp;title=Loki_indexes</id>
	<title>Loki indexes - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://tech.uvoo.io/index.php?action=history&amp;feed=atom&amp;title=Loki_indexes"/>
	<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Loki_indexes&amp;action=history"/>
	<updated>2026-05-10T18:43:15Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.35.2</generator>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Loki_indexes&amp;diff=5573&amp;oldid=prev</id>
		<title>Busk: Created page with &quot;This is a crucial distinction between Loki and Prometheus, despite both using labels.  ### Loki: Indexes on Labels, Not Message Data  **No, Loki does NOT build a separate inde...&quot;</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Loki_indexes&amp;diff=5573&amp;oldid=prev"/>
		<updated>2025-07-07T19:50:10Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;This is a crucial distinction between Loki and Prometheus, despite both using labels.  ### Loki: Indexes on Labels, Not Message Data  **No, Loki does NOT build a separate inde...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;This is a crucial distinction between Loki and Prometheus, despite both using labels.&lt;br /&gt;
&lt;br /&gt;
### Loki: Indexes on Labels, Not Message Data&lt;br /&gt;
&lt;br /&gt;
**No, Loki does NOT build a separate index for each unique combination of labels *and message data*.**&lt;br /&gt;
&lt;br /&gt;
Here's how Loki works:&lt;br /&gt;
&lt;br /&gt;
* **Labels define streams:** Loki's fundamental concept is the &amp;quot;log stream.&amp;quot; A log stream is defined by a unique combination of **labels**. For example, `app=&amp;quot;webserver&amp;quot;, env=&amp;quot;production&amp;quot;, host=&amp;quot;host-1&amp;quot;` would define one log stream.&lt;br /&gt;
* **Log content is not indexed:** The actual *content* of the log messages themselves is **not indexed** by Loki. This is its core difference from systems like Elasticsearch.&lt;br /&gt;
* **Index on labels only:** Loki builds an index only on the **labels**. This index allows it to quickly identify which log chunks (files containing log lines) contain logs belonging to a specific set of labels.&lt;br /&gt;
* **&amp;quot;Grep&amp;quot; at query time:** When you execute a LogQL query, Loki first uses the label index to narrow down the relevant log streams (and their associated chunks). Once it has those chunks, it then performs a **grep-like search** (text filtering, regex matching, parsing) on the raw log data within those chunks to find the specific log lines that match your query.&lt;br /&gt;
&lt;br /&gt;
**Why this design?**&lt;br /&gt;
&lt;br /&gt;
* **Cost-effective:** Not indexing log content significantly reduces storage requirements and ingestion costs compared to full-text indexing solutions.&lt;br /&gt;
* **Scalability:** It's easier to scale a system that primarily indexes metadata (labels) rather than the entire data payload.&lt;br /&gt;
* **Optimization for specific use cases:** Loki is optimized for use cases where you know the source of your logs (via labels) and then want to &amp;quot;tail&amp;quot; or grep through them, similar to how you'd use `grep` on log files on a server.&lt;br /&gt;
&lt;br /&gt;
**High Cardinality is Bad for Loki:**&lt;br /&gt;
&lt;br /&gt;
Because each unique combination of labels creates a new log stream and new chunks, **high cardinality in Loki is a major anti-pattern**. If you use labels that change frequently or have many unique values (e.g., `user_id`, `request_id`, full URL paths), you will create an explosion of log streams, leading to:&lt;br /&gt;
&lt;br /&gt;
* A very large and inefficient label index.&lt;br /&gt;
* Thousands or millions of tiny chunks, which are inefficient for object storage and increase query latency (more files to open and read).&lt;br /&gt;
* Higher operational costs and performance degradation.&lt;br /&gt;
&lt;br /&gt;
### Prometheus: Indexes on Labels to Create Time Series&lt;br /&gt;
&lt;br /&gt;
**Yes, Prometheus (using TSDB or remote storage) effectively does build a &amp;quot;separate index&amp;quot; for each unique combination of metric name and labels.**&lt;br /&gt;
&lt;br /&gt;
Here's how Prometheus works:&lt;br /&gt;
&lt;br /&gt;
* **Dimensional Data Model:** Prometheus stores all data as time series. Each time series is uniquely identified by its **metric name** and a unique set of **key-value label pairs**.&lt;br /&gt;
* **Each unique combination is a distinct time series:** `http_requests_total{method=&amp;quot;GET&amp;quot;, status=&amp;quot;200&amp;quot;}` is a *completely different time series* from `http_requests_total{method=&amp;quot;POST&amp;quot;, status=&amp;quot;404&amp;quot;}`. Even if they share the same metric name, the labels make them distinct.&lt;br /&gt;
* **TSDB Indexing:** The Prometheus TSDB (Time Series Database) is designed to efficiently store and query these time series. It builds an internal index that maps label sets to the actual time series data chunks.&lt;br /&gt;
    * It uses an **inverted index** where each label value points to a list of series IDs that contain that label. This allows for very fast filtering and aggregation based on label matchers.&lt;br /&gt;
    * Data is stored in &amp;quot;blocks,&amp;quot; and each block contains its own index and chunks of compressed time series data.&lt;br /&gt;
&lt;br /&gt;
**Why this design?**&lt;br /&gt;
&lt;br /&gt;
* **Efficient queries:** Prometheus is built for numerical time-series data and its query language (PromQL) relies heavily on labels for powerful aggregation and filtering. Efficient indexing of label sets is critical for fast PromQL queries.&lt;br /&gt;
* **Metrics vs. Logs:** Metrics are typically lower cardinality than log lines. While you can have millions of metric time series, the expectation is that they are generally bounded, unlike log messages which can contain an infinite variety of content.&lt;br /&gt;
&lt;br /&gt;
**High Cardinality is Bad for Prometheus too (but for different reasons):**&lt;br /&gt;
&lt;br /&gt;
While Prometheus's indexing model *supports* high cardinality better than Loki, extreme high cardinality in Prometheus still leads to significant issues:&lt;br /&gt;
&lt;br /&gt;
* **Increased memory usage:** More unique time series mean more entries in the in-memory index on the Prometheus server.&lt;br /&gt;
* **Increased disk usage:** More time series mean more data to store.&lt;br /&gt;
* **Slower query times:** While the index helps, processing and aggregating over millions of time series can still be computationally intensive.&lt;br /&gt;
* **Higher churn:** If labels change frequently (e.g., dynamic pod names without proper relabeling), it leads to &amp;quot;churn&amp;quot; – old time series are constantly created and new ones appear, putting stress on the TSDB.&lt;br /&gt;
&lt;br /&gt;
**In summary:**&lt;br /&gt;
&lt;br /&gt;
* **Loki:** Indexes only on **labels** to define log streams. The log message content itself is *not* indexed. Searches within the log content are done via &amp;quot;grep&amp;quot; on the retrieved chunks. High label cardinality is very detrimental.&lt;br /&gt;
* **Prometheus:** Indexes on the **combination of metric name and labels** to define unique time series. Each unique combination gets its own dedicated storage and is efficiently indexed for fast querying and aggregation. High label cardinality is also detrimental, but for different resource-based reasons (memory, disk, CPU) rather than the fundamental architectural issue of stream explosion like in Loki.&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
</feed>