Attaching an Index Lifecycle Management (ILM) policy to an Elasticsearch index makes retention, tiering, and cleanup predictable instead of relying on someone remembering to delete old data before disks fill up.

ILM policies live in the cluster state and are referenced from per-index settings. Once an index is linked to a policy (via index.lifecycle.name), the ILM runner evaluates age, size, and phase conditions and executes actions such as allocation, shrink, force merge, downsample, or delete.

Applying a policy to an existing index takes effect immediately, and switching policies requires removing the current assignment first. Policies that contain a rollover action should be applied through an index template so newly created indices inherit the policy; manually attaching a rollover policy to a single index typically leaves the next index unmanaged. Security-enabled clusters require privileges such as manage_ilm and view_index_metadata to update settings and inspect ILM status.

Steps to apply an ILM policy to an Elasticsearch index:

  1. Check whether the index is already managed by ILM.
    $ curl -s "http://localhost:9200/logs-2026.01/_ilm/explain?pretty"
    {
      "indices" : {
        "logs-2026.01" : {
          "index" : "logs-2026.01",
          "managed" : false
        }
      }
    }

    Add --user user:pass or an Authorization header (for example Authorization: ApiKey ...) when Elasticsearch security is enabled.

  2. Remove the existing ILM policy from the index when it is already managed.
    $ curl -s -X POST "http://localhost:9200/logs-2026.01/_ilm/remove?pretty"
    {
      "has_failures" : false,
      "failed_indexes" : [ ]
    }

    Removing a policy stops ILM management for the index until a new policy is applied.

  3. Apply the ILM policy name to the index settings.
    $ curl -s -H "Content-Type: application/json" -X PUT "http://localhost:9200/logs-2026.01/_settings?pretty" -d '{
      "index": {
        "lifecycle": {
          "name": "logs-policy"
        }
      }
    }'
    {
      "acknowledged" : true
    }

    Be careful when using wildcards in the index name (for example logs-*), because the update settings API can modify more indices than intended.

  4. Verify the index is managed by ILM.
    $ curl -s "http://localhost:9200/logs-2026.01/_ilm/explain?pretty"
    {
      "indices" : {
        "logs-2026.01" : {
          "index" : "logs-2026.01",
          "managed" : true,
          "policy" : "logs-policy",
          "index_creation_date_millis" : 1767700875029,
          "time_since_index_creation" : "2.68h",
          "lifecycle_date_millis" : 1767700875029,
          "age" : "2.68h",
          "phase" : "hot",
          "phase_time_millis" : 1767710525625,
          "action" : "rollover",
          "action_time_millis" : 1767710525625,
          "step" : "check-rollover-ready",
          "step_time_millis" : 1767710525625,
          "phase_execution" : {
            "policy" : "logs-policy",
            "phase_definition" : {
              "min_age" : "0ms",
              "actions" : {
                "rollover" : {
                  "max_age" : "7d",
                  "max_size" : "50gb"
                }
              }
            },
            "version" : 1,
            "modified_date_in_millis" : 1767710450545
          }
        }
      }
    }

    When the index enters an error state, the explain output includes the failing phase, action, and reason.