// Tutorial · Linux · Wartung

Linux monatlich aufräumen: Altlasten finden, beseitigen und automatisieren

📅 20.09.2026 ⏱ 18 Min. Lesezeit

Ein Linux-System wird nicht von allein langsam – es sammelt. Paketcache, alte Kernel, Runtimes, Logs und Container-Reste summieren sich über Monate zu mehreren Gigabyte. Dieser Artikel zeigt die Befehle für Debian 13 und CachyOS/Arch, ein sicheres Aufräum-Skript für beide Welten – und erklärt systemd-Timer so, dass du sie danach selbst schreiben kannst.

Warum überhaupt aufräumen?

Alle Beispiele in diesem Artikel sind echte Kandidaten – in der Reihenfolge, in der sie üblicherweise Platz freigeben:

QuelleTypische GrößeWächst durch
Paketcache (apt/pacman)1–8 GBjedes Update – alte Versionen bleiben liegen
Alte Kernel in /boot200 MB–1 GBKernel- und Treiberupdates
Logs und Journal100–800 MBDienste, die viel reden
Flatpak-Runtimes300 MB–2 GBverwaiste Runtimes nach App-Updates
Container-Images und -Volumes1–20 GBständige Rebuilds
Benutzer-Caches500 MB–5 GBBrowser, IDEs, Paketmanager-Caches
Papierkorb und Thumbnailsselten geprüftDinge, die man „später“ löschen wollte
Der eigentliche Grund ist nicht der Speicherplatz, sondern die Übersicht. Ein System, das man zweimal im Jahr komplett neu installiert, weil „irgendwas kaputt ist“, entsteht genau durch fehlende Wartung. Ein monatlicher Lauf dauert zwei Minuten und hält System und Kopf frei.

Erst messen, dann löschen

Wer blind löscht, löscht irgendwann das Falsche. Deshalb zuerst die Bestandsaufnahme:

FrageBefehl
Wie voll sind die Dateisysteme?df -h
…und die Inodes? („no space left“ trotz freiem Platz)df -i
Wo liegt der Ballast?sudo du -h --max-depth=1 / 2>/dev/null | sort -h | tail -20
Und darunter?sudo du -h --max-depth=1 /var | sort -h | tail -15
Wie groß ist die Paketcache?Debian: du -sh /var/cache/apt/archives · Arch: du -sh /var/cache/pacman/pkg
Wie groß ist das Journal?journalctl --disk-usage
Wie voll ist /boot?df -h /boot (bei UEFI oft eine eigene, kleine Partition)
Container-Platzverbrauchdocker system df bzw. podman system df
Gelöschte, aber noch offene Dateiensudo lsof +L1 | head -20 – Platz wird erst nach dem Neustart des Prozesses frei

Paket-Altlasten: Debian und Arch

Der größte Einzelposten ist fast immer der Paketcache. Beide Familien haben dafür ihre eigenen Werkzeuge – und bei beiden gibt es eine „sanfte“ und eine „radikale“ Stufe.

AufgabeDebian 13Arch / CachyOS
Cache: nur veraltete Pakete entfernensudo apt autocleansudo paccache -r (aus pacman-contrib)
Cache: alles entfernensudo apt cleansudo pacman -Sc – nur nicht installierte Pakete
Radikal (Arch): alles, auch installierte Versionensudo pacman -Scc → danach ist kein Downgrade mehr möglich
Versionen begrenzen statt löschensudo paccache -rk2 (zwei Versionen behalten) · paccache -ruk0 (alle nicht installierten weg)
Verwaiste Abhängigkeitensudo apt autoremove --purgepacman -Qdtq anzeigen, dann sudo pacman -Rns $(pacman -Qdtq)
Pakete ohne Repo mehr (nach Umstellungen)apt list '~o'pacman -Qm (fremd/AUR – nicht einfach löschen!)
Abgebrochene Installationen reparierensudo dpkg --configure -a · sudo apt --fix-broken installsudo pacman -Dk (Datenbank prüfen)
Vorher simulierensudo apt -s autoremovepacman -Qdtq – die Liste steht schon vor dem Löschen da
Zwei Fallen bei pacman -Qdtq: Erstens sind darunter häufig Pakete, die als makedepends für AUR-Builds gebraucht werden – die Liste also erst lesen, dann löschen. Zweitens: pacman -Scc wirft auch die Pakete weg, mit denen du ein fehlerhaftes Update zurücknehmen könntest. Wer den Notausgang behalten will, nimmt paccache -rk2.

Alte Kernel und /boot

Auf UEFI-Systemen ist /boot oft nur 512 MB groß – und jeder Kernel plus Initramfs belegt dort 50 bis 150 MB. Läuft die Partition voll, schlägt das nächste Kernel-Update fehl, und das System bleibt mit einem halben Update zurück.

# Wie voll, und was liegt dort?
df -h /boot
ls -1 /boot/vmlinuz-* /boot/initrd.img-* 2>/dev/null

# Was läuft gerade? (nur dieser Kernel ist unantastbar)
uname -r

# Debian: alte Kernel werden von apt selbst verwaltet
sudo apt autoremove --purge

# Arch: installierte Kernel-Pakete anzeigen
pacman -Q | grep -E '^linux'
DistributionVorgehenSicherheit
Debian 13Nichts von Hand löschen. apt autoremove --purge entfernt alte Kernel und Initramfs automatisch, lässt den laufenden und einen vorherigen stehen.sehr hoch
Arch / CachyOSsudo pacman -R linux-lts (Beispiel) – aber nur, wenn du weißt, welcher Kernel-Paketname installiert ist und kein Bootloader-Eintrag darauf zeigt.Vorsicht geboten
Die häufigste Notlage: /boot voll, Kernel-Update halb installiert, System startet nicht mehr. Vorbeugen ist einfach – der Eintrag in der Diagnose-Tabelle (df -h /boot) gehört in den monatlichen Lauf. Bei Debian reicht dafür apt autoremove, das sollte man nie „für später“ aufschieben.

Logs und das Journal

Das Journal ist der bequemste Posten überhaupt – es räumt sich selbst auf, wenn man ihm Grenzen setzt. Ohne Grenzen wächst /var/log/journal bis zu 10 % des Dateisystems.

# Bestand
journalctl --disk-usage

# Nach Alter oder Größe begrenzen (sofort wirksam)
sudo journalctl --vacuum-time=14d
sudo journalctl --vacuum-size=500M

# Dauerhaft begrenzen – die bessere Lösung
sudo nano /etc/systemd/journald.conf
#   SystemMaxUse=500M
#   MaxRetentionSec=1month
sudo systemctl restart systemd-journald

# Klassische Logdateien (rsyslog)
sudo du -sh /var/log
sudo find /var/log -type f -name '*.gz' -mtime +30 -ls    # erst ansehen
BausteinWas es tut
SystemMaxUseHarte Obergrenze für das Journal. Ab hier werden alte Einträge verworfen – dauerhafte Lösung statt Einmal-Aufräumen.
logrotateRotiert klassische Logs unter /var/log nach den Regeln in /etc/logrotate.d/ – läuft täglich per Timer bereits von selbst.
*.gz löschenNur die bereits rotierten Archive. Nie die aktuell beschriebenen Dateien anfassen.

Caches: Benutzer, Flatpak, Container

Caches sind ein Minenfeld: Browser-Caches sind harmlos, Caches von Entwicklungswerkzeugen können Build-Zeit kosten, und ~/.cache pauschal zu löschen wirft bei manchen Anwendungen die Anmeldung weg. Deshalb gezielt statt pauschal:

CacheBefehlNebenwirkung
Flatpak-Runtimesflatpak uninstall --unusedkeine – die sicherste Aktion überhaupt
Vorschaubilderrm -rf ~/.cache/thumbnails/*werden neu erzeugt
Papierkorbrm -rf ~/.local/share/Trash/files/*endgültig gelöscht – vorher nachsehen
Dockerdocker system prune -fentfernt gestoppte Container, ungenutzte Netze und dangling Images
Docker-Images (alles Ungenutzte)docker image prune -abeim nächsten Deploy wird neu gezogen/gebaut
Podmanpodman system prune -fanalog
Pythonpip cache purgenächste Installation lädt neu
Node.jsnpm cache clean --forcekeine
Gogo clean -modcacheModule werden neu geladen
Rust/Cargocargo cache -a oder rm -rf ~/.cargo/registry/cacheRebuilds dauern wieder länger
Arch: alte Paketversionensudo paccache -rk2Downgrade der letzten zwei Versionen bleibt möglich
docker volume prune gehört nicht in ein Automatikskript. Volumes enthalten Daten – Datenbanken, Nextcloud-Dateien, Konfigurationen. Ein Skript, das sie regelmäßig entfernt, ist ein Datenverlust mit Verzögerung. Wenn überhaupt, dann manuell und nach docker volume ls.

/tmp, Papierkorb, verwaiste Dateien

/tmp muss man bei systemd-Systemen nicht selbst aufräumen: Es gibt bereits einen Dienst dafür, gesteuert über /usr/lib/tmpfiles.d/tmp.conf und aktiviert durch systemd-tmpfiles-clean.timer.

# Läuft der Aufräum-Timer? (Standard: alle 15 Minuten prüfen, löschen ab 10 Tagen Alter)
systemctl status systemd-tmpfiles-clean.timer

# Konfiguration ansehen und bei Bedarf verschärfen
cat /usr/lib/tmpfiles.d/tmp.conf
sudo systemd-tmpfiles --clean          # sofort aufräumen

# Verwaiste Dateien: gehört diese Datei überhaupt zu einem Paket?
dpkg -S /pfad/zur/datei          # Debian
pacman -Qo /pfad/zur/datei       # Arch

# Optional für Arch: Dateien ohne Paketbesitz finden (extra installieren)
sudo pacman -S lostfiles && sudo lostfiles

Der letzte Punkt ist der interessante: Reste von Programmen, die nie per Paketmanager installiert wurden, findet man nur so. Auf lostfiles-Ausgaben sollte man allerdings nie blind rm anwenden – darunter sind auch selbst erstellte Dateien, Docker-Volumes und Benutzerdaten.

Dienste, Units und Autostarts

# Was ist fehlgeschlagen?
systemctl --failed
systemctl --user --failed

# Was startet wie lange? (Kandidaten zum Deaktivieren)
systemd-analyze blame | head -20

# Laufen noch Timer, die ich mal eingerichtet habe?
systemctl list-timers --all

# Eigene Units, die niemand mehr braucht
systemctl list-unit-files --state=enabled | grep -v '@'

# Crons, die sich angesammelt haben
crontab -l
ls -la /etc/cron.d/ /etc/cron.daily/

Fehlgeschlagene Units aus systemctl --failed haben meist eine echte Ursache (fehlende Datei, Port belegt, Rechte) – die findet man mit journalctl -u dienst -n 50. Es lohnt sich, sie nicht zu ignorieren: Sie kosten bei jedem Start Zeit und verstecken echte Probleme.

Auch „Toter Code“ gehört zur Pflege: Aufräumen heißt nicht nur löschen, sondern auch abschalten. Ein deaktivierter Dienst, den niemand vermisst, ist ein Sicherheitsgewinn – jede laufende Anwendung ist eine Angriffsfläche. Nach zwei Monaten ohne Beschwerde darf die Unit dann ganz weg.

Der wichtigste Punkt: Backup prüfen

Wartung heißt nicht nur Platz schaffen. Der wichtigste monatliche Termin ist die Kontrolle, ob dein Backup wirklich funktioniert – denn genau hier verstecken sich die Probleme, die man erst merkt, wenn es zu spät ist:

# Existiert das Repository und sind die Archive lesbar?
borg list /mnt/backup/borg-repo

# Integrität prüfen (dauert – aber einmal im Monat ist es das wert)
sudo borg check --verify-data /mnt/backup/borg-repo

# Wie viel liegt drin, wie viel ist neu?
borg info /mnt/backup/borg-repo

Und einmal im Quartal der eigentliche Test: eine Datei oder einen Ordner wirklich zurückholen – nicht nur „das Archiv ist da“. Wie das mit extract und mount geht, steht im Borg-Artikel dieser Reihe.

systemd-Timer ausführlich erklärt

Ein systemd-Timer besteht aus zwei Dateien: einer Unit, die die Arbeit beschreibt (.service) und einem Timer, der sagt, wann sie läuft (.timer). Beide gehören zusammen und tragen denselben Namen.

# /etc/systemd/system/systempflege.service
[Unit]
Description=Monatliche Systempflege
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/systempflege.sh
Nice=10
IOSchedulingClass=idle

# /etc/systemd/system/systempflege.timer
[Unit]
Description=Monatlicher Aufruf der Systempflege

[Timer]
OnCalendar=monthly
Persistent=true
RandomizedDelaySec=30m
AccuracySec=1min

[Install]
WantedBy=timers.target

Aktivieren, prüfen, beobachten:

sudo systemctl daemon-reload
sudo systemctl enable --now systempflege.timer

# Wann läuft er das nächste Mal? (Spalte NEXT)
systemctl list-timers systempflege.timer

# Was hat er beim letzten Mal getan?
journalctl -u systempflege.service -n 100 --no-pager

# Sofort testen, ohne auf den Termin zu warten
sudo systemctl start systempflege.service

Die Zeitangaben: OnCalendar verstehen

Das Format ist Wochentag Jahr-Monat-Tag Stunde:Minute:Sekunde – nicht angegebene Teile bedeuten „egal“. Am schnellsten lernt man es mit dem Prüfwerkzeug, das die nächsten Ausführungszeiten ausrechnet:

systemd-analyze calendar "monthly"
systemd-analyze calendar "*-*-* 04:30"
systemd-analyze calendar "Mon..Fri *-*-* 08:00"
AusdruckBedeutung
hourlystündlich zur Minute 0
dailytäglich 00:00 Uhr
weeklyMontag 00:00 Uhr
monthlyam 1. des Monats, 00:00 Uhr
*-*-01 05:001. des Monats um 5 Uhr – die klarere Schreibweise
*-*-01,15 05:00am 1. und 15. um 5 Uhr
Sat,Sun *-*-* 04:00Wochenende um 4 Uhr
Mon..Fri *-*-* 08:30werktags um 8:30 Uhr
*:0/15alle 15 Minuten
~*-*-* 03:00mit ~: nur ausführen, wenn der Zeitpunkt existiert – kein Nachholen

Die wichtigsten Timer-Optionen

OptionWirkung
OnCalendar=Kalenderzeitpunkte – die übliche Wahl für „monatlich“, „täglich“.
OnBootSec=, OnStartupSec=Zeit nach dem Boot bzw. nach Start des User-Managers – etwa für „15 Minuten nach dem Hochfahren“.
OnUnitActiveSec=Abstand relativ zum letzten Lauf (z. B. 1month). Wandert mit dem tatsächlichen Lauf – daher für feste Termine schlechter als OnCalendar.
Persistent=trueVerpasste Ausführungen werden nachgeholt, sobald das System wieder läuft. Die wichtigste Option überhaupt – ohne sie ist ein 04:00-Termin auf einem Laptop praktisch nie fällig.
RandomizedDelaySec=Zufällige Verzögerung (z. B. 30m). Verhindert Lastspitzen zur vollen Stunde und schont langsame Datenträger.
AccuracySec=Wie genau der Zeitpunkt getroffen werden muss. Standard 1min – systemd darf also bis zu eine Minute später starten, was Akku spart. Für „genau um 03:00“ auf 1s setzen.
Unit=Nur nötig, wenn Timer und Service unterschiedlich heißen.
Nice=, IOSchedulingClass=Im Service: Last niedrig halten, damit ein Aufräumlauf nebenbei läuft und nichts blockiert.
ConditionACPower=trueNur auf Netzstrom ausführen – sinnvoll für schwere Wartungsläufe auf Laptops.
Drei Regeln, die 90 % aller Timer-Fragen beantworten:OnCalendar für feste Termine, On*=Sec für relative Abstände. ② Immer Persistent=true bei Kalender-Terminen – sonst passiert nichts, wenn der Rechner ausgeschaltet war. ③ Ein Timer ist nur aktiv, wenn die .timer-Unit aktiviert ist (enable --now) – der .service allein reicht nicht.

Cron als Alternative

Cron ist älter, einfacher und auf jedem Unix zu finden. Auf Arch/CachyOS ist es nicht vorinstalliert (sudo pacman -S cronie), auf Debian ist es Teil des Basissystems. Ein Cronjob ist eine Zeile mit fünf Zeitfeldern:

# ┌ Min (0-59)
# │ ┌ Std (0-23)
# │ │ ┌ Tag des Monats (1-31)
# │ │ │ ┌ Monat (1-12)
# │ │ │ │ ┌ Wochentag (0-7, 0 und 7 = Sonntag)
# │ │ │ │ │
  0 5 1 * *   root  /usr/local/bin/systempflege.sh >/dev/null 2>&1
SchreibweiseBedeutung
0 5 1 * *am 1. jedes Monats um 05:00
30 3 * * 0sonntags um 03:30
*/15 * * * *alle 15 Minuten
@monthlyKurzform für den 1. des Monats, 00:00
@rebooteinmal nach dem Start

Wo Cronjobs hingehören:

OrtFür wen
crontab -edein eigenes Konto (kein Benutzerfeld in der Zeile!)
/etc/cron.d/meinsSystemjobs mit Benutzerfeld – die saubere Ablage für Skripte
/etc/cron.{daily,weekly,monthly}/einfach ein ausführbares Skript hineinlegen – run-parts erledigt den Rest
Die drei Cron-Fallen, über die jeder einmal stolpert:PATH: Cron startet mit minimalem Pfad. Immer absolute Pfade verwenden (/usr/local/bin/systempflege.sh statt systempflege.sh) und im Skript die Umgebung selbst setzen. ② Keine Login-Shell: ~/.bashrc, ~/.profile und deine Variablen existieren nicht. Ein Skript, das interaktiv läuft, scheitert hier gern. ③ Keine Ausgabe sichtbar: Cron schickt alles per Mail – ohne Mailserver landet es im Nichts. Entweder gezielt umleiten (>>/var/log/systempflege.log 2>&1) oder logger nutzen. Fehlt die Ausgabe, sucht man Fehler stundenlang.

Timer oder Cron?

Kriteriumsystemd-TimerCron
AbhängigkeitenAfter=, Wants=, RequiresMountsFor= – wartet echt auf Netzwerk oder Datenträgerkennt keine Abhängigkeiten
ProtokollJournal: journalctl -u nameMail oder selbst umgeleitet
Verpasste LäufePersistent=true holt nachnicht möglich (nur mit anacron)
LastverteilungRandomizedDelaySec eingebautmanuell über die Uhrzeit
Rechte/Umgebungsauber definierbar (User=, Nice=, Sandbox-Optionen)nur Benutzer und minimaler PATH
Einstiegzwei Dateien, aber gut prüfbareine Zeile
Sinnvoll fürWartung, Backups, alles mit AbhängigkeitenAnacron-artige Einfachjobs, ältere Systeme, BSD

Meine Empfehlung: auf systemd-Systemen Timer. Sie sind nicht komplizierter – nur ausführlicher geschrieben – und sie protokollieren von allein. Cron behält seinen Platz für /etc/cron.daily-Ablagen und für Systeme, auf denen systemd fehlt. Beides parallel zu betreiben ist selten sinnvoll, zwei Stellen für dieselbe Aufgabe verwirren nur.

Das monatliche Aufräum-Skript

Ein Skript für beide Welten: Es erkennt die Distribution selbst und führt nur aus, was vorhanden ist. Mit DRY=1 läuft es im Probelauf und zeigt nur, was es tun würde – der wichtigste Schalter überhaupt.

#!/usr/bin/env bash
# /usr/local/bin/systempflege.sh - monatliche Systempflege
set -euo pipefail

DRY="${DRY:-0}"                       # DRY=1 ./systempflege.sh  -> nur anzeigen
run() {
  if [ "$DRY" = "1" ]; then echo "[dry] $*"; else echo "[run] $*"; "$@"; fi
}
have() { command -v "$1" >/dev/null 2>&1; }

echo "=== Systempflege auf $(hostname) - $(date '+%F %T') ==="
echo "--- vorher ---"; df -h / | tail -1

# 1) Logs begrenzen (unabhaengig von der Distribution)
if have journalctl; then
  echo "Journal bisher: $(journalctl --disk-usage 2>/dev/null | tail -1)"
  run journalctl --vacuum-time=14d
  run journalctl --vacuum-size=500M
fi

# 2) Paketverwaltung
if have apt-get; then
  echo "--- Debian-Familie ---"
  run apt-get -y autoremove --purge
  run apt-get -y clean
  run apt-get -y autoclean
  run apt-get -y --fix-broken install
elif have pacman; then
  echo "--- Arch-Familie ---"
  ORPHANS="$(pacman -Qdtq || true)"
  if [ -n "$ORPHANS" ]; then
    echo "Verwaiste Pakete:"; echo "$ORPHANS" | sed 's/^/  - /'
    if [ "$DRY" = "1" ]; then echo "[dry] pacman -Rns $ORPHANS"
    else run pacman -Rns --noconfirm $ORPHANS; fi
  else echo "keine verwaisten Pakete"; fi

  if have paccache; then run paccache -rk2; run paccache -ruk0
  else echo "Hinweis: pacman-contrib fehlt (paccache)"; fi

  [ -d /var/cache/pacman/pkg ] && echo "Paketcache: $(du -sh /var/cache/pacman/pkg | cut -f1)"
fi

# 3) Flatpak
if have flatpak; then run flatpak uninstall --unused --noninteractive; fi

# 4) Container - ohne Volumes!
if have docker; then
  run docker container prune -f
  run docker image prune -f
  run docker network prune -f
fi

# 5) Benutzer-Caches des aufrufenden Kontos
if [ -n "${HOME:-}" ] && [ "$(id -u)" != "0" ]; then
  run rm -rf "$HOME/.cache/thumbnails"/* 2>/dev/null || true
  [ -d "$HOME/.local/share/Trash/files" ] && run rm -rf "$HOME/.local/share/Trash/files"/*
fi

# 6) Backup-Kontrolle (nur pruefen, nicht schreiben)
if have borg && [ -d /mnt/backup/borg-repo ]; then
  echo "--- Borg ---"; run borg list /mnt/backup/borg-repo | tail -3
fi

echo "--- nachher ---"; df -h / | tail -1
echo "=== fertig ==="

Ausführbar machen und erst im Probelauf, dann echt:

sudo install -m 755 systempflege.sh /usr/local/bin/systempflege.sh

# Probelauf als root (zeigt nur, was passieren wuerde)
sudo DRY=1 /usr/local/bin/systempflege.sh

# Echt laufen lassen
sudo /usr/local/bin/systempflege.sh
Warum im Skript zwei Läufe stecken (root und Benutzer): Ein root-Prozess kann die Caches deines Kontos nicht sinnvoll aufräumen – $HOME ist dort /root. Deshalb ist das Skript so gebaut, dass es beides kann: als System-Timer für Pakete, Logs und Container, und zusätzlich als User-Timer (systemctl --user) für ~/.cache und den Papierkorb. Zwei Timer auf dasselbe Skript – das ist der saubere Weg.

Und die Aktivierung – einmal systemweit, einmal für dein Konto:

sudo systemctl daemon-reload
sudo systemctl enable --now systempflege.timer

# User-Variante (Datei unter ~/.config/systemd/user/systempflege-user.timer)
systemctl --user daemon-reload
systemctl --user enable --now systempflege-user.timer

# Kontrolle
systemctl list-timers 'systempflege*'
systemctl --user list-timers 'systempflege*'
Erster Monat: Probelauf mit Ausgabe. Starte das Skript den ersten Monat mit journalctl -u systempflege -n 200 in Sichtweite. Nach zwei sauberen Läufen interessiert dich nur noch die Zeile „vorher/nachher“ – und die ist erstaunlich befriedigend.

Was du nicht löschen solltest

Befehl / PfadWarum nichtBesser
docker volume pruneenthält echte Anwendungsdatenmanuell, nach docker volume ls
pacman -Scclöscht auch die Downgrade-Rettung; danach ist ein fehlerhaftes Update nicht mehr zurücknehmbarpaccache -rk2
rm -rf ~/.cache/*bei manchen Apps gehen Anmeldung oder Konfiguration mitgezielt: thumbnails, Browser-Caches
Alle Kernel außer dem laufendenWenn der neue Kernel nicht startet, fehlt der Notausgangimmer mindestens einen Ersatz behalten
/var/lib/*Datenbanken, Container, libvirt, Flatpak, Docker – Daten, keine Cachesnur mit Kenntnis des Inhalts
Aktuelle /var/log-DateienDer laufende Prozess schreibt hinein, Logrotate wird gestörtnur *.gz, die älter als 30 Tage sind
Snapshots ignorierenSnapper/Timeshift-Snapshots fressen unbemerkt Dutzende GBsnapper list bzw. timeshift prüfen und alte Stände löschen
find / -name '*.log' -deleteBricht im Betrieb alles Mögliche wegnie global, nur in begrenzten Pfaden mit -mtime
Die Regel für alles Automatische: Ein Skript darf nur Dinge löschen, deren Entstehung es erklären kann – Cache, Log, verwaiste Runtime. Sobald „Daten“ im Spiel sind (Volumes, Snapshots, eigene Ordner), bleibt es bei einer Anzeige oder einer Meldung per Mail. Ein Aufräumskript, das Datenverlust verursacht, ist schlimmer als eine volle Festplatte.

Häufige Fragen (FAQ)

FrageAntwort
Wie oft sollte ich aufräumen?Monatlich ist der richtige Rhythmus: häufig genug für Paketcache und Kernel, selten genug, dass es sich nicht selbst beschäftigt. Logs dürfen wöchentlich laufen.
Wie viel bringt das wirklich?Typisch 2 bis 8 GB beim ersten Lauf, danach 200 MB bis 1 GB pro Monat. Der größte Einzeleffekt ist immer der Paketcache.
Ist apt autoremove --purge gefahrlos?Ja, wenn du Pakete nicht „ohne Paketmanager“ bzw. mit apt-mark manual-Bedarf installiert hast. Prüfe mit apt-mark showmanual, was du bewusst installiert hast – und lies vorher apt -s autoremove.
Meine Platte ist trotzdem voll. Warum?Vier übliche Ursachen: Inodes (df -i), gelöschte aber noch offene Dateien (lsof +L1), Snapshots (snapper list) und Container-Volumes.
Timer oder Cron – was soll ich nehmen?Auf systemd-Systemen Timer: Abhängigkeiten, Journal und Persistent sind den Aufwand wert. Cron für /etc/cron.daily und Systeme ohne systemd.
Mein Cronjob läuft nicht. Woran liegt's?Meist am PATH oder an der fehlenden Login-Shell. Absolute Pfade verwenden, Ausgabe in eine Datei oder ins Journal umleiten (logger), dann sieht man den Fehler.
Muss das Skript als root laufen?Für Pakete, Logs und Container ja. Für ~/.cache und den Papierkorb darf es nicht root sein – dafür der User-Timer. Deshalb zwei Läufe auf dasselbe Skript.
Kann ich die Wartung ganz automatisieren?Fast. Zwei Dinge sollten manuell bleiben: die Entscheidung über Daten (Volumes, Snapshots) und der regelmäßige Restore-Test des Backups.

Fazit

Aufräumen ist kein Spektakel, sondern eine Routine aus fünf Befehlen, die man in ein Skript packt – und ein Skript, das man von systemd ausführen lässt. Debian und Arch unterscheiden sich dabei nur in der Paketverwaltung; alles andere (Journal, Caches, Container, Backups) ist identisch.

Der Timer ist dabei die eigentliche Erkenntnis: Zwei kleine Dateien, eine klare Zeitangabe und Persistent=true – danach musst du nie wieder daran denken. Und wenn du das Muster einmal verstanden hast, nutzt du es für alles: Backups, Zertifikate, Aufräumen.

Die fünf Merksätze: ① Erst messen (df, du, journalctl --disk-usage), dann löschen. ② Der Paketcache ist der größte Posten – und der sicherste. ③ Persistent=true macht den Unterschied zwischen einem Timer, der läuft, und einem, der nur existiert. ④ Ein root-Skript räumt keine Benutzer-Caches – dafür braucht es einen User-Timer. ⑤ Wartung schließt den Backup-Test ein. Ein Aufräumen ohne Restore-Prüfung ist nur die halbe Arbeit.
📝
HuuuHosting-Redaktion

Open-Source-Tools für den eigenen Server – getestet, dokumentiert und in der Debian-13-Serie Schritt für Schritt erklärt.