Configuring retention in Loki controls how long stored log chunks remain queryable before the compactor marks them for deletion. It matters when local disk, object storage cost, or compliance policy requires logs to expire after a defined period.
Retention is enforced by the Loki compactor, and the compactor needs persistent working storage for marker files that track chunks waiting for deletion. For TSDB and BoltDB single-store indexes, the index period must be 24h for retention to work.
Set a global retention period first, then add stream-specific retention only when a label selector has a clear policy reason. The minimum retention period is 24h, and retention is not immediate because Loki delays chunk deletion to protect query components that may still have older index data.
$ vi loki-config.yaml
schema_config: configs: - from: "2024-01-01" store: tsdb object_store: filesystem schema: v13 index: prefix: index_ period: 24h
Retention requires a 24h index period with the supported single-store index types.
compactor: working_directory: /loki/retention compaction_interval: 10m retention_enabled: true retention_delete_delay: 2h retention_delete_worker_count: 150 delete_request_store: filesystem
Keep the compactor working directory on persistent storage. Losing marker files can leave chunks pending deletion after a restart.
limits_config: retention_period: 744h
744h is 31 days. Use a value that matches the environment's retention policy.
limits_config: retention_period: 744h retention_stream: - selector: '{namespace="dev"}' priority: 1 period: 24h
The selector field accepts label matchers, not arbitrary LogQL pipeline expressions.
$ docker run --rm \ --volume "$PWD/loki-config.yaml:/etc/loki/loki-config.yaml:ro" \ grafana/loki:3.7.1 \ -config.file=/etc/loki/loki-config.yaml \ -verify-config config is valid
$ docker compose up -d loki Container loki-compose-loki-1 Recreate Container loki-compose-loki-1 Started
$ curl --silent http://127.0.0.1:3100/ready ready
$ docker compose logs loki ##### snipped ##### level=info caller=module_service.go msg="module started" module=compactor level=info caller=compactor.go msg="retention enabled"
Chunk deletion happens after compaction and the configured delete delay, so a successful restart does not immediately remove older chunks.