Skip to content

Object Lifecycle

Available in lakeFS Enterprise, starting v1.101.0. Start a free trial.

Overview

Long-lived branches such as main, staging, and production are where data accumulates fastest. Ingestion pipelines write a fresh set of objects under a new dated prefix every time they execute and nothing removes the older ones, intermediate outputs get committed alongside the results they were meant to produce and then stay there, and sensitive data can outlive the retention window your compliance policy promises. Cleaning this up by hand means writing scripts that list and delete objects one by one, which is slow at data lake scale and leaves no durable record of what policy was applied or when.

Object Lifecycle turns that cleanup into repository-level rule. You define rules that say which objects to expire, on which branches, and after how long, and lakeFS applies them on a schedule. Objects selected by a rule are soft-deleted through a commit on the target branch, so the cleanup is versioned, reviewable, and reversible in the same way any other change to your data is. Once expired, those objects become eligible for permanent removal by Garbage Collection.

Object Lifecycle uses a rule-based configuration model similar to lifecycle configuration in Amazon S3, Azure Blob Storage, and Google Cloud Storage, applied to lakeFS branches instead of buckets.

Benefits

  • Scale: Cleanup is fast whether a rule expires a hundred objects or ten million.
  • Auditable: Every cleanup leaves a record of exactly what was expired, and by which rule.
  • Reversible: The state before a cleanup stays reachable until Garbage Collection removes the data.

Use cases

  • Compliance-driven expiration: Remove sensitive data under a prefix such as pii/ once it passes the retention period your policy allows, or cap retention across the whole repository with a single rule over all objects.
  • Storage cost control: Expire committed data under prefixes such as raw/ or tmp/ that no pipeline deletes.

How it works

You define rules on a repository. A rule reads as a single sentence: expire objects under raw/ on main after 90 days.

rules:
  - id: raw-landing-expiry
    branches: ["main"]
    prefix: "raw/"
    expire_after_days: 90

An object is expired when its key starts with the rule's prefix and its age exceeds expire_after_days, measured from the object's last modification time as recorded in lakeFS rather than in the object store. Only committed objects are evaluated.

A scheduled job evaluates the rules and, for each target branch, removes all matching objects in a single commit. Evaluation is asynchronous, so a new or edited rule takes effect on the next cycle rather than immediately. The job runs daily by default, on a schedule your server administrator can change (see server configuration), and a single instance runs it at a time even when lakeFS is deployed with multiple replicas. A branch that has uncommitted changes is skipped for that cycle. Skipped branches, along with any branch the job fails to clean for another reason, are left untouched and picked up on the next cycle, so one branch never holds up the rest of the run.

Rule fields

Field Required Description
id yes Identifier for the rule, unique within the repository. Up to 64 lowercase alphanumeric characters and hyphens, not starting with a hyphen (for example, raw-landing-expiry).
branches yes Exact names of the branches the rule applies to, including protected branches. No wildcards. At least one branch, and at most 20 distinct branches across all rules. A branch that does not exist is accepted and has no effect.
prefix yes Literal key prefix, with no wildcards or regular expressions. A non-empty prefix must end with / (for example, raw/ or tmp/staging/). An empty prefix matches every object in the repository.
expire_after_days yes Age in days after which a matching object is expired. An integer between 1 and 3650.
description no Free-form note shown in the UI and CLI.

Note

A repository supports up to 1,000 rules.

An empty prefix expires everything

A rule with an empty prefix matches every object in the repository on its target branches. In the Web UI this choice is an explicit All objects option on the rule form, so it cannot be selected by leaving the prefix field blank.

Overlapping rules

Rules are evaluated independently, with no ordering or priority between them, so overlapping prefixes are allowed and nested prefixes behave predictably. An object matched by several rules is expired as soon as the shortest expire_after_days among them is reached, and the expiration is attributed to that rule. When two matching rules specify the same number of days, attribution goes to the first rule alphabetically by ID.

The cleanup commit

Each cycle produces at most one commit per branch, covering every rule that targets it:

A cleanup commit in the lakeFS commit view

  • The committer is the dedicated system user object-lifecycle-manager.
  • Commit metadata records the per-rule attribution and the instant the run evaluated against (see Monitoring cleanup runs).

Note

Commit hooks do not run for cleanup commits, so a pre-commit hook cannot block or annotate them.

Managing rules

Rules can be managed from the lakeFS UI, lakectl, or the API. To turn the feature off for a repository, clear its rules.

  1. Navigate to your repository.
  2. Go to SettingsData Retention.
  3. In the Object lifecycle section, click Create rule, or use the actions menu on an existing row to edit or delete a rule.
  4. Fill in the Rule ID and the Branches the rule applies to, entered as a comma-separated list of exact branch names.
  5. Under Apply to, choose Objects under a prefix and enter the prefix, or choose All objects for a repository-wide rule.
  6. Set Expire after in days, optionally add a description, and save.

Write your rules to a YAML or JSON file and apply them. The example below uses YAML, and JSON is accepted as well.

cat > rules.yaml <<'EOF'
rules:
  - id: "raw-staging-expiry"
    prefix: "raw/"
    branches: ["main"]
    expire_after_days: 90
    description: "Expire raw staging objects"
  - id: "temp-object-expiry"
    prefix: "tmp/"
    branches: ["main", "staging"]
    expire_after_days: 7
EOF

lakectl object-lifecycle set lakefs://my-repo -f rules.yaml

set replaces the repository's entire ruleset with the contents of the file, so include every rule you want to keep. Use -f - to read the ruleset from stdin.

Other commands:

lakectl object-lifecycle get   lakefs://my-repo
lakectl object-lifecycle get   lakefs://my-repo --json
lakectl object-lifecycle clear lakefs://my-repo

get prints the ruleset as YAML by default, or as JSON with --json. clear removes all rules from the repository and is idempotent, so it succeeds even when no rules are set.

Three endpoints manage the ruleset at the repository level:

Method Path Description
GET /repositories/{repository}/settings/object_lifecycle Get all rules
PUT /repositories/{repository}/settings/object_lifecycle Replace all rules
DELETE /repositories/{repository}/settings/object_lifecycle Clear all rules

The API operates on the complete ruleset, and there are no per-rule endpoints. Adding, changing, or removing a single rule is a read-modify-write: GET the ruleset, modify it, and PUT it back.

This is the canonical JSON, as stored and as returned by GET:

{
  "rules": [
    {
      "id": "raw-landing-expiry",
      "prefix": "raw/",
      "branches": ["main"],
      "expire_after_days": 90,
      "description": "Expire raw landing data"
    },
    {
      "id": "max-retention",
      "prefix": "",
      "branches": ["main", "staging"],
      "expire_after_days": 1095,
      "description": "Compliance: expire everything older than 3 years"
    }
  ]
}

Permissions

The following RBAC actions gate the feature:

  • retention:GetObjectLifecycleRules - read the repository's rules.
  • retention:SetObjectLifecycleRules - create, update, or clear rules.

Both are scoped to the repository resource, arn:lakefs:fs:::repository/{repositoryId}.

Monitoring cleanup runs

Three places show what a cleanup did:

  • The commit on the target branch. Its diff is the per-object list of what was expired, and its metadata carries the per-rule tally (.lakefs.object-lifecycle.expired_by_rule), the run total (expired_total), and the instant ages were judged against (evaluated_at).
  • The audit log, where each cleanup commit is recorded with operation_id: CleanupCommit and service_name: object_lifecycle, attributed to the object-lifecycle-manager system user.
  • The lakeFS server log, where each run records its duration, the branches and rules it evaluated, the objects expired, and the reason for any branch that was skipped or failed.