Skip to main content
Pixeltable supports storing media files (images, videos, audio, documents) in external cloud storage providers instead of local disk. This is essential for production deployments, enabling scalable storage, team collaboration, and integration with existing data infrastructure.

Supported providers

Pixeltable Cloud

Managed storage, no bucket setup required

Amazon S3

Native S3 storage with full feature support

Google Cloud Storage

GCS buckets with gs:// URI scheme

Azure Blob Storage

Azure containers with wasb:// or abfs:// schemes

Cloudflare R2

S3-compatible storage with zero egress fees

Backblaze B2

Cost-effective S3-compatible storage

Tigris

Globally distributed S3-compatible storage

How it works

When you configure a storage destination, Pixeltable automatically:
  1. Uploads computed media: AI-generated images, extracted video frames, and other computed media files are stored in your bucket
  2. Copies input media: Optionally persists referenced media files for durability
  3. Manages file lifecycle: Cleans up files when table data is deleted
  4. Handles caching: Downloads files on-demand with intelligent local caching

Which destination do you need?

Do not put PIXELTABLE_API_KEY in config.toml as api_key. Use the env name. Hosted pods get their own worker key from the platform; you do not set it.

Configuration

There are two ways to configure cloud storage destinations. These apply to local Pixeltable and to bring-your-own buckets. Hosted Cloud tables skip this section.

Global default destinations

Set default destinations for all media columns with environment variables (see Configuration):
Or the same dest keys in ~/.pixeltable/config.toml (not the API key):
Configure these before creating tables. All media columns will automatically use the configured destinations.

Per-column destination (computed columns only)

For computed columns, you can override the default with a specific destination:
Then pxt schema update app.py my_app. In a notebook or a test, the same column is t.add_computed_column(thumbnail=t.image.resize((128, 128)), destination=...).
The destination parameter only applies to stored computed columns. For input columns, use the global input_media_dest configuration.

Precedence rules

Destinations are resolved in this order:
  1. Explicit column destination: highest priority (computed columns only)
  2. Global default: PIXELTABLE_INPUT_MEDIA_DEST / PIXELTABLE_OUTPUT_MEDIA_DEST (or the matching config.toml dest keys)
  3. Hosted Cloud process: pxtfs://org:db/home when the database is running in Cloud
  4. Local process: local disk

Provider configuration

Pixeltable Cloud (home bucket)

A Pixeltable Cloud database comes with a managed Media Store at pxtfs://org:db/home. Hosted tables and services write there automatically. No destination, no provider account, no credentials file. Cloud is in Limited Beta: email [email protected] to get an account. Use dest + PIXELTABLE_API_KEY only when a local Pixeltable process should write into that same bucket:
Create the key under API Keys in the dashboard and export it. Pixeltable reads the process environment only, so a .env file has to be sourced first. Provider keys (AWS_ACCESS_KEY_ID, OPENAI_API_KEY, …) go under Secrets or pxt secret set.
Replace org-slug and db-slug with your Pixeltable Cloud organization and database names.
On Cloud, open Storage in the database sidebar and browse home. Nothing to configure for hosted tables.

Amazon S3

Google Cloud Storage

Azure Blob Storage

Azure supports multiple URI schemes:

Cloudflare R2

Backblaze B2

Tigris

Complete example

Here’s a full example using S3 for both input and computed media. First, configure your global destinations in ~/.pixeltable/config.toml:
Then declare the columns in your application file:
pxt schema update app.py production creates the table. Insert and Pixeltable handles the uploads:

Best practices

Structure your bucket with prefixes that reflect your application:
Use different prefixes or buckets for input vs computed media:
  • Easier to set different retention policies
  • Clearer cost attribution
  • Simpler backup strategies
Set up bucket lifecycle policies to automatically:
  • Transition old data to cheaper storage tiers
  • Delete temporary/staging data after a period
  • Enable versioning for critical data
When running on cloud infrastructure, use IAM roles instead of access keys:
  • More secure (no key rotation needed)
  • Automatic credential refresh
  • Better audit trails

Troubleshooting

Verify your credentials have the necessary permissions:
  • s3:GetObject, s3:PutObject, s3:DeleteObject
  • s3:ListBucket for the bucket
For GCS: storage.objects.create, storage.objects.get, storage.objects.delete
  • Ensure the bucket exists and the name is spelled correctly
  • Check the region matches your credential configuration
  • For S3-compatible providers, verify the endpoint URL is correct
  • Pixeltable uses connection pooling and parallel uploads automatically
  • Consider using a bucket in the same region as your compute
  • Check your network bandwidth and latency

Configuration Reference

See the complete list of storage configuration options including profiles for S3, R2, B2, Tigris, and Azure.
Last modified on September 16, 2026