Bucket snapshots and forks | Tigris Object Storage Documentation

Enabling snapshots and forks

To enable snapshots and forks at creation, set the X-Tigris-Enable-Snapshot: true header when creating the bucket.

You can also switch an existing bucket between Regular and Snapshot under Bucket Settings → Storage Settings in the Tigris Dashboard.

Note: To convert a Regular bucket to Snapshot, it must not use the GLACIER storage tier, lifecycle rules, or object expiration (TTL) rules.

Example using the Go SDK github.com/aws/aws-sdk-go-v2/service/s3:

func createBucketWithSnapshotEnabled(ctx context.Context, client *s3.Client, bucketName string) error {

_, err := client.CreateBucket(ctx, &s3.CreateBucketInput{Bucket: aws.String(bucketName)}, func(options *s3.Options) {

options.APIOptions = append(options.APIOptions, http.AddHeaderValue("X-Tigris-Enable-Snapshot", "true"))

})

return err
}

Example using the Tigris SDK for JavaScript:

import { createBucket } from "@tigrisdata/storage";

const result = await createBucket("bucket-with-snapshots", {

enableSnapshot: true,

});

if (result.error) {

console.error("error creating bucket with snapshots enabled", result.error);
} else {

console.log("bucket created with snapshots enabled");
}

Example using the Python SDK boto3:

pip install tigris-boto3-ext
import boto3

from tigris_boto3_ext import (

TigrisSnapshotEnabled,

create_snapshot_bucket,

)

# Initialize boto3 S3 client

s3_client = boto3.client(

's3',

endpoint_url='https://t3.storage.dev',  # Tigris endpoint

aws_access_key_id='your-access-key',

aws_secret_access_key='your-secret-key',

)

# Create snapshot enabled bucket using context manager pattern

with TigrisSnapshotEnabled(s3_client):
    s3_client.create_bucket(Bucket='my-snapshot-bucket')

# Or, create snapshot enabled bucket using helper function

create_snapshot_bucket(s3_client, 'my-snapshot-bucket')

Creating a snapshot

Snapshots are created with the same CreateBucket API call, with an additional header: X-Tigris-Snapshot: true.

Snapshot name can optionally be specified as part of that header (with semicolon separator), e.g., X-Tigris-Snapshot: true; name=test snapshot name.

The version of the snapshot created is returned in the X-Tigris-Snapshot-Version header of the response.

Example using the Go SDK github.com/aws/aws-sdk-go-v2/service/s3:

func createBucketSnapshot(ctx context.Context, client *s3.Client, bucketName string, snapshotName string) (string, error) {

resp, err := client.CreateBucket(ctx, &s3.CreateBucketInput{Bucket: aws.String(bucketName)}, func(options *s3.Options) {

options.APIOptions = append(options.APIOptions, http.AddHeaderValue("X-Tigris-Snapshot", fmt.Sprintf("true; name=%s", snapshotName)))

})

if err != nil {

return "", err

}

rawResp := middleware.GetRawResponse(resp.ResultMetadata).(*http.Response)

return rawResp.Header.Get("X-Tigris-Snapshot-Version"), nil
}

Example using the Tigris SDK for JavaScript:

import { createBucketSnapshot } from "@tigrisdata/storage";

const result = await createBucketSnapshot("bucket-with-snapshots", {

name: "test snapshot", // optional name for the snapshot

});

if (result.error) {

console.error("error creating bucket snapshot", result.error);
} else {

console.log("bucket snapshot created");
}

Example using the Python SDK boto3:

pip install tigris-boto3-ext
import boto3

from tigris_boto3_ext import (

create_snapshot_bucket,

create_snapshot,

get_snapshot_version,

)

# Initialize boto3 S3 client

s3_client = boto3.client(

's3',

endpoint_url='https://t3.storage.dev',  # Tigris endpoint

aws_access_key_id='your-access-key',

aws_secret_access_key='your-secret-key',

)

# Create snapshot-enabled bucket

create_snapshot_bucket(s3_client, 'bucket-with-snapshots')

# Create snapshots

result = create_snapshot(s3_client, 'bucket-with-snapshots', snapshot_name='test-snapshot')

version = get_snapshot_version(result)

Listing snapshots

Snapshots are listed with the same ListBuckets API call, with an additional header: X-Tigris-Snapshot: <BUCKET_NAME>.

To list snapshots for a bucket, make a list buckets request and set the X-Tigris-Snapshot header to the bucket name, e.g., X-Tigris-Snapshot: test-bucket.

Example using the Go SDK github.com/aws/aws-sdk-go-v2/service/s3:

func listSnapshotsForBucket(ctx context.Context, client *s3.Client, bucketName string) (*s3.ListBucketsOutput, error) {

return client.ListBuckets(ctx, &s3.ListBucketsInput{}, func(options *s3.Options) {

options.APIOptions = append(options.APIOptions, http.AddHeaderValue("X-Tigris-Snapshot", bucketName))

})
}

Example using the Tigris SDK for JavaScript:

import { listBucketSnapshots } from "@tigrisdata/storage";

const listSnapshots = await listBucketSnapshots("bucket-with-snapshots"); // bucket name

if (listSnapshots.error) {

console.error("error listing snapshots", listSnapshots.error);
} else {

console.log("snapshots:", listSnapshots.data);
}

Example using the Python SDK boto3:

pip install tigris-boto3-ext
import boto3

from tigris_boto3_ext import (

TigrisSnapshot,

create_snapshot_bucket,

list_snapshots,

)

# Initialize boto3 S3 client

s3_client = boto3.client(

's3',

endpoint_url='https://t3.storage.dev',  # Tigris endpoint

aws_access_key_id='your-access-key',

aws_secret_access_key='your-secret-key',

)

# Create snapshot-enabled bucket

create_snapshot_bucket(s3_client, 'bucket-with-snapshots')

# List snapshots for a bucket using context manager pattern

with TigrisSnapshot(s3_client, 'bucket-with-snapshots'):
    snapshots = s3_client.list_buckets()

# Or, list snapshots via the helper function

snapshots = list_snapshots(s3_client, 'bucket-with-snapshots')

Example list snapshots response

The response will contain the list of snapshots for the bucket including the name and creation date of the snapshot. The response format is S3-compatible.

<ListAllMyBucketsResult>

<Buckets>

<Bucket>

<Name>1751631910196672425; name=my first snapshot</Name>

<CreationDate>2025-07-04T12:25:10.19667705Z</CreationDate>

</Bucket>

<Bucket>

<Name>1751631910169675092</Name>

<CreationDate>2025-07-04T12:25:10.16968055Z</CreationDate>

</Bucket>

<Bucket>

<Name>1751631910140685342; name=another snapshot</Name>

<CreationDate>2025-07-04T12:25:10.141025675Z</CreationDate>

</Bucket>

</Buckets>

<ContinuationToken>1751631910140685342</ContinuationToken>

</ListAllMyBucketsResult>

Creating a forked bucket

Forks are also created via the CreateBucket API, specifying a source bucket (and optionally a snapshot).

To create a bucket which is a fork of another bucket, specify the X-Tigris-Fork-Source-Bucket: <BUCKET_NAME> header where <BUCKET_NAME> is the name of the bucket you want to use as the fork source.

Add the X-Tigris-Fork-Source-Bucket-Snapshot: <SNAPSHOT_VERSION> header (e.g. X-Tigris-Fork-Source-Bucket-Snapshot: 1751631910140685342) if you want to use a specific snapshot of the source bucket for the fork. If this header is not set, then a new snapshot of the source bucket will be created at the current time and used for creating the fork bucket.

Example using the Go SDK github.com/aws/aws-sdk-go-v2/service/s3:

func createBucketFork(ctx context.Context, client *s3.Client, bucketName string) error {

_, err := client.CreateBucket(ctx, &s3.CreateBucketInput{Bucket: aws.String(bucketName)}, func(options *s3.Options) {

options.APIOptions = append(options.APIOptions, http.AddHeaderValue("X-Tigris-Fork-Source-Bucket", "source-bucket"))

})

return err
}

Example using the Tigris SDK for JavaScript:

import { createBucket } from "@tigrisdata/storage";

const result = await createBucket("forked-bucket", {

sourceBucketName: "source-bucket", // source bucket name

sourceBucketSnapshot: "snapshot_version", // optional snapshot version e.g. 1759343574493973169

});

if (result.error) {

console.error("error creating bucket fork", result.error);
} else {

console.log("bucket fork created");
}

Example using the Python SDK boto3:

pip install tigris-boto3-ext
import boto3

from tigris_boto3_ext import (

TigrisFork,

create_fork

)

# Initialize boto3 S3 client

s3_client = boto3.client(

's3',

endpoint_url='https://t3.storage.dev',  # Tigris endpoint

aws_access_key_id='your-access-key',

aws_secret_access_key='your-secret-key',

)

# Fork from current state

with TigrisFork(s3_client, 'source-bucket'):
    s3_client.create_bucket(Bucket='forked-bucket')

# Fork from specific snapshot

with TigrisFork(s3_client, 'source-bucket', snapshot_version='1759343574493973169'):
    s3_client.create_bucket(Bucket='forked-from-snapshot')

# Or, use a helper function to create forks

create_fork(s3_client, 'new-bucket', 'source-bucket', snapshot_version='1759343574493973169')

Retrieving snapshot and fork info for a bucket

Information related to snapshots and forks for an existing bucket can be retrieved by making a HeadBucket request. The response of the request will include custom Tigris headers with the details:

Note: These are not standard AWS S3 headers, and in order to retrieve them, the raw HTTP response will need to be used. Here is an example for checking whether snapshot is enabled for a bucket:

Example using the Go SDK github.com/aws/aws-sdk-go-v2/service/s3:

func hasSnapshotEnabled(ctx context.Context, client *s3.Client, bucketName string) (bool, error) {

resp, err := client.HeadBucket(ctx, &s3.HeadBucketInput{Bucket: aws.String(bucketName)})

if err != nil {

return false, err
    }

rawResp := middleware.GetRawResponse(resp.ResultMetadata).(*http.Response)

return rawResp.Header.Get("X-Tigris-Enable-Snapshot") == "true", nil
}

Example using the AWS SDK for JavaScript v3:

import { S3Client, HeadBucketCommand } from "@aws-sdk/client-s3";

async function hasSnapshotEnabled(s3Client, bucketName) {

const response = await s3Client.send(

new HeadBucketCommand({ Bucket: bucketName }),

);

const headers = response.$metadata?.httpHeaders || {};

return headers["X-Tigris-Enable-Snapshot"] === "true";
}

Example using the Python SDK boto3:

pip install tigris-boto3-ext
import boto3

from tigris_boto3_ext import (

create_snapshot_bucket,

create_snapshot,

create_fork,

get_snapshot_version,

has_snapshot_enabled,

get_bucket_info,

)

# Initialize boto3 S3 client

s3_client = boto3.client(

's3',

endpoint_url='https://t3.storage.dev',  # Tigris endpoint

aws_access_key_id='your-access-key',

aws_secret_access_key='your-secret-key',

)

# Check if a bucket has snapshots enabled

bucket_name = 'my-bucket'

create_snapshot_bucket(s3_client, bucket_name)

if has_snapshot_enabled(s3_client, bucket_name):

print(f"✓ Snapshots are enabled for {bucket_name}")
else:

print(f"✗ Snapshots are not enabled for {bucket_name}")

# Example: Check fork lineage

source_bucket = 'production-data'

create_snapshot_bucket(s3_client, source_bucket)

# Create a snapshot

snapshot_result = create_snapshot(s3_client, source_bucket, snapshot_name='v1')

snapshot_version = get_snapshot_version(snapshot_result)

# Create a fork

forked_bucket = 'test-data'

create_fork(s3_client, forked_bucket, source_bucket, snapshot_version=snapshot_version)

# Inspect the fork

fork_info = get_bucket_info(s3_client, forked_bucket)

print(f"Forked from: {fork_info['fork_source_bucket']}")

print(f"Snapshot version: {fork_info['fork_source_snapshot']}")

Retrieving objects in a snapshot

Existing APIs can be used to retrieve objects in a snapshot when an additional header is set:

Note: Additional header: X-Tigris-Snapshot-Version: SNAPSHOT_VERSION needs to be set when making these requests to retrieve objects from a specific snapshot.

