cloudparts

Grafana Loki

A log store that indexes only a few labels per stream, keeps the log lines as compressed chunks in object storage, and greps them at query time with LogQL.

What it is
Logs
Type
Open source
Made by
Grafana Labs
License
AGPLv3 (Apache 2.0 until April 2021)
Facts checked
24 October 2026

What it is

Most log search engines index every word of every line. Loki indexes almost nothing: each log line belongs to a stream, a unique set of labels such as {service_name="checkout", namespace="prod"}, and only those labels go into the index. The lines themselves are compressed into chunks, and both the index and the chunks are stored in one object storage bucket, such as Amazon S3, Google Cloud Storage or Azure Blob Storage. A query first picks streams by label, then reads their chunks for the time range and filters the lines, much like grep. The docs sum it up: a small index and highly compressed chunks make Loki simpler to run and much cheaper.

Logs arrive over HTTP from an agent such as Grafana Alloy or from any OpenTelemetry Collector, since Loki 3.0 has a native OTLP endpoint; resource attributes such as service.name and k8s.namespace.name become labels, and other attributes are kept as structured metadata next to the line. You query with LogQL, which looks like PromQL: {job="mysql"} |= "error" returns lines, and rate(...) over the same selector turns them into a metric you can graph or alert on through the ruler. All components (distributor, ingester, querier, query frontend and others) are in one binary, which runs as a single process or split into microservices. Grafana Labs moved Loki from Apache 2.0 to AGPLv3 in April 2021; the current line is 3.7.

Why teams pick it

  • Cheap to keep a lot of logs: the index stays small and the data sits compressed in object storage, so nobody is asked to log less
  • Uses the same labels as Prometheus and Tempo, so Grafana can jump from a spiking metric or a slow trace to the logs of the same service and time
  • LogQL turns logs into metrics with rate and count_over_time, and the ruler alerts on them through Alertmanager or Grafana Alerting
  • Scales from one process on a laptop to a microservices deployment ingesting petabytes a day, with the same binary and storage format

Watch out for

  • No full-text index: a search for a word reads every chunk of every selected stream in the time range, so broad queries over days of logs are slow and costly
  • Labels must have few values. The docs recommend 10 to 15 at most (the default limit is 15) and warn that user IDs or IP addresses as labels build a huge index and thousands of tiny chunks
  • Running it at scale means a dozen components with hash rings and caches to size; the middle option, simple scalable mode, is deprecated and will be removed in Loki 4.0
  • AGPLv3 since 2021; Promtail, its original agent, was removed in 3.7.3, so pipelines that used it must move to Alloy or an OpenTelemetry Collector
Data model
Log streams named by label sets; lines in compressed chunks
Query language
LogQL
Client protocol
HTTP push API and native OTLP
Secondary indexes
Labels only; no full-text index
How it scales
One binary, run as a single process or split into microservices
Storage format
Compressed chunks and a small index in object storage
Ways to run it
Self-hosted

Alternatives

What all logs have in common →Compare side by side →

How it fits with other technologies

LogQL: pick streams by label, filter lines, then count · text

# Log query: lines from the mysql job that contain "error" but not "timeout"
{job="mysql"} |= "error" != "timeout"

# Parse each line as JSON and keep only slow requests
{job="mysql"} |= "error" | json | duration > 10s

# Metric query: errors per second, per host, over 1-minute windows
sum by (host) (rate({job="mysql"} |= "error" != "timeout" | json | duration > 10s [1m]))

See it in a real stack

Self-hosted observability on the LGTM stack →
Live model
What you’re watchingServices emit logs, metrics and spans (three colours) to a collector, which routes each signal to Loki, Mimir or Tempo; all three write their data to object storage. Engineers’ dashboards and searches go through Grafana, which sends LogQL, PromQL or TraceQL to the matching store, and the answers come back from recent data and from the bucket.
Where it came from2018–2026

By 2018 Grafana Labs had metrics covered by Prometheus and wanted logs to match. Kubernetes made the problem obvious: kubectl logs shows only recent lines, and when a pod or node is gone, so are its logs. The existing log systems were, in the team’s words, too expensive or too unstable, and people were being asked to log less. That year Grafana Labs acquired Kausal and started Loki as a new open-source project; Tom Wilkie made the first commit to its repository on April 15, 2018.

The design goals were short: “Keep it simple. Just support grep!”, “Logs should be cheap. Nobody should be asked to log less.”, and metrics, logs and traces should work together. Loki borrowed Prometheus’s labels and its relabelling rules so that a log stream carries the same metadata as the metrics from the same pod, and its architecture came from the team’s experience running Cortex, a horizontally scalable Prometheus: the code that shards streams across ingesters was mostly taken from it. Goutham Veeramachaneni announced it in December 2018 as alpha software.

Loki 1.0 followed in November 2019 and 2.0 in October 2020. In April 2021 Grafana Labs relicensed Loki, with Grafana and Tempo, from Apache 2.0 to AGPLv3. Loki 3.0, in April 2024, added native OpenTelemetry ingestion, structured metadata and experimental bloom filters to skip chunks. In 2026 Loki 3.7 removed Promtail in favour of Grafana Alloy and handed its Helm chart to the community.

Why it’s built this way

Index labels, not log contents
The team wanted logs to be cheap and searching to be as simple as grep. Indexing only a stream’s labels keeps the index small; the price is that the querier must read and filter the chunks of every matching stream, a step later spread over many queriers by the query frontend.
The same labels as Prometheus
The agent applied the same relabelling rules as Prometheus, so logs and metrics from one pod share metadata and Grafana can switch between them on one time range without a lookup table.
Object storage for everything
Chunks in S3 or GCS cost far less than replicated disks. Early versions kept the index in Cassandra, Bigtable or DynamoDB; later the index also moved to the bucket, so a bucket is the only storage dependency.
One binary, many roles
The same binary runs every component or just one, picked with -target, so a team can start with one process and split it into microservices later without changing the data format.

Timeline

  1. 2018

    Tom Wilkie’s first commit in April; announced as alpha at the end of the year

  2. 2019

    Loki 1.0 in November

  3. 2020

    Loki 2.0 in October

  4. 2021

    Relicensed from Apache 2.0 to AGPLv3 in April

  5. 2024

    Loki 3.0 in April: native OTLP ingestion, structured metadata, bloom filters

  6. 2026

    Loki 3.7 in March; Promtail removed in 3.7.3 in favour of Grafana Alloy

Sources9 · facts checked 24 October 2026

Improve this page on GitHub