Swap ist eines der unterschätzten Themen beim Server-Bootstrap. Wer keine Swap-Datei einrichtet, riskiert, dass bei Speicherengpässen der OOM-Killer unkontrolliert Prozesse abschießt — meist genau die wichtigen, weil sie den meisten Speicher belegen. Wer hingegen großzügig Swap dimensioniert, ohne sich Gedanken über Tunables zu machen, holt sich messbare Performance-Einbußen ins Haus. Dieser Artikel zeigt, wie du Swap als Datei anlegst, mit swappiness das Verhalten steuerst, OOM-Killer-Events im Journal liest und mit earlyoom eine modernere Variante einsetzt — inklusive ehrlichem Realitätscheck zum Mythos „Swap killt SSDs”.

Was Swap ist und wann es sinnvoll ist

Swap ist ein Speicherbereich auf der Festplatte, den der Kernel als Erweiterung des RAMs nutzen kann. Wenn der physische RAM knapp wird, lagert der Kernel selten genutzte Speicher-Seiten auf den Swap aus und gibt den entsprechenden RAM-Bereich frei. Das ist deutlich langsamer als RAM-Zugriff, aber unendlich viel besser, als dass der Kernel mangels Speicher Prozesse abschießt.

Wann Swap sinnvoll ist:

  • Server mit knappem RAM (≤ 4 GB) — hier hilft Swap als Sicherheitsnetz, weil seltene Speicherspitzen sonst sofort den OOM-Killer auslösen würden.
  • Workloads mit unregelmäßigen Speicher-Peaks — z. B. Build-Server, die kurzfristig viel RAM brauchen, oder Anwendungen mit gelegentlichen großen Berechnungen.
  • Server, die Hibernate-fähig sein sollen — der Hibernate-Modus schreibt den kompletten RAM-Inhalt in den Swap. Auf VPS irrelevant, auf Heim-Servern mit Stromausfall-Vorsorge ein Thema.

Wann Swap weniger sinnvoll ist:

  • Server mit reichlich RAM (≥ 32 GB), die nie an die Grenze kommen. Hier wird Swap praktisch nie genutzt — schadet aber auch nicht.
  • Datenbank-Server mit klar dimensioniertem Working Set — wenn die DB einmal in den Swap schreibt, ist die Performance ruiniert. Hier ist es besser, der OOM-Killer schießt eine Anwendung ab, als dass die DB auf Festplatte zugreift.
  • Container-Hosts, bei denen Container-Memory-Limits gesetzt sind — Swap wird vom Container ohnehin nicht (oder nur eingeschränkt) gesehen.

Realitätscheck: „Swap killt SSDs.” Dieser Mythos kommt aus den frühen 2010ern, als die ersten SSDs niedrige Schreib-Endurance hatten. Eine moderne Server-SSD hält je nach Modell 1.000–10.000 vollständige Disk-Schreibvorgänge aus. Auch ein Swap, der täglich mehrere Gigabyte schreibt, schafft es in unter zehn Jahren nicht annähernd in den kritischen Bereich. Das Argument ist heute nicht mehr relevant.

Swap-File oder Swap-Partition?

Es gibt zwei Wege, Swap bereitzustellen:

  • Swap-Partition — ein eigener Festplattenbereich, beim Setup angelegt. Klassischer Weg, früher Pflicht.
  • Swap-File — eine ganz normale Datei in einem regulären Filesystem, vom Kernel als Swap genutzt. Heute der Standard-Weg.

Auf einem laufenden Server ist eine Swap-File die deutlich praktischere Wahl: Sie lässt sich beliebig vergrößern, verkleinern oder entfernen, ohne die Partitionierung zu ändern. Performance-Unterschiede zur Partition sind seit Kernel-Version 3.x verschwunden — auf modernen Filesystems (ext4, xfs, btrfs) gibt es keinen messbaren Unterschied.

Eine Ausnahme: ZFS und Btrfs mit Copy-on-Write vertragen Swap-Files nicht ohne Vorbereitung. Bei ZFS macht man entweder ein eigenes ZFS-ZVOL als Swap oder verzichtet ganz darauf. Bei Btrfs braucht das Swap-File spezielle Attribute (chattr +C vor dem Anlegen, was nur auf neuen Dateien funktioniert). In dieser Anleitung gehen wir von ext4 oder xfs aus — der Standard auf den meisten Distros.

Wie viel Swap? Faustregeln:

RAM-GrößeSwap-EmpfehlungBegründung
≤ 2 GB2× RAMKnappes System, Sicherheitsnetz wichtig
2–8 GB1× RAMKlassische Faustregel, immer noch sinnvoll
8–32 GB4–8 GB fixMehr als 8 GB Swap braucht praktisch nie ein Server-Workload
≥ 32 GB4 GBSymbolisch — falls doch mal etwas durchgeht. Oder ganz weglassen.

Diese Werte sind Daumenregeln, keine Wissenschaft. Bei spezialisierten Workloads (DB, In-Memory-Cache) gelten andere Optimierungen.

Swap-File anlegen

Vor dem Anlegen prüfen, ob bereits Swap vorhanden ist:

Bash
sudo swapon --show
free -h

Wenn swapon --show leer ist und free -h in der Swap-Zeile nur Nullen zeigt, gibt es noch keinen Swap.

Eine Swap-Datei mit 4 GB anlegen:

Bash
sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

Erläuterungen:

  • fallocate -l 4G — reserviert 4 GB Speicherplatz für die Datei. Auf manchen Filesystems (insbesondere alten ext4-Versionen oder bei aktiviertem discard) funktioniert das nicht zuverlässig. Alternative: dd if=/dev/zero of=/swapfile bs=1M count=4096 — langsamer, aber garantiert echter Speicher.
  • chmod 600 — die Swap-Datei darf nur root lesen. Andernfalls könnte ein anderer User durch Lesen der Datei sensible RAM-Inhalte (Passwörter, Schlüssel) abgreifen, die der Kernel dort ausgelagert hat.
  • mkswap — formatiert die Datei als Swap, schreibt das Swap-Header-Format hinein.
  • swapon — aktiviert die Datei sofort als Swap, ohne Reboot.

Verifikation:

Bash
sudo swapon --show
free -h

Erwartete Ausgabe in swapon --show:

Output
NAME      TYPE SIZE USED PRIO
/swapfile file   4G   0B   -2

Persistenz über Reboots in /etc/fstab

swapon aktiviert die Datei nur für die aktuelle Boot-Session — nach einem Reboot ist sie wieder aus. Damit sie automatisch eingebunden wird, gehört ein Eintrag in /etc/fstab:

Bash
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

Die Felder in fstab bedeuten:

FeldWertBedeutung
Quelle/swapfilePfad der Swap-Datei
MountpointnoneSwap hat keinen Mountpoint
FilesystemswapSpezial-Typ
OptionenswStandard für Swap (entspricht defaults für reguläre Filesysteme)
Dump0Kein Backup
Pass0Kein fsck

Test, dass die fstab-Zeile funktioniert (ohne Reboot):

Bash
sudo swapoff /swapfile
sudo swapon -a       # liest /etc/fstab und aktiviert alle Swap-Einträge
sudo swapon --show

Wenn swapon --show die Datei wieder zeigt, ist /etc/fstab korrekt.

swappiness und vfs_cache_pressure

Zwei Kernel-Parameter steuern, wie aggressiv Swap genutzt wird und wie der Kernel mit Filesystem-Caches umgeht:

vm.swappiness — Wert 0–200. Steuert, ab welchem RAM-Auslastungs-Punkt der Kernel beginnt, Pages auszulagern. Default auf den meisten Distros: 60. Das ist relativ aggressiv und wurde für Desktop-Systeme optimiert.

WertVerhalten
0Swap nur, wenn RAM komplett voll ist. Unter Last fast nie.
1Wie 0, aber Swap bleibt verfügbar (anders als völliges Abschalten). Empfohlen für Datenbank-Server.
10Swap zurückhaltend nutzen. Empfohlen für Server mit klar dimensioniertem RAM-Bedarf.
60Default. Aggressiv für Desktops, oft zu aggressiv für Server.
100Sehr aggressiv. Nutzt Swap fast wie zusätzliches RAM. Selten sinnvoll.

Empfehlung für die meisten Server: 10 — Swap als Sicherheitsnetz, aber nicht als regulärer Speicherplatz.

vm.vfs_cache_pressure — Wert 1–1000. Steuert, wie aggressiv der Kernel Inode/Dentry-Caches freigibt. Default: 100. Bei file-intensiven Workloads (Webserver mit vielen kleinen Dateien) kann ein niedrigerer Wert (50) Performance bringen, weil das Filesystem-Layout im Cache bleibt.

Beide Parameter setzen — sofort und persistent:

Konfiguration /etc/sysctl.d/99-swap.conf
vm.swappiness=10
vm.vfs_cache_pressure=50

Werte sofort anwenden, ohne Reboot:

Bash
sudo sysctl --system
cat /proc/sys/vm/swappiness        # erwartet: 10

Den OOM-Killer verstehen

Wenn RAM und Swap voll sind und ein Prozess mehr Speicher anfordert, wird der OOM-Killer (Out-of-Memory) aktiv. Der Kernel wählt einen Prozess zum Abschießen aus — die Auswahl basiert auf einem Score, der pro Prozess in /proc/<pid>/oom_score einsehbar ist. Faustformeln zur Score-Berechnung:

  • Mehr RAM-Verbrauch → höherer Score → eher betroffen.
  • Höhere oom_score_adj-Anpassung → höherer Score (positive Werte) oder niedriger (negative Werte, bis -1000 = nie töten).
  • Root-Prozesse bekommen Bonus, werden also später getötet.

Was abgeschossen wird: Meistens der Prozess, der gerade am meisten RAM hat. Auf einem Webserver mit großer App ist das die App selbst — also genau das, was lebenswichtig ist. Das ist der Hauptgrund, warum Server bei Speicherproblemen ungewollt offline gehen.

OOM-Events finden im systemd-Journal:

Bash
sudo journalctl -k | grep -iE 'oom|killed process'

Ein typischer Eintrag sieht so aus:

Output
Out of memory: Killed process 12345 (php-fpm) total-vm:892456kB,
anon-rss:735028kB, file-rss:0kB, shmem-rss:0kB, UID:33 pgtables:1632kB oom_score_adj:0

Das Log zeigt: PID, Prozess-Name, Speicherverbrauch zum Zeitpunkt des Abschießens. Bei wiederkehrenden OOM-Events ist die Diagnose meistens: zu wenig RAM für den Workload, oder Memory-Leak in der Anwendung.

Wichtige Prozesse vor dem OOM-Killer schützen — z. B. SSH und Datenbank, damit man bei Problemen noch reinkommt:

Konfiguration /etc/systemd/system/sshd.service.d/oom.conf
[Service]
OOMScoreAdjust=-900

-900 macht sshd zu einem fast unanfechtbaren Prozess (gültiger Bereich: -1000 bis 1000). Anwenden mit:

Bash
sudo systemctl daemon-reload
sudo systemctl restart ssh   # bzw. sshd auf RHEL

earlyoom — bevor es ernst wird

Der Kernel-OOM-Killer reagiert sehr spät — wenn er anspringt, ist das System oft schon einige Minuten unresponsive, weil der Kernel hektisch versucht, Pages auszulagern. earlyoom ist ein User-Space-Daemon, der RAM-Auslastung beobachtet und früher eingreift, wenn Schwellen unterschritten werden.

Installation:

Bash Debian / Ubuntu
sudo apt install earlyoom -y
sudo systemctl enable --now earlyoom
Bash RHEL-Familie (über EPEL)
sudo dnf install epel-release -y
sudo dnf install earlyoom -y
sudo systemctl enable --now earlyoom

Konfiguration in /etc/default/earlyoom (Debian/Ubuntu) bzw. /etc/sysconfig/earlyoom (RHEL):

Konfiguration /etc/default/earlyoom
# Bei <10 % freiem RAM und <10 % Swap eingreifen
EARLYOOM_ARGS="-m 10 -s 10 --avoid '(^|/)(systemd|sshd|dbus-daemon)$' --prefer '(^|/)(chrome|firefox|node)$'"

