[Setup](https://docs.cloud.google.com/storage/docs/using-object-versioning.md.txt)
[Usage](https://docs.cloud.google.com/storage/docs/using-versioned-objects.md.txt)

Object Versioning preserves deleted objects as versioned, noncurrent objects
that remain accessible in your bucket until explicitly removed. This feature
is used to track changes to objects and to enable recovery of specific
versions of an object. This page describes the feature and the options
available when using it.

We recommend that you use [soft delete](https://docs.cloud.google.com/storage/docs/soft-delete.md.txt)
instead of Object Versioning to protect against permanent data loss from
accidental or malicious deletions. To learn more about when to use
soft delete and Object Versioning, see
[Considerations](https://docs.cloud.google.com/storage/docs/object-versioning.md.txt#considerations).

> [!CAUTION]
> **Caution:** Objects can only be recovered from a deleted bucket when soft delete is enabled. Object Versioning does not provide protection against bucket deletions.

## Introduction

You [enable Object Versioning](https://docs.cloud.google.com/storage/docs/using-object-versioning.md.txt#set) for a *bucket*. Once enabled:

- Cloud Storage retains a *noncurrent object version* each time you
  replace or delete a *live* object version, as long as you don't specify the
  [generation number](https://docs.cloud.google.com/storage/docs/metadata.md.txt#generation-number) of the live version.

  - Noncurrent versions retain the name of the object, but are uniquely
    identified by their generation number.

  - Noncurrent versions only appear in requests that explicitly call for them
    to be included.

- You delete a noncurrent version of an object by including the generation
  number in the deletion request or by using [Object Lifecycle Management](https://docs.cloud.google.com/storage/docs/lifecycle.md.txt).

- In a bucket with soft delete enabled, when you delete a noncurrent
  object, Cloud Storage changes its state to soft-deleted. A
  soft-deleted object is permanently deleted after its soft delete
  retention period expires.

- Noncurrent versions of objects exist independently of any live version.

If you [disable Object Versioning](https://docs.cloud.google.com/storage/docs/using-object-versioning.md.txt#set):

- The bucket no longer accumulates new noncurrent versions of objects.

- Object versions that already exist in the bucket are unaffected.

> [!IMPORTANT]
> **Important:** If you change the versioning configuration for a bucket, the change may take time to propagate, and object deletions or replacements in the bucket may behave according to the previous setting for a short period of time. In order to ensure object deletions and replacements behave according to your change, wait at least 30 seconds between changing the versioning configuration and deleting or replacing objects.

### Considerations

- There is no default limit on the number of object versions you can have. Each
  noncurrent version of an object is [charged](https://docs.cloud.google.com/storage/pricing) at the same rate it was when
  it was live.

- [Early deletion charges](https://docs.cloud.google.com/storage/pricing#early-delete) apply only when an object version is removed
  from the bucket, not when the version becomes noncurrent. The storage
  duration for a version removed from a bucket is based on the time it was
  added to the bucket, not the time it became noncurrent.

<!-- -->

- If you enable versioning, consider using [Object Lifecycle Management](https://docs.cloud.google.com/storage/docs/lifecycle.md.txt),
  which can remove older versions of an object after a specified length of
  time or as newer versions become noncurrent. For one possible setup, see
  the lifecycle configuration [example for deleting objects](https://docs.cloud.google.com/storage/docs/lifecycle-configurations.md.txt#deletion-example).

- To determine whether to enable Object Versioning or soft delete on
  your bucket, consider the following points:

  - If you want to prevent permanent data loss from accidental or
    malicious deletions, use soft delete instead of Object Versioning.
    soft delete provides bucket-level protection by retaining all
    recently deleted live or noncurrent objects. It also can protect against
    bucket-level deletions.

  - If you have specific billing requirements and have configured
    Object Lifecycle Management rules to retain a specified
    number of noncurrent versions, use Object Versioning.

    In such a scenario, you only get partial protection from
    accidental deletions because Object Versioning does not protect against
    bucket-level events or undesired noncurrent object deletions.
  - Noncurrent objects are accessible and readable, while soft-deleted
    objects are retained offline and are non-readable. Restoring soft-deleted
    objects requires [specific IAM permissions](https://docs.cloud.google.com/storage/docs/use-soft-deleted-objects.md.txt#before-you-begin) that are available to the
    Storage Admin (`roles/storage.admin`) IAM role.

    If you want access to the most recently deleted objects and a high level
    of protection against permanent data loss from accidental and
    malicious deletion events, you can
    enable Object Versioning and soft delete on the same bucket.
    You can configure the Object Lifecycle Management policy to automatically
    delete noncurrent versions after a specific number of days, and then use
    soft delete to provide an additional layer of protection.

### Noncurrent object metadata

Noncurrent versions of objects have their own metadata, which may differ from
the metadata of the live version. Most importantly, a noncurrent version retains
its [ACLs](https://docs.cloud.google.com/storage/docs/access-control/lists.md.txt) and does not necessarily have the same permissions as the live
version.

Each version, whether live or noncurrent, has one set of metadata; only the
latest [metageneration number](https://docs.cloud.google.com/storage/docs/metadata.md.txt#generation-number) refers to metadata. Older metageneration
numbers cannot be used to access metadata that has since been changed.

You can update metadata for a noncurrent version of an object by specifying its
`generation` in your request. To ensure safe read-modify-write semantics, you
can use a [metageneration-match precondition](https://docs.cloud.google.com/storage/docs/request-preconditions.md.txt). Using this precondition causes
the update to fail if the metadata you are attempting to update was
changed between the time you read the metadata and sent the update.

## Object Versioning example

This example shows what happens to the object `cat.jpg` in a bucket
with Object Versioning and soft delete enabled as you replace, update,
and delete the object.

You upload a new image

:   When you first [upload `cat.jpg` to Cloud Storage](https://docs.cloud.google.com/storage/docs/uploading-objects.md.txt), it receives a
    [`generation` number and a `metageneration` number](https://docs.cloud.google.com/storage/docs/metadata.md.txt#generation-number). In this example, the
    generation number is `1360887697105000`. Because the object is
    new, the `metageneration` number is `1`.

    `cat.jpg` receives `generation` and `metageneration` numbers even though
    Object Versioning is not enabled. You can obtain these numbers by
    [viewing the object metadata](https://docs.cloud.google.com/storage/docs/viewing-editing-metadata.md.txt#view).

You enable Object Versioning

:   At this point, you decide to [enable Object Versioning](https://docs.cloud.google.com/storage/docs/using-object-versioning.md.txt#set) for your bucket.
    Doing so does not affect the `generation` or `metageneration` numbers of
    `cat.jpg`.

You change the metadata of the image

:   You update the metadata for `cat.jpg` by
    [adding custom metadata](https://docs.cloud.google.com/storage/docs/viewing-editing-metadata.md.txt#edit): `color:black`. Updating metadata causes the
    `metageneration` value of `cat.jpg` to increase, in this case from
    `1` to `2`. However, the object itself remains unchanged, so Cloud Storage
    continues to store only one version of `cat.jpg`, and the version continues
    to have a `generation` number of `1360887697105000`.

You upload a new version of the image

:   You upload a new version of `cat.jpg` to your Cloud Storage bucket.
    When you do so, Object Versioning moves the existing `cat.jpg` object into
    a noncurrent state. The noncurrent version retains the same storage class
    and metadata it previously had. The noncurrent version appears only if you
    [perform a versioned listing](https://docs.cloud.google.com/storage/docs/using-versioned-objects.md.txt#list): it does not appear in normal listing
    commands. The noncurrent version is now referenced as:
    `cat.jpg#1360887697105000`.

    Meanwhile, the newly uploaded `cat.jpg` becomes the live version of the
    object. This new `cat.jpg` gets its own `generation` number, in this example
    `1360887759327000`. It also gets its own metadata and a `metageneration`
    number of `1`, which means it does not contain the `color:black` metadata
    unless you specify it. When you access or modify `cat.jpg,` this is the
    version that is used. You can alternatively refer to this version of
    `cat.jpg` using its `generation` number. For example, when using the
    Google Cloud CLI, you would refer to it as `cat.jpg#1360887759327000`.

You delete the live version of the image

:   You now delete `cat.jpg`. When you do this, the version that had generation
    number `1360887759327000` becomes noncurrent. Your bucket now
    contains two noncurrent versions of `cat.jpg` and no live versions. You can
    still refer to either noncurrent version by using its `generation` number,
    but if you try to access `cat.jpg` without a `generation` number, it fails.

    Similarly, a normal object listing of the bucket won't show `cat.jpg` as one
    of the objects in the bucket. For information on listing noncurrent versions
    of objects, see [Listing noncurrent object versions](https://docs.cloud.google.com/storage/docs/using-versioned-objects.md.txt#list).

You disable Object Versioning

:   You [disable Object Versioning](https://docs.cloud.google.com/storage/docs/lifecycle-configurations.md.txt#deletion-example), which stops objects from becoming
    noncurrent. Existing noncurrent versions of objects remain in
    Cloud Storage. Even though Object Versioning is disabled,
    `cat.jpg#1360887697105000` and `cat.jpg#1360887759327000` remain stored
    in your bucket until you delete them.

You restore one of the noncurrent versions

:   Even with Object Versioning disabled, you can make a copy of one of the
    existing noncurrent versions, which effectively [restores the version](https://docs.cloud.google.com/storage/docs/using-versioned-objects.md.txt#restore).
    Once you do this, your bucket has three versions of `cat.jpg`: the two
    noncurrent versions and the live version that came from restoring.

You delete one of the noncurrent versions

:   You can delete a noncurrent version of an object [manually](https://docs.cloud.google.com/storage/docs/using-versioned-objects.md.txt#delete) or by using
    [Object Lifecycle Management](https://docs.cloud.google.com/storage/docs/lifecycle.md.txt).

    When you delete a noncurrent version, `cat.jpg#1360887697105000`, it
    gets soft-deleted. This soft-deleted object is retained for the
    soft delete retention duration specified in the
    soft delete policy of the bucket. After the retention duration expires,
    Cloud Storage permanently deletes the soft-deleted version of
    this object.

You restore one of the soft-deleted object versions

:   Even with Object Versioning disabled, you can restore a soft-deleted version
    of a noncurrent object. A copy of a soft-deleted version is restored as the
    live version with new object metadata and a new creation date. The original
    soft-deleted object also remains in the bucket and is permanently deleted
    after its soft delete retention duration expires.

## Object Versioning reference

This reference table shows what happens when you take certain actions with Object
Versioning.

| Object Versioning status | Soft delete status | Action | Result |
|---|---|---|---|
| **Disabled** | **Disabled** |   |   |
|   |   | Delete `dog.png`. | `dog.png` is permanently deleted. |
|   |   | Delete a noncurrent version of `dog.png` by specifying its generation number.^1^ | The noncurrent version is permanently deleted. |
|   |   | Replace `dog.png` with a new version. | The new version replaces the live version and receives a new generation number. The old live version is permanently deleted. |
|   |   | Copy a noncurrent version of `dog.png` over the live version.^1^ | A copy of the noncurrent version replaces the live version and receives a new generation number. The old live version is permanently deleted. |
| **Disabled** | **Enabled** |   |   |
|   |   | Delete `dog.png`. | `dog.png` is soft-deleted. |
|   |   | Delete a noncurrent version of `dog.png` by specifying its generation number.^1^ | The noncurrent version is soft-deleted. |
|   |   | Replace `dog.png` with a new version. | The new version replaces the live version and receives a new generation number. The old live version is soft-deleted. |
|   |   | Copy a noncurrent version of `dog.png` over the live version.^1^ | A copy of the noncurrent version replaces the live version and receives a new generation number. The old live version is soft-deleted. |
| **Enabled** | **Disabled** |   |   |
|   |   | Delete the live version of `dog.png` without specifying its generation number. | The live version becomes a noncurrent version and keeps the same generation number. |
|   |   | Delete the live version of `dog.png` by specifying its generation number. | The live version is permanently deleted. |
|   |   | Delete a noncurrent version of `dog.png` by specifying its generation number. | The noncurrent version is permanently deleted. |
|   |   | Replace `dog.png` with a new version. | The new version replaces the live version and receives a new generation number. The old live version becomes a noncurrent version and keeps the same generation number. |
|   |   | Copy a noncurrent version of `dog.png` over the live version. | A copy of the noncurrent version replaces the live version and receives a new generation number. The old live version becomes a noncurrent version and keeps the same generation number. |
| **Enabled** | **Enabled** |   |   |
|   |   | Delete the live version of `dog.png` without specifying its generation number. | The live version becomes a noncurrent version and keeps the same generation number. |
|   |   | Delete the live version of `dog.png` by specifying its generation number. | The live version is soft-deleted. |
|   |   | Delete a noncurrent version of `dog.png` by specifying its generation number. | The noncurrent version is soft-deleted. |
|   |   | Replace `dog.png` with a new version. | The new version replaces the live version and receives a new generation number. The old live version becomes a noncurrent version and keeps the same generation number. |
|   |   | Copy a noncurrent version of `dog.png` over the live version. | A copy of the noncurrent version replaces the live version and receives a new generation number. The old live version becomes a noncurrent version and keeps the same generation number. |

^1^ A noncurrent version might exist if the bucket had Object Versioning enabled previously.

## Restoration behavior

You can effectively restore a noncurrent object version to the current live
version. See [Restoring noncurrent object versions](https://docs.cloud.google.com/storage/docs/using-versioned-objects.md.txt#restore) for a step-by-step
guide to doing so.

When you do this with Object Versioning enabled, if there already exists a live
version of the object in your bucket, Cloud Storage replaces the
existing live version but also retains it as a new noncurrent version. In such a
case, your bucket subsequently contains the replaced object (now noncurrent) and
two copies of the object that was previously noncurrent (one live copy and one
still-noncurrent copy), all of which incur storage charges. To prevent
unnecessary charges, [delete the noncurrent version](https://docs.cloud.google.com/storage/docs/using-versioned-objects.md.txt#delete) that you used to make
the current live copy, or configure [Object Lifecycle Management](https://docs.cloud.google.com/storage/docs/lifecycle.md.txt) to remove
noncurrent objects when they meet the conditions you specify.

## What's next

- Learn how to [enable Object Versioning](https://docs.cloud.google.com/storage/docs/using-object-versioning.md.txt).
- [Work with noncurrent objects](https://docs.cloud.google.com/storage/docs/using-versioned-objects.md.txt).
- Learn about the [generation and metageneration](https://docs.cloud.google.com/storage/docs/metadata.md.txt#generation-number) object properties.
- Learn about [Object Lifecycle Management](https://docs.cloud.google.com/storage/docs/lifecycle.md.txt), which lets you automatically manage object versions.
- See an [Object Lifecycle Management example](https://docs.cloud.google.com/storage/docs/lifecycle-configurations.md.txt#deletion-example) that works with Object Versioning.