> ## Documentation Index
> Fetch the complete documentation index at: https://docs.coreweave.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Configure bucket lifecycle policies

> Use lifecycle policies to expire objects, clean up old versions, and abort incomplete multipart uploads.

A **bucket lifecycle policy** is a set of rules that tells CoreWeave AI Object Storage to automatically delete objects, expire old object versions, or abort incomplete multipart uploads on a schedule you define. Lifecycle policies are the most reliable way to keep storage costs predictable, prevent unbounded growth from forgotten data, and unblock bucket deletion when incomplete multipart uploads accumulate.

A lifecycle configuration is a JSON document with one or more rules. Each rule has a filter that selects which objects it applies to and one or more actions that run when an object matches the filter and reaches the rule's age threshold.

## Supported actions

AI Object Storage supports the following lifecycle actions:

* **`Expiration`**: Delete current object versions when they reach a given age, on a specific date, or after they become an expired delete marker.
* **`NoncurrentVersionExpiration`**: For versioned buckets, delete noncurrent object versions when they reach a given age. Optionally retain a fixed number of newer noncurrent versions.
* **`AbortIncompleteMultipartUpload`**: Permanently abort multipart uploads that have not completed within a given number of days after initiation, removing all uploaded parts.

`Transition` actions, which move objects between storage classes, are not supported. AI Object Storage manages storage tiering automatically based on access patterns. See [Cost management](/products/storage/object-storage/about#cost-management) for details.

## Key behaviors

Read these behaviors before designing a lifecycle policy.

<Warning>
  **Lifecycle rules ignore Deny statements in bucket and organization access policies.**

  Lifecycle deletions run as a privileged service action and are not evaluated against the bucket access policy or organization access policy. A `Deny` statement on `s3:DeleteObject` does not prevent a lifecycle rule from deleting matching objects. Treat the lifecycle configuration itself as the access boundary for automated deletions, and protect bucket retention by controlling who can call [`s3:PutBucketLifecycleConfiguration`](/products/storage/object-storage/reference/object-storage-s3#s3putbucketlifecycleconfiguration).
</Warning>

* **Object age is measured from creation time, not last access time.** A `Days: 7` rule deletes an object 7 days after it was uploaded, regardless of how recently it was read. To target objects by access pattern, use the [tier-based pricing model](/products/storage/object-storage/about#cost-management) instead.
* **Eligibility is evaluated at UTC midnight day boundaries; once eligible, objects are processed within roughly an hour.** Eligibility is calculated by truncating `creationTime + Days` to midnight UTC. A `Days: 7` rule on an object uploaded at 14:00 UTC on day 1 makes it eligible at midnight UTC on day 8. The lifecycle processor runs approximately every hour -- once the midnight UTC eligibility date has passed, the object is processed in the next hourly run. Storage fees continue to accrue until the physical deletion completes.
* **Versioning interacts with `Expiration`.** On a versioning-enabled bucket, an `Expiration` rule does not permanently delete objects -- it writes a delete marker, making the current version noncurrent. On a versioning-suspended bucket, expiration creates a delete marker with a null version ID; if the current version already has a null version ID, it is permanently replaced. To permanently remove data in either case, also configure `NoncurrentVersionExpiration`.
* **Putting a configuration replaces the existing one.** [`s3:PutBucketLifecycleConfiguration`](/products/storage/object-storage/reference/object-storage-s3#s3putbucketlifecycleconfiguration) overwrites the entire lifecycle configuration for a bucket. Always send the full set of rules you want enforced.
* **Each bucket can have up to 1,000 lifecycle rules.** See [Manage quotas and limits](/products/storage/object-storage/manage-quotas) for the full limits table.
* **Disabling or deleting a rule unschedules pending expirations.** If a rule is disabled or removed, objects that were already queued for expiration are unscheduled and are not deleted.
* **When multiple rules match the same object on the same day, the most aggressive action wins.** Permanent deletion takes precedence over creating a delete marker. If two expiration rules overlap, the shorter expiration period is applied. When a broad rule (empty prefix) and a narrower rule (specific prefix) both match, both run independently.

## Rule filters

A rule's `Filter` selects which objects the rule applies to. A rule with an empty filter applies to every object in the bucket.

### Prefix filter

A prefix filter applies the rule to objects whose keys start with the given prefix. Use prefix filters to scope rules to a folder-like portion of a bucket.

```json title="Apply only to objects under the logs/ prefix" theme={"system"}
{
  "Rules": [
    {
      "ID": "ExpireLogsAfter30Days",
      "Filter": {
        "Prefix": "logs/"
      },
      "Status": "Enabled",
      "Expiration": {
        "Days": 30
      }
    }
  ]
}
```

### Tag filter

A tag filter applies the rule to objects that carry a specific object tag. Use tag filters when objects you want to expire are not grouped by key prefix.

```json title="Apply only to objects tagged temp=true" theme={"system"}
{
  "Rules": [
    {
      "ID": "ExpireTaggedTemporaryObjects",
      "Filter": {
        "Tag": {
          "Key": "temp",
          "Value": "true"
        }
      },
      "Status": "Enabled",
      "Expiration": {
        "Days": 7
      }
    }
  ]
}
```

To match objects that have **all** of multiple tags, wrap the tags in `And`. Objects with additional tags beyond those listed still match.

```json title="Apply only to objects tagged environment=dev AND team=ml-training" theme={"system"}
{
  "Filter": {
    "And": {
      "Tags": [
        { "Key": "environment", "Value": "dev" },
        { "Key": "team", "Value": "ml-training" }
      ]
    }
  }
}
```

### Size filter

A size filter matches objects whose size falls within a specified range. Both boundaries are **exclusive** -- objects exactly at the boundary value are not matched. Values are in bytes.

```json title="Apply only to objects larger than 1 MB and smaller than 100 MB" theme={"system"}
{
  "Filter": {
    "ObjectSizeGreaterThan": 1048576,
    "ObjectSizeLessThan": 104857600
  }
}
```

Size constraints can be combined with a prefix and tags using `And`. See [Combined filter](#combined-filter) below.

### Combined filter

A rule can combine a prefix, multiple tags, and object size constraints by wrapping them in `And`.

```json title="Apply to large objects under archive/ tagged class=cold" theme={"system"}
{
  "Rules": [
    {
      "ID": "ExpireLargeColdArchives",
      "Filter": {
        "And": {
          "Prefix": "archive/",
          "Tags": [
            { "Key": "class", "Value": "cold" }
          ],
          "ObjectSizeGreaterThan": 1048576
        }
      },
      "Status": "Enabled",
      "Expiration": {
        "Days": 90
      }
    }
  ]
}
```

## Common configurations

The following configurations cover the most common use cases. Each configuration is a complete, valid lifecycle document you can apply to a bucket as is.

<Tabs>
  <Tab title="Expire objects after 7 days">
    This configuration expires every object in the bucket 7 days after it is uploaded.

    ```json title="Expire all objects 7 days after creation" theme={"system"}
    {
      "Rules": [
        {
          "ID": "ExpireObjectsAfter7Days",
          "Filter": {},
          "Status": "Enabled",
          "Expiration": {
            "Days": 7
          }
        }
      ]
    }
    ```
  </Tab>

  <Tab title="Expire noncurrent versions">
    On versioned buckets, this configuration expires noncurrent object versions 7 days after they become noncurrent and retains the 10 most recent noncurrent versions of each object.

    ```json title="Expire noncurrent versions after 7 days, keep 10 newest noncurrent" theme={"system"}
    {
      "Rules": [
        {
          "ID": "ExpireNoncurrentAfter7DaysKeep10",
          "Filter": {},
          "Status": "Enabled",
          "NoncurrentVersionExpiration": {
            "NoncurrentDays": 7,
            "NewerNoncurrentVersions": 10
          }
        }
      ]
    }
    ```
  </Tab>

  <Tab title="Abort incomplete multipart uploads">
    This configuration aborts multipart uploads that have not completed 7 days after they were initiated, removing all uploaded parts. This is the recommended baseline for every bucket. Without it, abandoned uploads accumulate as orphaned parts that consume storage and prevent bucket deletion.

    ```json title="Abort incomplete multipart uploads after 7 days" theme={"system"}
    {
      "Rules": [
        {
          "ID": "AbortIncompleteMpuAfter7Days",
          "Filter": {},
          "Status": "Enabled",
          "AbortIncompleteMultipartUpload": {
            "DaysAfterInitiation": 7
          }
        }
      ]
    }
    ```
  </Tab>

  <Tab title="Expire objects on a fixed date">
    Date-based expiration removes matching objects on and after a specific UTC date. Unlike day-count expiration, this is **not a one-time event** -- newly created objects that match the filter continue to be expired as long as the rule is enabled. Disable or remove the rule to stop the action.

    ```json title="Expire all objects after December 31, 2025" theme={"system"}
    {
      "Rules": [
        {
          "ID": "ExpireAfterDate",
          "Filter": {},
          "Status": "Enabled",
          "Expiration": {
            "Date": "2025-12-31T00:00:00Z"
          }
        }
      ]
    }
    ```
  </Tab>

  <Tab title="ML training retention policy">
    This configuration applies three retention rules suited to AI training workloads: short retention for inference outputs, medium retention for training checkpoints, and automatic MPU cleanup across the entire bucket.

    ```json title="Retention policy for training and inference data" theme={"system"}
    {
      "Rules": [
        {
          "ID": "ExpireInferenceOutputs",
          "Filter": { "Prefix": "inference-outputs/" },
          "Status": "Enabled",
          "Expiration": { "Days": 7 }
        },
        {
          "ID": "ExpireTrainingCheckpoints",
          "Filter": { "Prefix": "checkpoints/" },
          "Status": "Enabled",
          "Expiration": { "Days": 14 }
        },
        {
          "ID": "AbortIncompleteMpuAfter7Days",
          "Filter": {},
          "Status": "Enabled",
          "AbortIncompleteMultipartUpload": { "DaysAfterInitiation": 7 }
        }
      ]
    }
    ```
  </Tab>
</Tabs>

You can combine multiple rules in one configuration. A single configuration that applies all three of the preceding patterns at once would include three entries in the `Rules` array.

## Apply a lifecycle configuration

Save the lifecycle configuration to a file, then apply it to your bucket using one of the following clients.

<Tabs>
  <Tab title="AWS CLI">
    1. Save the configuration to a local file, for example `lifecycle.json`.

    2. Apply the configuration. Replace `[BUCKET-NAME]` with the name of your bucket.

       ```bash title="Apply a lifecycle configuration with AWS CLI" theme={"system"}
       aws s3api put-bucket-lifecycle-configuration \
           --bucket [BUCKET-NAME] \
           --lifecycle-configuration file://lifecycle.json
       ```
  </Tab>

  <Tab title="s3cmd">
    s3cmd accepts the lifecycle configuration as an XML document.

    1. Save the configuration to a local file, for example `lifecycle.xml`. The XML form of the abort-incomplete-multipart-upload example shown earlier is:

       ```xml title="lifecycle.xml" theme={"system"}
       <LifecycleConfiguration>
         <Rule>
           <ID>AbortIncompleteMpuAfter7Days</ID>
           <Filter />
           <Status>Enabled</Status>
           <AbortIncompleteMultipartUpload>
             <DaysAfterInitiation>7</DaysAfterInitiation>
           </AbortIncompleteMultipartUpload>
         </Rule>
       </LifecycleConfiguration>
       ```

    2. Apply the configuration. Replace `[BUCKET-NAME]` with the name of your bucket.

       ```bash title="Apply a lifecycle configuration with s3cmd" theme={"system"}
       s3cmd setlifecycle lifecycle.xml s3://[BUCKET-NAME]
       ```
  </Tab>

  <Tab title="Boto3">
    1. Set environment variables for your CoreWeave credentials:

       ```bash theme={"system"}
       export ACCESS_KEY_ID="[ACCESS-KEY-ID]"
       export SECRET_ACCESS_KEY="[SECRET-ACCESS-KEY]"
       ```

       Alternatively, configure your CoreWeave credentials to work with the AWS CLI.

       We recommend using a separate profile for CoreWeave AI Object Storage to avoid conflicts with your other AWS profiles and S3-compatible services. If you don't set up this configuration, you might encounter errors when using AI Object Storage.

           <Accordion title="Configure CoreWeave credentials">
             1. Create a new credentials file and profile in your CoreWeave configuration directory.

                ```bash title="Create a new credentials file and profile" theme={"system"}
                AWS_SHARED_CREDENTIALS_FILE=~/.coreweave/cw.credentials aws configure --profile cw
                ```

             2. When prompted, provide the following values:

                * **AWS Access Key ID**: The [Access Key](/products/storage/object-storage/auth-access/manage-access-keys/create-keys) ID of your CoreWeave AI Object Storage Access Key.
                * **AWS Secret Access Key**: The Secret Key of your CoreWeave AI Object Storage Access Key.
                * **Default region name** (Optional): To set a default region, see [CoreWeave Availability Zones](/products/storage/object-storage/buckets/manage-buckets#availability-zones).
                * **Default output format**: Use `json` for JSON output.

             3. Set the default endpoint URL to the appropriate endpoint for your use case:

                * The primary endpoint, `https://cwobject.com`, for use outside a CoreWeave cluster.
                * The LOTA endpoint, `http://cwlota.com`, for use inside a CoreWeave cluster. The LOTA endpoint routes to the LOTA path for best performance.

                ```bash title="Set the primary endpoint for local development" theme={"system"}
                AWS_CONFIG_FILE=~/.coreweave/cw.config aws configure set endpoint_url https://cwobject.com --profile cw
                ```

             4. Set the S3 `addressing_style` to `virtual`:

                ```bash title="Set virtual addressing style" theme={"system"}
                AWS_CONFIG_FILE=~/.coreweave/cw.config aws configure set s3.addressing_style virtual --profile cw
                ```

             If you set `endpoint_url` and `s3.addressing_style` directly in your code (for example, in a Boto3 `Config` object), you can skip steps 3 and 4. The profile only needs the access key, secret key, and region.
           </Accordion>

    2. Apply the lifecycle configuration. Replace `[BUCKET-NAME]` with the name of your bucket.

       ```python title="Apply a lifecycle configuration with Boto3" theme={"system"}
       import os
       import boto3
       from botocore.client import Config

       boto_config = Config(
           region_name='US-EAST-04A',
           s3={'addressing_style': 'virtual'}
       )

       s3 = boto3.client(
           's3',
           endpoint_url='https://cwobject.com',
           aws_access_key_id=os.environ['ACCESS_KEY_ID'],
           aws_secret_access_key=os.environ['SECRET_ACCESS_KEY'],
           config=boto_config
       )

       response = s3.put_bucket_lifecycle_configuration(
           Bucket='[BUCKET-NAME]',
           LifecycleConfiguration={
               'Rules': [
                   {
                       'ID': 'AbortIncompleteMpuAfter7Days',
                       'Filter': {},
                       'Status': 'Enabled',
                       'AbortIncompleteMultipartUpload': {
                           'DaysAfterInitiation': 7
                       }
                   }
               ]
           }
       )

       print(response)
       ```
  </Tab>
</Tabs>

## Verify a lifecycle configuration

Confirm the active configuration on a bucket. To check when a specific object will expire, use the `HeadObject` (AWS CLI: `head-object`) or `GetObject` API -- the response includes an `x-amz-expiration` header with the expiration date and the rule ID that applies to the object.

<Tabs>
  <Tab title="AWS CLI">
    ```bash title="Get the active lifecycle configuration with AWS CLI" theme={"system"}
    aws s3api get-bucket-lifecycle-configuration --bucket [BUCKET-NAME]
    ```
  </Tab>

  <Tab title="s3cmd">
    ```bash title="Get the active lifecycle configuration with s3cmd" theme={"system"}
    s3cmd getlifecycle s3://[BUCKET-NAME]
    ```
  </Tab>

  <Tab title="Boto3">
    ```python title="Get the active lifecycle configuration with Boto3" theme={"system"}
    import os
    import boto3
    from botocore.client import Config

    boto_config = Config(
        region_name='US-EAST-04A',
        s3={'addressing_style': 'virtual'}
    )

    s3 = boto3.client(
        's3',
        endpoint_url='https://cwobject.com',
        aws_access_key_id=os.environ['ACCESS_KEY_ID'],
        aws_secret_access_key=os.environ['SECRET_ACCESS_KEY'],
        config=boto_config
    )

    response = s3.get_bucket_lifecycle_configuration(Bucket='[BUCKET-NAME]')
    for rule in response.get('Rules', []):
        print(rule)
    ```
  </Tab>
</Tabs>

## Delete a lifecycle configuration

Removing the lifecycle configuration stops all automated lifecycle actions on the bucket. Objects that were already queued for expiration are unscheduled and are not deleted.

<Tabs>
  <Tab title="AWS CLI">
    ```bash title="Delete the lifecycle configuration with AWS CLI" theme={"system"}
    aws s3api delete-bucket-lifecycle --bucket [BUCKET-NAME]
    ```
  </Tab>

  <Tab title="s3cmd">
    ```bash title="Delete the lifecycle configuration with s3cmd" theme={"system"}
    s3cmd dellifecycle s3://[BUCKET-NAME]
    ```
  </Tab>

  <Tab title="Boto3">
    ```python title="Delete the lifecycle configuration with Boto3" theme={"system"}
    import os
    import boto3
    from botocore.client import Config

    boto_config = Config(
        region_name='US-EAST-04A',
        s3={'addressing_style': 'virtual'}
    )

    s3 = boto3.client(
        's3',
        endpoint_url='https://cwobject.com',
        aws_access_key_id=os.environ['ACCESS_KEY_ID'],
        aws_secret_access_key=os.environ['SECRET_ACCESS_KEY'],
        config=boto_config
    )

    s3.delete_bucket_lifecycle(Bucket='[BUCKET-NAME]')
    ```
  </Tab>
</Tabs>

## Rule field reference

The following fields are available in a lifecycle rule:

| Field                                  | Description                                                                                                                                                                                                          |
| -------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ID`                                   | Identifier for the rule. Up to 255 characters.                                                                                                                                                                       |
| `Filter`                               | Selects which objects the rule applies to. Contains a `Prefix`, `Tag`, or `And` clause. An empty filter matches every object in the bucket.                                                                          |
| `Filter.Prefix`                        | Object key prefix to match. For example, `foo/` matches both `foo/bar` and `foo/baz`.                                                                                                                                |
| `Filter.Tag`                           | A single tag key/value pair to match.                                                                                                                                                                                |
| `Filter.And`                           | Combines a prefix, multiple tags, and object size constraints in one filter.                                                                                                                                         |
| `Filter.ObjectSizeGreaterThan`         | Minimum object size, in bytes.                                                                                                                                                                                       |
| `Filter.ObjectSizeLessThan`            | Maximum object size, in bytes.                                                                                                                                                                                       |
| `Status`                               | `Enabled` or `Disabled`. Disabled rules do not run.                                                                                                                                                                  |
| `Expiration`                           | Deletes the current version of matching objects when they reach a given age (`Days`), on a specific UTC date in ISO 8601 format (`Date`), or when an expired delete marker is present (`ExpiredObjectDeleteMarker`). |
| `Expiration.ExpiredObjectDeleteMarker` | If `true`, removes a delete marker that has no remaining noncurrent versions. Cannot be combined with `Days` or `Date`.                                                                                              |
| `NoncurrentVersionExpiration`          | On versioned buckets, deletes noncurrent versions after `NoncurrentDays`. Optionally retains `NewerNoncurrentVersions` of the most recent noncurrent versions.                                                       |
| `AbortIncompleteMultipartUpload`       | Aborts multipart uploads that have not completed `DaysAfterInitiation` days after they were started.                                                                                                                 |

## Common questions

**Can I recover objects that were deleted by a lifecycle rule?**

In a non-versioned bucket, no -- expired objects are permanently deleted. In a versioning-enabled bucket, an `Expiration` rule creates a delete marker rather than permanently deleting the object, so you can restore a previous version by copying it back as the current version. Enable versioning before configuring expiration rules if you need recoverability.

**Can I use multiple prefixes in a single rule?**

No. A single lifecycle rule supports only one prefix. To apply the same action to objects under multiple prefixes, either create a separate rule for each prefix, or use object tags to group objects under a tag-based filter.

**Can I exclude a prefix from a lifecycle rule?**

Lifecycle rules do not support exclusion filters. Use object tags to mark the objects you want to include, then create a tag-based rule that targets them rather than trying to exclude objects by prefix.

**Do lifecycle rules apply to objects that already exist in the bucket?**

Yes. When you add or update a lifecycle configuration, rules apply to both existing and newly created objects. Existing objects that already meet the expiration criteria are queued for removal immediately.

**What happens when I update a lifecycle configuration?**

[`PutBucketLifecycleConfiguration`](/products/storage/object-storage/reference/object-storage-s3#s3putbucketlifecycleconfiguration) replaces the entire existing configuration. To add or modify a single rule, retrieve the current configuration first, make your changes, and then put the updated configuration back.

## Related

* [Empty and delete a bucket](/products/storage/object-storage/buckets/empty-and-delete-bucket): Use a lifecycle policy to keep buckets ready for deletion.
* [Abort incomplete multipart uploads](/products/storage/object-storage/buckets/abort-multipart-uploads): Locate and clean up incomplete multipart uploads before applying a recurring rule.
* [Versioned buckets](/products/storage/object-storage/buckets/rclone-versioned-buckets): Manage versioned buckets and noncurrent versions.
* [Manage AI Object Storage with Terraform](/products/storage/object-storage/use-terraform-aws-provider): Apply lifecycle configurations as code, including a known issue with `NoncurrentVersionTransitions` in version 0.7.0 of the CoreWeave provider.
* [S3 API compatibility](/products/storage/object-storage/reference/object-storage-s3#s3-api-compatibility-notes): Reference notes for `PutBucketLifecycleConfiguration`, `GetBucketLifecycleConfiguration`, and `DeleteBucketLifecycle`.
