Mastodon aufräumen

Medienspeicher in Backblaze B2 reduzieren

Wer Mastodon selbst hostet und Mediendateien in einem S3-kompatiblen Object Storage wie Backblaze B2 ablegt, erlebt früher oder später eine unangenehme Überraschung: Die tatsächlich in B2 gespeicherte Datenmenge übersteigt das, was Mastodon unter „gecachte Medien” ausweist, um ein Vielfaches. Nach einigen Monaten Betrieb können das leicht 50 bis 100 GB oder mehr sein.

Warum entsteht die Diskrepanz?

Mastodon cached Medieninhalte fremder Instanzen lokal bzw. in B2: Profilbilder, Header-Grafiken, angehängte Bilder und Videos aus dem Fediverse. Dabei verliert Mastodon im Laufe der Zeit die Datenbankreferenz auf einen Teil dieser Dateien – die Objekte bleiben in B2 liegen, Mastodon „kennt” sie aber nicht mehr. Diese verwaisten Dateien (Orphaned Files) werden weder von tootctl noch von Backblaze-Lifecycle-Rules automatisch entfernt, weil B2 nicht weiß, welche Dateien noch referenziert sind.

Hinzu kommt: Backblaze Lifecycle-Rules funktionieren bei Mastodon-Mediendaten nicht zuverlässig als Aufräummechanismus, weil Mastodon die Dateipfade in der Datenbank verwaltet. Löscht B2 eine Datei per Rule, bleibt der tote Link in der Datenbank – das führt zu broken Images in der Timeline. Mastodon muss daher immer selbst das Löschen initiieren.


Schritt 1: Ist-Zustand ermitteln

Zunächst den tatsächlichen Speicherverbrauch aus Mastodon-Sicht abfragen:

sudo -u mastodon bash -c "export PATH=/home/mastodon/.rbenv/shims:/home/mastodon/.rbenv/bin:\$PATH && cd /home/mastodon/live && RAILS_ENV=production bin/tootctl media usage"

Die Ausgabe zeigt Attachments, Avatare, Header, Custom Emoji und Preview Cards getrennt nach Remote (B2) und Local.

Den tatsächlichen B2-Verbrauch siehst du am schnellsten in der Backblaze-Webkonsole unter Buckets → dein-bucket → Bucket-Größe wird direkt angezeigt.

Die Differenz beider Werte sind die orphaned files.


Schritt 2: Remote-Mediencache aufräumen

Der erste und harmloseste Schritt löscht gecachte Medien von anderen Instanzen, die älter als 30 Tage sind. Mastodon lädt sie bei Bedarf neu:

sudo -u mastodon bash -c "export PATH=/home/mastodon/.rbenv/shims:/home/mastodon/.rbenv/bin:\$PATH && cd /home/mastodon/live && RAILS_ENV=production bin/tootctl media remove --days=30"

Eigene Uploads der eigenen User werden dabei nicht angefasst.


Schritt 3: Profilmedien inaktiver Accounts entfernen

Avatare und Header-Grafiken von Fediverse-Accounts, die seit mehr als 30 Tagen nicht aktiv waren, können ebenfalls gelöscht werden. Vorher immer einen Dry-Run machen:

sudo -u mastodon bash -c "export PATH=/home/mastodon/.rbenv/shims:/home/mastodon/.rbenv/bin:\$PATH && cd /home/mastodon/live && RAILS_ENV=production bin/tootctl media remove --prune-profiles --days=30 --dry-run"

Die Ausgabe zeigt wie viele Accounts betroffen sind und wie viel Speicher freigegeben würde. Wenn das Ergebnis plausibel ist, ohne --dry-run ausführen:

sudo -u mastodon bash -c "export PATH=/home/mastodon/.rbenv/shims:/home/mastodon/.rbenv/bin:\$PATH && cd /home/mastodon/live && RAILS_ENV=production bin/tootctl media remove --prune-profiles --days=30"

Bei einer großen Instanz mit hunderttausenden bekannten Fediverse-Accounts kann dieser Schritt eine Stunde oder länger dauern und mehrere Dutzend Gigabyte freisetzen.


Schritt 4: Preview Cards aufräumen

Mastodon generiert Vorschaukarten für verlinkte Webseiten. Auch diese sammeln sich an:

sudo -u mastodon bash -c "export PATH=/home/mastodon/.rbenv/shims:/home/mastodon/.rbenv/bin:\$PATH && cd /home/mastodon/live && RAILS_ENV=production bin/tootctl preview_cards remove --days=30"

Schritt 5: Automatisierung per Cronjob

Damit der Speicher nicht wieder unkontrolliert wächst, alle Bereinigungsschritte als wöchentlichen Cronjob einrichten. Als root:

sudo crontab -e

Folgende Zeile einfügen (sonntags 04:00 Uhr):

0 4 * * 0 sudo -u mastodon bash -c "export PATH=/home/mastodon/.rbenv/shims:/home/mastodon/.rbenv/bin:\$PATH && cd /home/mastodon/live && RAILS_ENV=production bin/tootctl media remove --days=30 && bin/tootctl media remove --prune-profiles --days=30 && bin/tootctl preview_cards remove --days=30"

Fazit: Ein strukturell ungelöstes Problem

Wer die obigen Schritte konsequent durchführt, wird feststellen dass die Diskrepanz zwischen dem was Mastodon als gecachten Speicher ausweist und dem was tatsächlich im B2-Bucket liegt, sich zwar deutlich reduziert – aber nie auf null sinkt. Ein hartnäckiger Rest bleibt, und er wächst kontinuierlich weiter.

Der Grund ist strukturell: Mastodon verliert im laufenden Betrieb regelmäßig die Datenbankreferenz auf Dateien in B2 – durch abgebrochene Uploads, Race Conditions oder alte Bugs. Diese verwaisten Dateien kennt Mastodon nicht mehr, also räumt es sie auch nicht auf. tootctl media remove-orphans hilft, aber nur teilweise: Der Befehl findet nur einen Teil der Orphans, weil er seinerseits auf Mastodon-interne Mechanismen angewiesen ist die lückenhaft sind.

Erschwerend kommt hinzu dass Mastodon in neueren Versionen den Befehl tootctl files remove-orphans – der einen direkten DB-vs-Bucket-Abgleich ermöglicht hätte – wieder entfernt hat. Damit fehlt das einzige Werkzeug das theoretisch eine vollständige Bereinigung ermöglicht hätte.

Ein manuelles Script das alle Dateipfade aus der Mastodon-Datenbank exportiert, sie mit dem tatsächlichen Bucket-Inhalt abgleicht und die Differenz löscht, wäre technisch möglich – aber mit Restrisiko behaftet. Dateien die gerade hochgeladen werden sind in B2 bevor sie in der DB landen; ein zu aggressives Script würde sie als Orphans interpretieren und löschen. Mit einem Zeitpuffer von 48 Stunden lässt sich das Risiko minimieren, aber nicht eliminieren.

Der unbefriedigende Befund: Für ein System das explizit auf dezentrales Selbsthosting ausgelegt ist und dabei zwangsläufig große Mediendatenmengen anfallen, ist das Storage-Management von Mastodon erschreckend primitiv. Ein sauberer, vollständiger Bereinigungsmechanismus existiert nicht. Wer eine größere Instanz mit S3-Storage betreibt, zahlt dauerhaft für Daten die er nicht mehr braucht und an die er mit Bordmitteln nicht herankommt. Das ist kein Einzelfall – es ist der Normalzustand.

Share