Wichtige Optionen:

  • -m 10 — bei unter 10 % freiem RAM eingreifen (terminiert dann den Prozess mit höchstem Verbrauch).
  • -s 10 — zusätzlich bei unter 10 % freiem Swap.
  • --avoid <PATTERN> — diese Prozesse niemals abschießen. Hier: alle systemd-Komponenten und sshd.
  • --prefer <PATTERN> — diese bevorzugt abschießen. Sinnvoll für bekannte Speicher-Fresser.

Logs:

Bash
journalctl -u earlyoom -f

Vorteil von earlyoom: das System bleibt responsive — keine minutenlangen Hängern bei RAM-Knappheit. Der Trade-off ist, dass earlyoom etwas konservativer agiert (ein Prozess wird ggf. abgeschossen, obwohl der Kernel-OOM-Killer noch nicht eingegriffen hätte). Für die meisten Server ist das ein guter Kompromiss.

Sicherheits- und Performance-Checkliste

  • Swap-Dimensionierung passend zum RAM und Workload — nicht „Faustregel × 2”, sondern bewusste Entscheidung
  • Swap-File mit chmod 600 abgesichert
  • /etc/fstab-Eintrag vorhanden, mit swapon -a getestet
  • vm.swappiness auf 10 (typisch für Server), bei DB-Servern auf 1
  • Kritische Services (sshd, DB) per OOMScoreAdjust vor OOM-Killer geschützt
  • earlyoom installiert, falls plötzliche RAM-Spitzen erwartet werden
  • Monitoring auf Speicher-Auslastung, sodass Probleme früh sichtbar werden, bevor der OOM-Killer eingreifen muss

Häufige Fehler bei Swap und OOM

Swap-File mit zu offenen Rechten

Ohne chmod 600 kann jeder lokale User die Swap-Datei lesen und damit auf ausgelagerte RAM-Inhalte zugreifen — Passwörter, Schlüssel, Session-Tokens. chmod 600 ist Pflicht, nicht „nice to have”.

Swap-File mit fallocate funktioniert nicht überall

Auf manchen Filesystem-Konfigurationen (besonders alte ext4-Versionen mit aktivierten Extents-Optionen, sowie XFS in bestimmten Modi) erzeugt fallocate eine Datei mit „Holes”, die Swap nicht unterstützt. Symptom: mkswap meldet swap file has holes. Lösung: stattdessen dd if=/dev/zero of=/swapfile bs=1M count=4096, langsamer, aber garantiert.

swappiness=0 statt swappiness=1 gesetzt

swappiness=0 bedeutet seit Kernel 3.5 nicht mehr „Swap nur im Notfall”, sondern „Swap niemals nutzen, lieber OOM-Killer”. Wer das aggressive Verhalten möchte, sollte explizit swappiness=1 setzen — der Kernel hält dann Swap als letzte Reserve, ohne ihn aktiv zu nutzen.

OOM-Killer schießt sshd ab

Auf knapp dimensionierten Servern kommt es vor, dass der OOM-Killer ausgerechnet sshd erwischt — und der Server damit ohne Login-Möglichkeit dasteht. OOMScoreAdjust=-900 für sshd in einem systemd-Drop-in macht sshd nahezu unangreifbar für den OOM-Killer.

Fehlendes Monitoring auf RAM-Auslastung

OOM-Events sind ein Symptom, kein Auslöser. Wer dauerhaft an die RAM-Grenze stößt, hat ein Dimensionierungs- oder Memory-Leak-Problem — beides sollte früher sichtbar werden als beim OOM-Kill. Monitoring (Prometheus, Netdata, einfacher: cron-Job mit Mail-Alarm bei >90 % RAM-Auslastung) gehört zur Bootstrap-Hygiene.

earlyoom auf Datenbank-Servern

earlyoom kann den DB-Prozess als „der mit dem höchsten RAM-Verbrauch” identifizieren und abschießen. Auf DB-dedizierten Servern ist das fatal — die Datenbank ist meistens legitim der größte RAM-Verbraucher. Hier mit --avoid die DB explizit ausnehmen oder earlyoom bewusst nicht installieren.

Verwandte Artikel

Externe Quellen

/ Weiter

Zurück zu Server-Bootstrap

Zur Übersicht