Tigris Global Object Storage

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.

fly storage create
? 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:

  • https://mybucket.t3.tigrisfiles.io/key-name (primary)
  • https://mybucket.t3.tigrisbucket.io/key-name
  • https://mybucket.t3.tigrisblob.io/key-name

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:

  • Click the Tigris Object Storage tab in the Fly Dashboard.
  • Run flyctl storage dashboard <bucket_name> from the command line to jump to a specific bucket, or flyctl storage dashboard --org <org_name> for the organization-level overview (billing, organization settings).

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

  • Sign in with Fly.io — choose Fly.io on the Tigris login page to manage buckets created through fly storage create. Tigris reads your Fly organization, so the buckets shown match flyctl storage list.
  • Sign in directly — Tigris also supports standalone accounts (Google, GitHub, or email). These are independent of any Fly account and only see buckets created under that Tigris account.

List your buckets

Get a list of all of your Tigris buckets.

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

Or with the Tigris CLI (see setup below):

tigris buckets list

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:

  • flyctl — for bucket lifecycle (create, list, destroy) and shadow buckets.
  • Tigris CLI — for day-to-day bucket and object management, plus Tigris-specific features like snapshots, forks, and shadow buckets.
  • S3-compatible SDKs — for application code in any language.

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:

  • Endpoint URL: https://t3.storage.dev
  • Region: auto
  • Access key ID: from AWS_ACCESS_KEY_ID
  • Secret access key: from AWS_SECRET_ACCESS_KEY

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 are point-in-time references to a bucket’s state. When snapshots are enabled, Tigris persists every write to the bucket, so the bucket’s full history is restorable — not just the moments you took a manual snapshot. tigris snapshots take simply names a point in time for easy reference.
  • Forks are copy-on-write clones of a bucket from a chosen snapshot. Writes to a fork don’t affect the source bucket, so they’re useful for testing migrations, branching production data, or running experiments on isolated copies.

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

  • Reads: Tigris checks its own bucket first. On a miss, it fetches the object from the shadow bucket, returns it to the caller, and asynchronously copies it into Tigris (in a region close to the user). Subsequent reads are served from Tigris with no shadow lookup.
  • Writes (default): Objects are written only to Tigris.
  • Writes (write-through enabled): Objects are written to both Tigris and the shadow bucket simultaneously, keeping both stores in sync.
  • Deletes: Removed from both Tigris and the shadow bucket.
  • Listing: With write-through enabled, ListObjects returns the full shadow bucket contents. Without write-through, only objects already migrated into Tigris are listed.

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:

  • Pre-signed URLs for secure download and upload
  • Setting HTTP headers on objects such as Cache-Control