rembrembdocs

Tigris is a globally distributed, multi-cloud object storage service with built-in support for the S3 API. Tigris is available natively as the object storage provider for Fly.io.

Objects in Tigris are stored close to the region where they’re written. Then, when requested, objects are replicated close to the requesting user. This durable cross-region replication is intelligently managed by Tigris based on global traffic patterns. This automatic global replication can replace a CDN and makes all your data available at low latency with zero configuration required.

Learn more from their service overview and architecture docs.

Use Tigris with your framework

Language- and framework-specific guides for setting up Tigris:

Create and manage a Tigris storage bucket

Provision Tigris storage buckets through the Fly CLI. Install it, then sign up for a Fly account. Once provisioned, you can also manage your buckets and objects with the Tigris CLI or any S3-compatible SDK — see Connect to your bucket below.

Running the following command in a Fly.io app context – inside an app directory or specifying -a yourapp – will automatically set secrets on your app.

? Select Organization: fly-ephemeral (fly-ephemeral)
? Choose a name, use the default, or leave blank to generate one:
Your project (summer-grass-2004) is ready.

Set one or more of the following secrets on your target app.
BUCKET_NAME: summer-grass-2004
AWS_ENDPOINT_URL_S3: https://fly.storage.tigris.dev
AWS_ACCESS_KEY_ID: tid_xxxxxx
AWS_SECRET_ACCESS_KEY: tsec_xxxxxx

Public buckets

By default, buckets are private. If you need to serve public assets like images or JavaScript files, create a public bucket:

fly storage create --public

You can also make a public bucket private.

fly storage update mybucket --private

Objects in a public bucket can be accessed by anyone without authentication. Public content is served from dedicated domains using the bucket name as a subdomain:

No credentials or pre-signed URLs are needed. For production use, we recommend setting up a custom domain so your public URLs stay stable:

flyctl storage update mybucket --custom-domain assets.example.com

Then create a CNAME record for assets.example.com pointing to mybucket.t3.tigrisbucket.io. See the Tigris Custom Domain docs for full setup instructions and the Tigris Public Bucket docs for details on all available public domains.

Object Level Access Control

By default, all objects inherit the access control settings of the bucket they are in. If a bucket is private, all objects in it are also private and vice versa. However, you can make individual objects in a bucket public-read (or private) by setting an object level ACL on them. This lets you serve a public object from an otherwise private bucket, or a private object from an otherwise public bucket. For details on how to set this up see the Tigris Object ACL docs

Access keys

fly storage create prints a Tigris access key ID and secret in its output (and sets them as AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY secrets on your Fly app, when run in an app context). Save them at that moment — flyctl can’t retrieve them later, and fly secrets list only shows hashes.

To view or create new keys for an existing bucket, open the Tigris web console with fly storage dashboard <bucket-name> and manage keys there. For Tigris CLI use, the Tigris CLI sidesteps raw keys via tigris login.

The Tigris web console

The Tigris web console at console.storage.dev is a visual interface for managing buckets, objects, access keys, and usage. From a Fly account, open it either way:

If you visit console.storage.dev directly, the Tigris sign-in page offers two paths:

List your buckets

Get a list of all of your Tigris buckets.

NAME                    ORG
js-storage-1            fly-ephemeral
late-surf-5384          fly-ephemeral

Or with the Tigris CLI (see setup below):

Delete a Tigris bucket

Deleting can’t be undone. Empty buckets can’t be deleted without the --force option.

fly storage destroy late-surf-5384
Destroying a Tigris bucket is not reversible.
? Destroy Tigris bucket late-surf-5384? Yes
Your Tigris bucket late-surf-5384 was destroyed

Or with the Tigris CLI:

tigris buckets delete late-surf-5384

Connect to your bucket

Buckets created with fly storage create are standard Tigris buckets. You can manage them three ways:

All three target the same bucket and accept the credentials that fly storage create set on your Fly app.

Endpoint

The canonical Tigris S3 endpoint is https://t3.storage.dev. We recommend using it for new code.

fly storage create currently sets the AWS_ENDPOINT_URL_S3 secret on your Fly app to https://fly.storage.tigris.dev. Both endpoints reach the same Tigris service and the same buckets, so existing code keeps working. To switch a Fly app to the canonical endpoint:

fly secrets set AWS_ENDPOINT_URL_S3=https://t3.storage.dev

To configure an SDK or tool manually:

Tigris CLI

The Tigris CLI (tigris, also available as t3) manages Tigris buckets and objects from the command line. It targets https://t3.storage.dev by default.

Install and sign in:

npm install -g @tigrisdata/cli
tigris login

When prompted, choose As a user (OAuth2 flow), then select Fly.io on the login page that opens in your browser. This connects the CLI to buckets created through your Fly account. Then run commands like:

tigris ls
tigris cp ./photo.jpg t3://my-bucket/photo.jpg
tigris presign t3://my-bucket/photo.jpg

Tigris SDKs

Tigris is S3-compatible, so any AWS SDK works — point it at https://t3.storage.dev. Tigris publishes language-specific guides for Python, Node.js, Go, Ruby, PHP, .NET, Java, and Elixir.

Snapshots and forks

Snapshots and forks are Tigris-only features that aren’t exposed through flyctl.

Snapshots must be enabled when the bucket is created — they cannot be turned on later, and forks require snapshots. Buckets created with fly storage create do not have snapshots enabled.

To use snapshots and forks on Fly-provisioned buckets, install the Tigris CLI and sign in with your Fly.io account:

npm install -g @tigrisdata/cli
tigris login

When prompted, choose As a user (OAuth2 flow), then select Fly.io on the login page that opens in your browser. The CLI then manages every Tigris bucket on your Fly account — tigris buckets list should show the same buckets as flyctl storage list.

Snapshots can’t be enabled on existing buckets, so create a new bucket with the --enable-snapshots flag, then migrate or write data into it:

tigris buckets create my-bucket --enable-snapshots
tigris snapshots take my-bucket
tigris forks create my-bucket my-fork

You can also create snapshot-enabled buckets from a Tigris SDK or the Tigris web console.

Migrate from another S3-compatible provider with zero downtime

Tigris supports zero-downtime, lazy migration from any S3-compatible storage provider — AWS S3, Cloudflare R2, Google Cloud Storage, MinIO, Backblaze B2, and others. Instead of copying everything up front, Tigris fetches objects from your old bucket as your application requests them and asynchronously stores copies in Tigris for future reads. Only data that’s actually used moves over, so migration latency and egress costs stay low.

The migration setup uses a shadow bucket: your existing source bucket, attached to a Tigris bucket through flyctl. Once attached, your application points at Tigris, and Tigris transparently fills in objects from the shadow bucket as needed. See the Tigris migration guide for provider-specific setup.

How shadow bucket migration works

Write-through mode: zero-downtime cutover

Write-through mode (the --shadow-write-through flag below) is what makes the migration zero-downtime and reversible. Because every new write also lands in your old bucket, your previous provider stays fully current while you run on Tigris in production. You can soak in this dual-write state for days, weeks, or months, validate behavior, and roll back to your old provider at any time without data loss. When you’re ready, disable write-through and decommission the old bucket.

Create a new bucket with a shadow bucket

You must specify all shadow bucket attributes, including the endpoint and region. Check your provider docs to find these values. Here’s the AWS S3 list of regions and endpoints.

flyctl storage create -n mybucket -o myorg --shadow-access-key 123 --shadow-secret-key abc --shadow-endpoint https://s3.us-east-1.amazonaws.com --shadow-region us-east-1 --shadow-write-through

Add or remove a shadow bucket on an existing Tigris bucket

You can also add and remove shadow buckets from existing Tigris buckets.

flyctl storage update mybucket --shadow-access-key 123 --shadow-secret-key abc --shadow-endpoint https://s3.us-east-1.amazonaws.com --shadow-region us-east-1

flyctl storage update mybucket --clear-shadow

--shadow-write-through enables zero-downtime cutover by replicating every new write back to the source bucket.

Pricing and Billing

Tigris buckets created through your Fly account are billed through Fly. Tigris usage appears on your regular Fly bill — there’s no separate Tigris invoice or account to manage. This applies whether you create buckets with fly storage create, the Tigris CLI, or a Tigris SDK using the credentials Fly provisioned for you.

Buckets are billed by usage with no up-front costs. Check the official Tigris Pricing page for rates.

AWS API compatibility

Check out the Tigris docs on compatibility: https://www.tigrisdata.com/docs/api/s3

Tigris also supports the following: