How to configure retention in Loki

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.

Steps to configure retention in Loki:

  1. Open the active Loki configuration file.
    $ vi loki-config.yaml
  2. Confirm the schema index period is 24h.
    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.

  3. Add compactor retention settings.
    loki-config.yaml
    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.

  4. Set the global retention period.
    loki-config.yaml
    limits_config:
      retention_period: 744h

    744h is 31 days. Use a value that matches the environment's retention policy.

  5. Add stream-specific retention only when a labeled subset needs a different lifetime.
    loki-config.yaml
    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.

  6. Validate the file by starting a disposable Loki container with the updated configuration.
    $ 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
  7. Restart Loki through the deployment mechanism that owns the container.
    $ docker compose up -d loki
    Container loki-compose-loki-1  Recreate
    Container loki-compose-loki-1  Started
  8. Check the readiness endpoint after restart.
    $ curl --silent http://127.0.0.1:3100/ready
    ready
  9. Check the Loki log for retention and compactor startup messages.
    $ 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.