Mastodon Instance Tuning¶
Running your own Mastodon instance means you control the rules — including limits the upstream project imposes by default. These are the tweaks applied to majortoot (MajorsHouse's Mastodon instance).
Increase Character Limit¶
Mastodon's default 500-character post limit is low for longer-form thoughts. You can raise it, but it requires modifying the source — there's no config toggle.
The process depends on your deployment method (Docker vs bare metal) and Mastodon version. The community-maintained guide covers the approaches:
Key points: - The limit is enforced in both the backend (Ruby) and frontend (React). Both must be changed or the UI will reject posts the API would accept. - After changing, you need to rebuild assets and restart services. - Other instances will still display the full post — the character limit is per-instance, not a federation constraint. - Some Mastodon forks (Glitch, Hometown) expose this as a config option without source patches.
Media Cache Management¶
Federated content (avatars, headers, media from remote posts, preview cards) gets cached in S3. On an active single-user instance federating with large servers, this grows fast — the majortoot bucket hit 648 GB with only ~7 GB of actual local content. The other ~620 GB was remote cache.
Check current usage¶
# Bare metal (rbenv)
export PATH="$HOME/.rbenv/bin:$HOME/.rbenv/shims:$PATH"
cd /home/mastodon/live
RAILS_ENV=production bin/tootctl media usage
Output breaks down by type with local vs total — the gap between those two numbers is all purgeable remote cache.
Manual prune¶
Run these three commands to clear all remote cache types:
export PATH="$HOME/.rbenv/bin:$HOME/.rbenv/shims:$PATH"
export RAILS_ENV=production
cd /home/mastodon/live
# 1. Remote media attachments older than 7 days
bin/tootctl media remove --days=7 --concurrency=5
# 2. Remote avatars and headers (accounts not followed/following locally)
bin/tootctl media remove --prune-profiles --remove-headers --days=7 --concurrency=5
# 3. Preview card thumbnails older than 30 days
bin/tootctl preview_cards remove --days=30 --concurrency=5
Note: On a large cache (hundreds of GB, millions of objects), each command can take 30–60+ minutes. Run in
tmuxto survive SSH disconnection.
Automate with weekly cron¶
Deploy via configure_mastodon_media_prune.yml Ansible playbook. It installs a wrapper script and cron entry for the mastodon user.
Manual crontab entry:
Log output goes to /var/log/mastodon/media-prune.log.
Reduce S3 storage class costs¶
By default Mastodon uploads to S3 Standard ($0.023/GB/mo). Switching to Standard-IA halves the storage cost for infrequently accessed media:
Then restart Mastodon. New uploads will use Standard-IA ($0.0125/GB). Note the 30-day minimum charge per object — fine for media attachments, less ideal for very short-lived objects.
What is and isn't removed¶
- ✅ Removed: Cached copies of remote users' media, avatars, headers, preview card thumbnails
- ✅ Re-fetched on demand: Remote media is pulled again if someone views the post
- ❌ Never removed: Your local posts' media, your account's avatar/header, Mastodon account export backups (
/backups/) - ❌ Not affected: PostgreSQL database, local disk usage outside S3
Gotchas & Notes¶
- Character limit changes break on upgrades. Any source patch gets overwritten when you pull a new Mastodon release. Track your changes and reapply after updates.
tootctlis your admin CLI. It handles media cleanup, user management, federation diagnostics, and more. Runtootctl --helpfor the full list.- Monitor disk usage. Even with cache cleanup, the PostgreSQL database and local media uploads grow over time. Keep an eye on it.