Note: Any UNIX nanosecond-precision timestamp (e.g., 1765889000501544464) can be used as a snapshot parameter value for ListObjectsV2, GetObject, HeadObject and CopyObject API calls, even if there is no snapshot created at that particular time.

Example using the Go SDK github.com/aws/aws-sdk-go-v2/service/s3:

func getObjectFromSnapshot(ctx context.Context, client *s3.Client, bucket string, object string, snapshotVersion string) (*s3.GetObjectOutput, error) {

return client.GetObject(ctx, &s3.GetObjectInput{Bucket: aws.String(bucket), Key: aws.String(object)}, func(options *s3.Options) {

options.APIOptions = append(options.APIOptions, http.AddHeaderValue("X-Tigris-Snapshot-Version", snapshotVersion))

})
}

Example using the AWS SDK for JavaScript v3:

import { S3Client, GetObjectCommand } from "@aws-sdk/client-s3";

async function getObjectFromSnapshot(client, bucket, key, snapshotVersion) {

return client.send(

new GetObjectCommand({

Bucket: bucket,

Key: key,

$httpOptions: {

headers: { "X-Tigris-Snapshot-Version": snapshotVersion },

},

}),

);
}

Example using the Python SDK boto3:

pip install tigris-boto3-ext
import boto3

from tigris_boto3_ext import (

TigrisSnapshot,

create_snapshot_bucket,

create_snapshot,

get_object_from_snapshot,

get_snapshot_version,

head_object_from_snapshot,

list_objects_from_snapshot,
)

# Initialize boto3 S3 client

s3_client = boto3.client(

's3',

endpoint_url='https://t3.storage.dev',  # Tigris endpoint

aws_access_key_id='your-access-key',

aws_secret_access_key='your-secret-key',

)

# First, ensure bucket has snapshots enabled

create_snapshot_bucket(s3_client, 'my-bucket')

s3_client.put_object(Bucket='my-bucket', Key='file.txt', Body=b'data')

response = create_snapshot(

s3_client,

'my-bucket',

snapshot_name='daily-backup-2024-01-01'
)

snapshot_version = get_snapshot_version(response)

print(f"Snapshot version: {snapshot_version}")

# Read objects from a specific snapshot using context manager pattern

with TigrisSnapshot(s3_client, 'my-bucket', snapshot_version=snapshot_version):
    obj = s3_client.get_object(Bucket='my-bucket', Key='file.txt')
    objects = s3_client.list_objects_v2(Bucket='my-bucket')

# Or, use a helper function to access snapshot data

obj = get_object_from_snapshot(s3_client, 'my-bucket', 'file.txt', snapshot_version)

objects = list_objects_from_snapshot(s3_client, 'my-bucket', snapshot_version)

metadata = head_object_from_snapshot(s3_client, 'my-bucket', 'file.txt', snapshot_version)

Note: Check out the examples in the tigris-boto3-ext repo for more details on how to use the snapshot and forking feature with the Python boto3 SDK.

Using object versioning APIs

Working with a snapshot-enabled bucket sometimes requires reading or deleting a specific version of an object - for example, fetching a known prior version directly, or permanently removing a single version across the bucket and its snapshots. A subset of S3-compatible object versioning APIs supports these cases without any additional changes. No special headers or extra steps are required, and standard SDKs and tools work as-is.

Supported APIs

Note: As in S3, deleting an object with a specified version ID permanently removes that version. It is also deleted from all snapshots.

Note: No additional authorization permissions are required to use the HeadObject or GetObject APIs with the versionId parameter. The ListObjectVersions operation is available to users with read-only (or higher) access to the bucket.

Using a forked bucket

Forked buckets behave the same as regular buckets, and you can use the usual tooling (AWS CLI or SDK) to work with them.

The only restriction is that the source bucket cannot be deleted while forked buckets depend on it.

Authorization

Snapshot and fork operations on existing buckets are limited to users who are bucket owners, organization admins, or have ReadOnly (or Editor) access to the buckets. This includes all operations mentioned above, such as creating a snapshot, creating a fork from a specific source bucket, or listing objects in a snapshot.