Mastodon instances generate large amounts of media files from user uploads and cached remote content. Storing these files on the same server as your database and application code quickly fills disk space and can degrade performance. Moving media storage to Backblaze B2 reduces server disk usage and lowers hosting costs. This article explains how to configure your Mastodon instance to use Backblaze B2 as the primary media storage backend.
Key Takeaways: Migrating Mastodon Media to Backblaze B2
- .env.production configuration: Setting S3-compatible environment variables redirects Mastodon’s Active Storage to Backblaze B2.
- rails assets:precompile and db:migrate: Required commands after changing storage provider to apply the new configuration.
- Existing media migration: Use
tootctl mediacommands to copy existing local files to the B2 bucket and remove local copies.
Understanding Mastodon Media Storage and Backblaze B2
Mastodon uses Ruby on Rails Active Storage to manage file attachments. By default, Active Storage saves files to the local filesystem under public/system. This location includes user-uploaded images and videos, custom emoji, and cached media from federated instances. On a busy instance, this directory can exceed tens of gigabytes within weeks.
Backblaze B2 is an object storage service that is S3-compatible. Mastodon’s Active Storage can be configured to use any S3-compatible provider by setting environment variables. The migration involves changing these variables, running Rails commands to update the application, and copying existing files to the B2 bucket. No code changes are required. The entire process takes about 30 minutes for a small instance.
Prerequisites for this guide:
- Root or sudo access to the Mastodon server
- A Backblaze B2 account with an application key that has write and read permissions
- A B2 bucket created with default settings (public or private; Mastodon will handle access)
- Mastodon v3.5 or later (older versions require additional gems)
Steps to Configure Mastodon for Backblaze B2 Storage
- Create a Backblaze B2 bucket and application key
Log into your Backblaze account. Navigate to B2 Cloud Storage and click Create a Bucket. Name the bucket something likemastodon-media. Set the bucket type to Private. After creation, go to App Keys and click Generate New Application Key. Select the bucket you just created. Allow read and write access. Copy the Key ID and Application Key values. Keep these secure. - Stop the Mastodon web and sidekiq processes
On your server, stop the services to prevent file writes during the configuration change. Run:sudo systemctl stop mastodon-webandsudo systemctl stop mastodon-sidekiq. Also stop the streaming API service if you use it:sudo systemctl stop mastodon-streaming. - Edit the Mastodon .env.production file
Open/home/mastodon/live/.env.productionwith a text editor. Locate the section for S3 storage. If it does not exist, add the following lines. Replace placeholders with your actual values:S3_ENABLED=true S3_BUCKET=mastodon-media S3_REGION=us-west-001 AWS_ACCESS_KEY_ID=your_backblaze_key_id AWS_SECRET_ACCESS_KEY=your_backblaze_application_key S3_ENDPOINT=https://s3.us-west-001.backblazeb2.com S3_PROTOCOL=https S3_HOSTNAME=s3.us-west-001.backblazeb2.com S3_ALIAS_HOST=https://your-bucket-name.s3.us-west-001.backblazeb2.com
The
S3_REGIONandS3_ENDPOINTvalues depend on your B2 bucket region. Find the correct endpoint in the Backblaze B2 dashboard under the bucket details. Do not use quotes around the values. - Run Rails asset precompilation and database migration
Switch to the mastodon user:sudo -i -u mastodon. Navigate to the live directory:cd /home/mastodon/live. Run:RAILS_ENV=production bundle exec rails assets:precompile. This command generates new asset files that include the S3 configuration. Then run:RAILS_ENV=production bundle exec rails db:migrate. This updates the database schema if needed. - Restart Mastodon services
Exit the mastodon user shell. Run:sudo systemctl start mastodon-web,sudo systemctl start mastodon-sidekiq, andsudo systemctl start mastodon-streaming. Check the service status:sudo systemctl status mastodon-web. Ensure all services are active and running. - Copy existing media files to Backblaze B2
Mastodon provides thetootctltool for media management. Run the following command to upload all local media to B2:RAILS_ENV=production bin/tootctl media remove --days=0. This command removes local media that is older than 0 days (i.e., all media) but only after ensuring the files exist in the remote storage. Wait for the command to finish. Then run:RAILS_ENV=production bin/tootctl media usageto verify that the media count and size match the remote bucket. - Remove the local media directory
After confirming all files are in B2, delete the local media directory to free disk space. Run:sudo rm -rf /home/mastodon/live/public/system. This action cannot be undone. Only perform this step after verifying your B2 bucket contains all files.
Common Issues When Moving Mastodon Media to Backblaze B2
Media uploads fail after switching to B2
This usually indicates incorrect S3_ENDPOINT or S3_HOSTNAME values. Verify that the endpoint matches the Backblaze B2 region exactly. Also confirm that the application key has write permissions. Check the Mastodon logs at /home/mastodon/live/log/production.log for S3-related error messages.
Existing media files not accessible after migration
The tootctl media remove command only removes files that are already stored remotely. If you deleted local files before uploading them to B2, the media will be missing. To recover, you must restore the local files from a backup and rerun the migration steps in the correct order. Always verify B2 bucket contents before deleting local files.
New media saves locally instead of to B2
The S3_ENABLED variable must be set to true exactly. Trailing spaces or incorrect capitalization will cause Mastodon to ignore the S3 configuration. After editing the .env file, restart all Mastodon services and test by uploading a new post with an image. Check the production log to confirm the file path points to the B2 endpoint.
Mastodon Local Storage vs Backblaze B2
| Item | Local Storage | Backblaze B2 |
|---|---|---|
| Storage location | Server filesystem | Remote object storage |
| Cost | Server disk cost (included in VPS) | Pay per GB stored and downloaded |
| Scalability | Limited by disk size | Virtually unlimited |
| Backup requirement | Must back up media separately | B2 includes 99.999999999% durability |
| Server load | File operations consume CPU and I/O | Offloads file serving to CDN edge |
After moving media to Backblaze B2, your Mastodon instance will store all user-uploaded and cached media remotely. The server disk usage will drop significantly, reducing backup size and extending the life of your SSD. Monitor the B2 bucket usage from the Backblaze dashboard to track costs. For large instances, consider enabling the S3_ALIAS_HOST with a custom subdomain to improve load times through a CDN.