WordPress Backups treiben nachts oft CPU, RAM und I/O hoch, weil Kompression, Datei-Scanning und Datenbank-Dumps parallel laufen und Engpässe erzeugen. Ich zeige Ursachen und konkrete Gegenmaßnahmen, damit geplante Sicherungen nicht mehr zu spürbarer Serverlast, Timeouts und Ausfällen führen.
Zentrale Punkte
- CPU/I-O durch Kompression, Datei-Scanning und parallele Tasks
- DB-Dumps mit großen Tabellen, Transients und Logs als Engpass
- WP-Cron triggert unzuverlässig und kollidiert mit Caches
- Plugins konkurrieren mit Frontend-Traffic und sterben bei Timeouts
- Strategie: inkrementell, throttlen, Server-Cron, Snapshots
Warum WordPress-Backups nachts Server überlasten
Serverlast steigt beim Backup sprunghaft, weil mehrere ressourcenhungrige Schritte gleichzeitig laufen: Dateien packen, Datenbank exportieren, Prüfsummen bilden und oft zusätzlich Remote-Upload. Die CPU glüht bei ZIP/GZIP-Kompression, während RAM-Spitzen durch große Archive entstehen. I/O-Waits verlängern jedes Dateilesen, was auf drehenden Platten stark ausbremst und selbst SSDs bei Dauerlast ausreizt. Große Installationen mit zehntausenden Dateien in wp-content/uploads verursachen dabei lange Scans und blockierende Prozesse. Läuft parallel noch ein Cron-Event oder ein Bild-Optimierer, häufen sich PHP-Worker, die Prozesszahl wächst, und der Load-Average klettert spürbar.
Die wahre Bremse: Datenbank-Dumps und gleichzeitige Zugriffe
Datenbank-Exporte treffen nachts oft auf Jobs wie Caches, Logrotation oder Suchindex-Updates; dadurch entstehen Sperren, Lock-Waits und abgebrochene Verbindungen. Tabellen wie wp_posts, wp_postmeta oder Plugin-Logs wachsen beim Export weiter, wenn Schreibzugriffe laufen; das erhöht den Dump und verlängert die Laufzeit. Alte Transients, Session-Reste und historische Log-Einträge blähen die Sicherung zusätzlich auf. Ich räume vor dem Backup auf, optimiere Tabellen und reduziere das Volumen, damit die Exportzeit und der Speicherbedarf sinken. Für tiefergehende Hintergründe zu Lastspitzen durch Exporte hilft mir dieser kurze Leitfaden zu Datenbank-Backups.
Konsistenz beim Dump: Transaktionen, Sperren und Optionen
Konsistenz sichere ich, indem ich transaktionale Dumps nutze: Für InnoDB arbeite ich mit einem Snapshot über --single-transaction und streame mit --quick, damit keine riesigen Zwischenspeicher entstehen. --lock-tables vermeide ich auf schreibaktiven Systemen, weil es Frontend-Requests ausbremst; stattdessen setze ich nötigenfalls kurze Read-Locks nur für Metadaten. Gibt es noch MyISAM-Tabellen, plane ich das Backup in ein engeres Ruhefenster oder friere kurz mit Read-Lock ein, um Inkonsistenzen zu verhindern. Große Tabellen sichere ich in Scheiben über --where-Filter nach Datum oder Status (z. B. nur neue Bestellungen), sodass ich in nachgelagerten Inkrementen nachziehe. Ich erhöhe max_allowed_packet nur so weit wie nötig, um Speicherpeaks zu vermeiden, und prüfe, ob Binlog-Events das Volumen zusätzlich treiben. So bleibt der Dump reproduzierbar, ohne unnötig zu blockieren.
WP-Cron als Auslöser: Warum geplante Backups nachts scheitern
WP-Cron startet Aufgaben nicht auf Systemebene, sondern bei Seitenaufrufen; bei wenig Traffic in der Nacht triggert daher kein Event oder es beginnt verspätet. Greifen CDN, Full-Page-Cache oder Wartungsmodus, verpuffen Auslöser und Backups bleiben hängen. Unter Last schlagen zudem PHP-Timeouts zu; lange Tasks bekommen nur 30–60 Sekunden und reißen ab. Ich entkopple daher Aufgaben von Seitenaufrufen, deaktiviere WP-Cron per define(‚DISABLE_WP_CRON‘, true); und setze einen echten System-Cron. Mit Locking wie flock verhindere ich Doppelstarts, was Kollisionen und hohe Prozesszahlen unterbindet.
Plugin-Backups vs. Server-Snapshots
Plugins, die im WordPress-Stack laufen, konkurrieren mit Besucheranfragen, Cron-Events und Admin-Aktionen; bei Peaks entstehen Timeouts und unvollständige Archive. Chunking hilft, indem das Plugin Pakete in kleineren Blöcken schreibt, und Throttling drosselt CPU sowie I/O; beides entschärft Lastspitzen. In Shared-Umgebungen fehlt oft Shell-Zugriff oder ionice/nice, wodurch Drosselung begrenzt bleibt. Ich umgehe den Stack bei kritischen Zeitfenstern mit serverseitigen Snapshots auf Volume-Ebene; die Sicherung friert den Zustand ein, ohne PHP-Worker zu binden. Offsite-Targets verringern Risiken bei Ausfällen am Primärsystem und beschleunigen Restore-Pfade deutlich.
Backup-Strategien, die Serverlast senken
Strategie entscheidet über Laufzeit und Risiko: Kleine Sites (bis ca. 5.000 Dateien, DB bis etwa 200 MB) sichere ich täglich inkrementell und exportiere die Datenbank mit niedriger Kompression. Mittlere Projekte erhalten wöchentliche Vollbackups sowie tägliche differentielle Sicherungen für Dateien und Datenbank. Große Shops fahren monatliche Vollbackups, wöchentliche differentielle und mehrere inkrementelle Läufe pro Tag, damit das Wiederherstellen zielgenau und schnell bleibt. Ich schließe Cache-Ordner (z. B. page-cache, object-cache) und temporäre Verzeichnisse aus, um nutzlosen I/O zu sparen. Einen kompakten Performance-Guide nutze ich als Merkzettel für sinnvolle Ausschlüsse und Intervallwahl.
Aufbewahrung, Rotation und Verschlüsselung
Retention bestimme ich anhand von RPO/RTO und Kosten: Ein GFS-Schema (täglich, wöchentlich, monatlich) hält kurze und lange Zeiträume abgedeckt, ohne Speicher zu sprengen. Ich rotiere aggressiver bei Datei-Backups, behalte DB-Snapshots länger, weil sie meist kleiner sind. Backups verschlüssele ich vor dem Transfer und am Ziel; Schlüssel lagere ich getrennt, drehe sie regelmäßig und teste die Entschlüsselung automatisiert. Passwörter und Keys gehören nicht in Repos oder Cron-Einzeiler, sondern in Variablen oder Key-Stores mit minimalen Rechten. So lassen sich Offsite-Kopien sicher halten, ohne den Restore zu verkomplizieren.
So setze ich Server-Cron richtig auf
System-Cron sorgt für zuverlässige Ausführung: Ich setze in wp-config.php define(‚DISABLE_WP_CRON‘, true);, lege dann in crontab einen Job an, der alle 15–60 Minuten wp-cron.php über die CLI ausführt. Ein Beispiel: /usr/bin/php -q /pfad/zu/wp-cron.php > /dev/null 2>&1 oder mit WP-CLI wp cron event run --due-now. Gegen doppelte Starts hilft flock -n /tmp/wp-cron.lock -c "wp cron event run --due-now", was parallele Läufe zuverlässig verhindert. Ich messe anschließend die Wirkung auf CPU, RAM und I/O und passe Intervalle an, bis keine Engpässe mehr auftreten. Wer Intervalle strukturiert abstimmen will, findet Anhaltspunkte zu Cronjob-Intervalle, die Last glätten und Zeitfenster sichern.
Praxisbefehle: Drosseln, Exkludieren, Stabilisieren
Shell-Befehle setze ich gedrosselt ab, damit der Webserver atmen kann. Beispiele aus meiner Praxis:
- Gedrosselter Cron mit Locking:
* 2-5 * * * flock -n /tmp/backup.lock nice -n 10 ionice -c2 -n7 /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1 - Tar mit Ausschlüssen und niedriger Kompression:
tar --exclude='wp-content/cache' --exclude='node_modules' --exclude='vendor' -I 'gzip -1' -cf /backups/wp-files.tar.gz /pfad/zur/site - Rsync mit Bandbreitenlimit und Resume:
rsync -a --delete --partial --bwlimit=2000 /backups/ remote:/ziel/ - Mysqldump mit Streaming:
mysqldump --single-transaction --quick --routines --events dbname | gzip -1 > /backups/db.sql.gz - WP-CLI Such-/Ersetzlauf nach Restore:
wp search-replace 'https://alt' 'https://neu' --all-tables --precise
Solche Defaults senken Spitzenlast, halten die Laufzeiten kalkulierbar und erleichtern das Fortsetzen nach Abbrüchen.
Drosseln, stückeln, priorisieren: Techniken gegen Lastspitzen
Throttling begrenze ich, indem ich Prozessorzeit und I/O für Backup-Prozesse senke; auf der Shell geht das mit nice/ionice, in Plugins mit Delay-Optionen zwischen Archiv-Schritten. Chunking mit festen Paketgrößen (z. B. 50–100 MB) reduziert max_allowed_packet-Probleme und erleichtert das Fortsetzen nach Abbrüchen. Ich teste die optimale Kompressionsstufe: Höhere Kompression spart Speicherplatz, verbraucht aber deutlich mehr CPU; bei Engpässen stelle ich niedriger. Remote-Ziele wie S3-kompatible Buckets oder SSH-Storage nutze ich mit Retries und Bandbreitenlimit, damit Webzugriffe weiter flüssig bleiben. Bei Verbindungsabbrüchen erhöhe ich Timeouts und aktiviere Resume, was nächtliche Transfers stabil hält.
Restore-Realität: RTO/RPO messen und Proberestores üben
Wiederherstellung entscheidet, ob ein Backup wirklich taugt. Ich definiere RPO (maximaler Datenverlust) und RTO (maximale Ausfallzeit) und teste gegen diese Ziele. Geplante Übungen auf einer Staging-Instanz zeigen, ob Dumps importierbar sind, Such-/Ersetzungen sauber greifen und Medienpfade stimmen. Teil-Restores (nur DB, nur Uploads, nur ein Subsite bei Multisite) probiere ich explizit, weil sie im Alltag häufiger sind als Vollrestores. Nach jedem Test messe ich Dauer, Engpässe und dokumentiere die Schritte, damit im Ernstfall niemand rätselt. Erst wenn Proberestores reproduzierbar klappen, gilt die Sicherung für mich als produktionsreif.
Datenbank und Dateien vor dem Backup entschlacken
Aufräumen vor dem Backup wirkt oft stärker als jede Hardware: Ich lösche abgelaufene Transients, trimme Log-Tabellen und führe OPTIMIZE/ANALYZE aus. Uploads-Ordner befreie ich von doppelten Miniaturen, Cache- und tmp-Verzeichnissen; Build-Ordner wie node_modules oder vendor schließe ich aus. Zuerst sichere ich die Datenbank, danach die Dateien, damit die Konsistenz stimmt und Lock-Zeiten sinken. Prüfsummen für große Dateien setze ich nur, wenn sie wirklich nötig sind, weil sie CPU kosten. Ein kurzer Testlauf mit Teilauswahl deckt vergessene Ausschlüsse auf, bevor ich das volle Fenster nutze.
Multisite, Mediatheken und Dateistrukturen
Multisite-Netzwerke vergrößern Dump-Volumen und Datei-Anzahl rapide. Ich sichere Subsites gezielt, wenn das RPO es erlaubt, und prüfe Domain-Mappings sowie Upload-Pfade separat. In großen Mediatheken begrenze ich Vorschaubilder: Überflüssige Größen entferne ich vorab, so schrumpfen Backups ohne Qualitätsverlust im Frontend. Für Uploads halte ich die Jahres-/Monatsstruktur bei, damit Inkremente effizient greifen und Restore-Pfade klar bleiben. Ein Manifest mit Dateiliste (z. B. via find + Hash) hilft, Unterschiede schnell zu erkennen, ohne komplette Verzeichnisse neu zu scannen.
Symlinks, Netzlaufwerke und Offload-Speicher
Dateisysteme verhalten sich unterschiedlich: Bei NFS oder FUSE-Mounts erhöhe ich Timeouts und meide extremes Parallelisieren, weil Latenzen sonst Kaskaden auslösen. Symlinks dereferenziere ich je nach Ziel mit tar --dereference, wenn der Inhalt ins Archiv soll; andernfalls dokumentiere ich Links, damit sie beim Restore korrekt gesetzt werden. Liegen Uploads extern (z. B. Offload), sichere ich nur Metadaten und eine Stichprobe der Dateien; Vollbackups des Offload-Ziels plane ich separat, um doppelte Transfers zu vermeiden.
Monitoring: Symptome erkennen und schnell beheben
Signale zeigen sich früh: Steigt der Load-Average und bleiben PHP-FPM-Worker lange busy, stauen sich Requests und TTFB schießt hoch. Meldungen wie “MySQL server has gone away” deuten auf zu kleine Paketgrößen oder lange Pausen hin; ich erhöhe max_allowed_packet und stelle Resume sicher. Lock wait timeouts weisen auf konkurrierende Schreibvorgänge hin; ich verschiebe Exporte in noch ruhigere Zeitfenster oder setze transaktionale Dumps ein. Häkchen wie “loopback requests” in Health-Checks geben Hinweise, wenn WP-Cron wegen CORS, Auth-Problemen oder Basic-Auth blockiert. Nach jedem Backup wärme ich Caches an, damit die Seite sofort wieder schnell antwortet und Boxen nicht bei den ersten Besuchern rotieren.
Fehlerkultur: Logs, Alarme und schnelle Gegenmaßnahmen
Logging halte ich strukturiert: Ein menschenlesbares Log und eine kompakte JSON-Variante reichen mir für Alerting und spätere Analysen. Ich definiere klare Abbruchkriterien (z. B. mehr als drei Retries, Transfer unter Schwellwert X, Dump länger als Y Minuten) und löse dann Alarme aus. Backoff-Strategien vermeiden Dauerschleifen, wenn das Ziel temporär nicht erreichbar ist. Nach Ausfällen markiere ich inkonsistente Artefakte, statt sie stillschweigend als “grün” zu führen; so täuschen alte, defekte Archive nicht über Lücken hinweg.
Fehlerbilder nachts: Warum es ausgerechnet dann kracht
Nachtfenster wirken verlockend, weil weniger Besucher online sind; genau dann fehlen aber WP-Cron-Auslöser und Backups starten zu spät oder gleichzeitig. Treffen mehrere verschobene Jobs zusammen, addieren sich CPU-Spitzen, I/O-Waits und RAM-Bedarf. Caches leeren sich, Warmup fehlt und das erste Traffic-Bündel trifft auf eine ausgelastete Maschine. Ich plane Sicherheitsfenster so, dass sie Abstände zu anderen Heavy-Tasks wie Bildoptimierung, Suchindex oder Berichten haben. Ein kurzes, automatisiertes Monitoring per Log-Scan vor Start verhindert überraschende Überschneidungen.
Container, Orchestrierung und Snapshots auf Volume-Ebene
Container entkoppeln Applikation und Backups: In Orchestrierungen fahre ich Backups als dedizierte Jobs mit begrenzten Ressourcen (Requests/Limits), damit Webpods nicht drosseln. Persistent Volumes sichere ich über Storage-Snapshots, die ich anschließend asynchron exportiere. Kritisch sind Reconcile-Zeiten: Ich sperre nicht die App, sondern stelle sicher, dass Dumps innerhalb der Snapshot-Kohärenz laufen (Transaktionen), und prüfe, dass Pods währenddessen neue Artefakte schreiben können, ohne den Snapshot zu verfälschen. CronJobs takte ich so, dass sie nicht mit Deployments kollidieren.
Kostenfallen und Offsite-Strategien
Kosten entstehen vor allem durch Speicherklassen, Egress und API-Operationen. Ich komprimiere lokal, lade erst dann hoch und limitiere Re-Uploads durch saubere Inkremente. Lifecycle-Regeln räumen alte Generationen automatisiert weg; für Langzeitaufbewahrung wechsle ich in günstigere Klassen mit längerer Abrufzeit, aber halte die jüngsten Stände “heiß” für schnelle Restores. Upload-Fenster parke ich außerhalb von Geschäftszeiten, achte aber auf Überschneidungen mit Reports und Imports, damit nicht wieder nächtliche Staulagen entstehen. So bleibt Offsite-Sicherheit bezahlbar und planbar.
Hosting-Wahl: Limits, Isolierung und Kosten
Ressourcen und Isolierung entscheiden darüber, ob ein Backup still und sauber durchläuft. Shared-Hosting bietet günstige Einstiege, greift aber bei CPU, RAM und I/O hart ein, sobald Limits erreicht sind. Ein VPS trennt Projekte und erlaubt echte Cronjobs, WP-CLI sowie feinere Steuerung für Lastdrosselung. Managed-WordPress-Hosting nimmt viel Arbeit ab, setzt aber eigene Regeln und limitiert teils Shell-Zugänge. Ich prüfe daher, wie der Anbieter mit Cron, I/O-Limits, PHP-Workers und Remote-Transfers umgeht, bevor ich Sicherungsfenster festlege.
| Hosting-Typ | Vorteile | Nachteile | Einsatz |
|---|---|---|---|
| Shared | Niedriger Preis | Enges CPU/RAM/I-O, Timeouts | Kleine Sites mit kurzen Backups |
| VPS | Isolierte Ressourcen, echter Cron | Höhere Kosten als Shared | Mittlere bis große Projekte |
| Managed WP | Komfort, Wartung enthalten | Weniger Freiheiten, Limits | Teams mit Fokus auf Inhalte |
Sicherheit und Datenschutz
Datenschutz berücksichtige ich von Beginn an: Backups enthalten oft personenbezogene Daten, Sessions und Bestellinfos. Ich minimiere Inhalte (keine Debug-Logs, keine temporären Exporte) und verschlüssele konsequent. Zugriffe aufs Backup-Ziel sind strikt getrennt vom Produktionszugriff und rollenbasiert. Löschanfragen setze ich auch in Backup-Generationen durch, soweit das rechtlich und technisch sinnvoll umsetzbar ist, und dokumentiere Ausnahmen mit klaren Fristen. Protokolliert wird, wer wann worauf zugegriffen hat; so bleiben Audits beherrschbar.
Kurz zusammengefasst
Essenz: Nächtliche Backups bremsen Server vor allem durch Kompression, Datei-Scanning, große Dumps und schwankende WP-Cron-Trigger. Ich löse das, indem ich WP-Cron deaktiviere, System-Cron mit Locking setze und Backups in inkrementelle, gedrosselte Schritte aufteile. Vorbereitungen an Datenbank und Dateien reduzieren Volumen, senken I/O und verkürzen die Laufzeit. Monitoring deckt Konflikte früh auf, während Cache-Warmup die Seite nach dem Sicherungslauf schnell hält. Mit klaren Intervallen, sinnvollen Ausschlüssen und passendem Hosting bleiben Nächte ruhig und Daten zuverlässig geschützt.


