Wartung einer Webanwendung: Was sie kostet und was drin sein muss
“Die App läuft doch, warum sollen wir monatlich zahlen?” Diese Frage höre ich regelmäßig. Die Antwort kommt meist 6 bis 12 Monate später, wenn PHP veraltet ist, Security-Patches fehlen und der Server unter Last zusammenbricht. Webapp-Wartung ist wie Zahnpflege: Ignorieren funktioniert eine Weile, aber die Rechnung kommt garantiert.
Executive Summary
| Wartungspaket | Monatliche Kosten | Enthalten | Für wen geeignet |
|---|---|---|---|
| Basic | 500 bis 800 Euro | Security-Updates, Monitoring, Backup-Prüfung | Kleine interne Tools |
| Standard | 1.000 bis 1.500 Euro | Basic + Bug-Fixes, kleine Anpassungen, SLA 48h | Business-kritische Apps |
| Premium | 2.000 bis 2.500 Euro | Standard + 24/7 Monitoring, SLA 4h, On-Call | Mission-Critical, E-Commerce |
ROI-Beispiel: 1.200 Euro/Monat Wartung vs. 45.000 Euro Notfall-Migration nach Security-Breach.
Was passiert ohne Wartung?
Die ersten 6 Monate: Alles läuft
Die App funktioniert, keine sichtbaren Probleme. Der Geschäftsführer fragt: “Warum zahlen wir Wartung?”
Monate 6 bis 12: Erste Warnsignale
- PHP-Version veraltet (Security-Patches fehlen)
- SSL-Zertifikat läuft unbemerkt ab
- Datenbank wächst, keine Optimierung
- Erste Performance-Einbrüche bei Lastspitzen
Monate 12 bis 18: Probleme häufen sich
- Hoster kündigt Support für alte PHP-Version an
- Backup funktioniert nicht mehr (niemand hat geprüft)
- Externe APIs ändern sich, Integrationen brechen
- Security-Scanner meldet kritische Schwachstellen
Monat 18+: Die Rechnung kommt
Real Case: Ein Kunde hatte 18 Monate keine Wartung. Dann:
- SQL-Injection-Angriff über bekannte Schwachstelle
- 48h Downtime, Datenverlust
- DSGVO-Meldung an Behörde erforderlich
- Notfall-Migration: 45.000 Euro
- Verlorenes Kundenvertrauen: unbezahlbar
Mit 1.200 Euro/Monat Wartung wäre das nicht passiert.
Was gehört zur Wartung?
1. Security-Updates (kritisch)
// Security-Patch-Management
class SecurityUpdateService {
private array $komponenten = [
'php' => ['aktuell' => '8.3.x', 'minimum' => '8.1.x', 'eol' => '8.0.x'],
'postgresql' => ['aktuell' => '16.x', 'minimum' => '14.x'],
'composer_packages' => 'wöchentlich prüfen',
];
public function pruefeUpdates(): array {
$ergebnis = [];
// PHP-Version prüfen
$phpVersion = phpversion();
if (version_compare($phpVersion, '8.1.0', '<')) {
$ergebnis[] = [
'komponente' => 'PHP',
'status' => 'kritisch',
'aktion' => 'Sofort updaten, EOL erreicht',
];
}
// Composer-Pakete auf Schwachstellen prüfen
// composer audit --format=json
$audit = shell_exec('composer audit --format=json 2>/dev/null');
$vulnerabilities = json_decode($audit, true);
if (!empty($vulnerabilities['advisories'])) {
foreach ($vulnerabilities['advisories'] as $paket => $advisory) {
$ergebnis[] = [
'komponente' => $paket,
'status' => 'schwachstelle',
'aktion' => 'Update auf sichere Version',
];
}
}
return $ergebnis;
}
}
Aufwand: 2 bis 4 Stunden/Monat Was passiert ohne: Bekannte Schwachstellen bleiben offen, Angriffsfläche wächst
2. Monitoring & Alerting
// Einfaches Health-Check-Endpoint
class HealthCheckController {
public function __construct(
private PDO $db,
private Redis $redis
) {}
public function check(): array {
$status = ['status' => 'healthy', 'checks' => []];
// Datenbank-Verbindung
try {
$this->db->query('SELECT 1');
$status['checks']['database'] = 'ok';
} catch (PDOException $e) {
$status['status'] = 'unhealthy';
$status['checks']['database'] = 'failed';
}
// Redis-Verbindung
try {
$this->redis->ping();
$status['checks']['redis'] = 'ok';
} catch (Exception $e) {
$status['status'] = 'degraded';
$status['checks']['redis'] = 'failed';
}
// Festplattenspeicher
$freeSpace = disk_free_space('/');
$totalSpace = disk_total_space('/');
$usedPercent = (1 - $freeSpace / $totalSpace) * 100;
if ($usedPercent > 90) {
$status['status'] = 'warning';
$status['checks']['disk'] = "kritisch: {$usedPercent}% belegt";
} else {
$status['checks']['disk'] = "ok: {$usedPercent}% belegt";
}
// Response-Header für Monitoring-Tools
http_response_code($status['status'] === 'healthy' ? 200 : 503);
return $status;
}
}
Was überwachen:
- Verfügbarkeit (Uptime)
- Response-Zeiten
- Error-Raten (5xx-Fehler)
- Ressourcen (CPU, RAM, Disk)
- SSL-Zertifikat-Ablauf
- Datenbank-Verbindungen
Aufwand: Setup 4h, dann automatisiert Tools: UptimeRobot (kostenlos), Datadog, New Relic, eigenes Monitoring
3. Backup-Management
// Backup-Verifizierung
class BackupVerificationService {
public function verifyBackup(string $backupPath): array {
$ergebnis = [
'datum' => date('Y-m-d H:i:s'),
'pfad' => $backupPath,
'checks' => [],
];
// 1. Backup existiert
if (!file_exists($backupPath)) {
$ergebnis['status'] = 'failed';
$ergebnis['checks']['existenz'] = 'Backup nicht gefunden';
return $ergebnis;
}
// 2. Backup ist aktuell (max 24h alt)
$alter = time() - filemtime($backupPath);
if ($alter > 86400) {
$ergebnis['checks']['alter'] = 'Warnung: älter als 24h';
} else {
$ergebnis['checks']['alter'] = 'ok';
}
// 3. Backup hat sinnvolle Größe
$groesse = filesize($backupPath);
$minGroesse = 1024 * 1024; // Min 1 MB
if ($groesse < $minGroesse) {
$ergebnis['checks']['groesse'] = 'Warnung: verdächtig klein';
} else {
$ergebnis['checks']['groesse'] = 'ok: ' . round($groesse / 1024 / 1024) . ' MB';
}
// 4. Restore-Test (monatlich)
// In separater Test-Umgebung durchführen!
$ergebnis['status'] = 'ok';
return $ergebnis;
}
public function getBackupRetention(): array {
return [
'täglich' => '7 Tage aufbewahren',
'wöchentlich' => '4 Wochen aufbewahren',
'monatlich' => '12 Monate aufbewahren',
'offsite' => 'Kopie an zweitem Standort',
];
}
}
Aufwand: 1 bis 2 Stunden/Monat (Prüfung + Restore-Test) Was passiert ohne: Backup existiert, aber Restore funktioniert nicht (häufiger als gedacht)
4. Performance-Überwachung
// Slow-Query-Log auswerten
class PerformanceAnalyzer {
public function analyzeSlowQueries(PDO $db): array {
// PostgreSQL: pg_stat_statements aktivieren
$stmt = $db->query("
SELECT
query,
calls,
total_exec_time / 1000 as total_seconds,
mean_exec_time / 1000 as avg_seconds,
rows
FROM pg_stat_statements
WHERE mean_exec_time > 100 -- > 100ms
ORDER BY total_exec_time DESC
LIMIT 10
");
$slowQueries = $stmt->fetchAll(PDO::FETCH_ASSOC);
$empfehlungen = [];
foreach ($slowQueries as $query) {
if ($query['avg_seconds'] > 1) {
$empfehlungen[] = [
'query' => substr($query['query'], 0, 100) . '...',
'durchschnitt' => round($query['avg_seconds'], 2) . 's',
'aufrufe' => $query['calls'],
'empfehlung' => 'Index prüfen, Query optimieren',
];
}
}
return $empfehlungen;
}
public function checkTableBloat(PDO $db): array {
// PostgreSQL: Aufgeblähte Tabellen finden
$stmt = $db->query("
SELECT
schemaname || '.' || relname as tabelle,
pg_size_pretty(pg_total_relation_size(relid)) as groesse,
n_dead_tup as dead_tuples,
last_vacuum,
last_autovacuum
FROM pg_stat_user_tables
WHERE n_dead_tup > 10000
ORDER BY n_dead_tup DESC
");
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
}
Monatliche Checks:
- Slow Queries identifizieren
- Index-Nutzung prüfen
- Tabellen-Bloat (VACUUM)
- Cache-Hit-Ratio
Aufwand: 2 bis 4 Stunden/Monat
5. Dependency-Updates
# Composer-Updates (PHP)
composer outdated --direct # Zeigt veraltete Pakete
composer update --dry-run # Simulation
composer update # Update durchführen
# npm-Updates (Frontend, falls vorhanden)
npm outdated
npm update
// Automatisierte Dependency-Prüfung
class DependencyChecker {
public function checkComposerPackages(): array {
$composerLock = json_decode(
file_get_contents('composer.lock'),
true
);
$veraltete = [];
foreach ($composerLock['packages'] as $package) {
// Prüfe auf Security-Advisories
// Prüfe auf Major-Updates
// Prüfe auf EOL-Versionen
}
return $veraltete;
}
public function getUpdateStrategy(): array {
return [
'security' => 'Sofort (innerhalb 24h)',
'bugfix' => 'Wöchentlich (minor versions)',
'feature' => 'Monatlich (nach Test)',
'major' => 'Quartalsweise (mit Migrationsplan)',
];
}
}
Aufwand: 2 bis 4 Stunden/Monat Risiko ohne: Veraltete Dependencies mit bekannten Schwachstellen
SLA-Beispiele zum Kopieren
SLA Basic (500 bis 800 Euro/Monat)
Reaktionszeiten:
- Kritisch (System nicht nutzbar): Reaktion innerhalb von 24 Stunden (Werktage)
- Hoch (Funktion eingeschränkt): Reaktion innerhalb von 48 Stunden (Werktage)
- Normal (Fehler ohne Workaround): Reaktion innerhalb von 5 Werktagen
Leistungen:
- Security-Updates für PHP, PostgreSQL, Betriebssystem
- Monatliche Backup-Prüfung
- Uptime-Monitoring mit E-Mail-Alert
- Bis zu 2 Stunden Bug-Fixes pro Monat (nicht übertragbar)
Nicht enthalten:
- Feature-Entwicklung
- Wochenend- und Feiertagssupport
- Performance-Optimierung
SLA Standard (1.000 bis 1.500 Euro/Monat)
Reaktionszeiten:
- Kritisch (System nicht nutzbar): Reaktion innerhalb von 4 Stunden, Fix innerhalb von 24 Stunden
- Hoch (Funktion eingeschränkt): Reaktion innerhalb von 8 Stunden, Fix innerhalb von 48 Stunden
- Normal (Fehler ohne Workaround): Reaktion innerhalb von 24 Stunden, Fix innerhalb von 5 Werktagen
Leistungen:
- Alles aus Basic
- Proaktives Monitoring (Response-Zeiten, Error-Rates)
- Monatlicher Performance-Report
- Bis zu 5 Stunden Bug-Fixes/kleine Anpassungen pro Monat
- Quartalsweiser Restore-Test
- Dependency-Updates mit Changelog
Nicht enthalten:
- Feature-Entwicklung (separat abrechenbar)
- 24/7-Support
SLA Premium (2.000 bis 2.500 Euro/Monat)
Reaktionszeiten:
- Kritisch (System nicht nutzbar): Reaktion innerhalb von 1 Stunde, Fix innerhalb von 4 Stunden (24/7)
- Hoch (Funktion eingeschränkt): Reaktion innerhalb von 2 Stunden, Fix innerhalb von 8 Stunden
- Normal: Reaktion innerhalb von 4 Stunden, Fix innerhalb von 24 Stunden
Leistungen:
- Alles aus Standard
- 24/7 Monitoring mit Telefon-Eskalation
- On-Call-Bereitschaft (Rufbereitschaft)
- Bis zu 10 Stunden Bug-Fixes/Anpassungen pro Monat
- Monatlicher Restore-Test
- Proaktive Performance-Optimierung
- Dedizierter Ansprechpartner
Verfügbarkeitsgarantie: 99,5% Uptime (max. 3,6h Downtime/Monat)
Kostenvergleich: Wartung vs. Keine Wartung
Szenario 1: Alles läuft gut (3 Jahre)
| Posten | Mit Wartung | Ohne Wartung |
|---|---|---|
| Monatliche Kosten | 1.200 Euro x 36 = 43.200 Euro | 0 Euro |
| Notfall-Einsätze | 0 Euro | 8.000 Euro (2x jährlich) |
| PHP-Migration (EOL) | Inkludiert | 12.000 Euro |
| Performance-Probleme | Proaktiv behoben | 6.000 Euro Notfall-Optimierung |
| Gesamt | 43.200 Euro | 42.000 Euro |
Fast gleich? Ja, aber: Bei “Ohne Wartung” ist das Risiko nicht eingepreist.
Szenario 2: Security-Incident
| Posten | Mit Wartung | Ohne Wartung |
|---|---|---|
| 3 Jahre Wartung | 43.200 Euro | 0 Euro |
| Security-Breach | Verhindert | 45.000 Euro Notfall-Response |
| Downtime (48h) | 0 Euro | 15.000 Euro Umsatzausfall |
| DSGVO-Strafe | 0 Euro | 10.000 bis 50.000 Euro |
| Reputationsschaden | 0 Euro | Unbezifferbar |
| Gesamt | 43.200 Euro | 70.000 bis 110.000 Euro |
Was Sie selbst machen können
Tägliche Checks (5 Minuten)
# Einfaches Health-Check-Skript für Cronjob
#!/bin/bash
URL="https://ihre-app.de/health"
RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" $URL)
if [ $RESPONSE != "200" ]; then
echo "ALARM: Health-Check fehlgeschlagen (HTTP $RESPONSE)" | \
mail -s "App-Alarm" admin@firma.de
fi
Wöchentliche Checks (30 Minuten)
- Error-Logs prüfen (ungewöhnliche Muster?)
- Disk-Usage prüfen (> 80% kritisch)
- Backup-Datum prüfen (aktuell?)
- SSL-Zertifikat prüfen (Ablauf in < 30 Tagen?)
Monatliche Checks (2 Stunden)
- Security-Updates verfügbar?
- Composer/npm outdated prüfen
- Slow-Query-Log analysieren
- Uptime-Report reviewen
- Backup-Restore testen (in Staging)
Wartungsvertrag: Worauf achten
Must-Haves im Vertrag
1. Klare Definition von “Bug” vs. “Feature”:
“Als Bug gilt ein Verhalten der Software, das von der dokumentierten Spezifikation abweicht. Neue Funktionalitäten oder Änderungswünsche gelten als Feature und werden separat beauftragt.”
2. Reaktionszeit vs. Lösungszeit:
“Reaktionszeit bezeichnet die Zeit bis zur ersten qualifizierten Rückmeldung. Lösungszeit bezeichnet die Zeit bis zur Behebung des Problems oder Bereitstellung eines Workarounds.”
3. Definition der Prioritäten:
class TicketPrioritaet {
public const KRITISCH = [
'definition' => 'System nicht nutzbar, keine Workaround möglich',
'beispiele' => ['Login nicht möglich', 'Datenbank nicht erreichbar', 'Komplettausfall'],
'reaktion' => '4h',
'loesung' => '24h',
];
public const HOCH = [
'definition' => 'Wichtige Funktion eingeschränkt, Workaround existiert',
'beispiele' => ['Export fehlerhaft', 'Performance-Einbruch', 'Teilausfall'],
'reaktion' => '8h',
'loesung' => '48h',
];
public const NORMAL = [
'definition' => 'Fehler ohne kritische Auswirkung',
'beispiele' => ['Darstellungsfehler', 'Falsches Datumsformat', 'Kleinere Bugs'],
'reaktion' => '24h',
'loesung' => '5 Werktage',
];
}
4. Stundenkontingent:
“Das monatliche Kontingent von X Stunden verfällt am Monatsende und ist nicht übertragbar. Nicht genutzte Stunden werden nicht erstattet. Zusätzliche Stunden werden mit Y Euro/Stunde abgerechnet.”
Red Flags im Vertrag
- “Best Effort” ohne konkrete Zeiten: Bedeutet nichts
- Keine Definition von Prioritäten: Führt zu Diskussionen
- Automatische Verlängerung ohne Kündigungsrecht: Prüfen!
- Keine Regelung für Preisanpassungen: Jährliche Erhöhung vereinbaren
Checkliste: Brauche ich Wartung?
Ja, unbedingt (Standard oder Premium)
- Die App ist geschäftskritisch (Ausfall kostet > 1.000 Euro/Stunde)
- Personenbezogene Daten werden verarbeitet (DSGVO)
- Externe Nutzer (Kunden, Partner) arbeiten damit
- Integration mit anderen Systemen (API-Abhängigkeiten)
- Mehr als 100 aktive Nutzer
Ja, mindestens Basic
- Die App wird regelmäßig genutzt
- Keine internen Ressourcen für Updates vorhanden
- PHP/PostgreSQL-Version älter als 2 Jahre
Vielleicht verzichtbar
- Rein internes Tool mit < 10 Nutzern
- Kein Internet-Zugriff (nur Intranet)
- Eigene IT-Abteilung mit PHP/PostgreSQL-Know-how
- Niedriger Schaden bei Ausfall
Häufige Fragen
Was kostet die Wartung einer Webanwendung?
Was passiert, wenn eine Webanwendung nicht gewartet wird?
Was gehört in einen Wartungsvertrag?
Fazit: Wartung ist Versicherung
Webapp-Wartung ist keine optionale Luxusleistung. Sie ist eine Versicherung gegen vorhersehbare Risiken. Die Frage ist nicht “ob” etwas passiert, sondern “wann”.
Meine Empfehlung:
| App-Typ | Empfohlenes Paket | Monatliche Kosten |
|---|---|---|
| Internes Tool, < 50 User | Basic | 500 bis 800 Euro |
| Business-App, 50 bis 500 User | Standard | 1.000 bis 1.500 Euro |
| E-Commerce, > 500 User | Premium | 2.000 bis 2.500 Euro |
| Mission-Critical, 24/7 | Premium + On-Call | 2.500+ Euro |
Die billigste Wartung ist die, die Probleme verhindert, bevor sie entstehen.
Sie haben eine bestehende Webapp ohne Wartungsvertrag? In einem kostenlosen 30-Minuten-Check analysiere ich den Ist-Zustand und empfehle das passende Wartungspaket.
Über Carola Schulte
Software-Architektin mit 25+ Jahren Erfahrung. Spezialisiert auf robuste Business-Apps mit PHP/PostgreSQL, Security-by-Design und DSGVO-konforme Systeme. 1,8M+ Lines of Code in Produktion.
Projekt im Kopf?
Lassen Sie uns besprechen, wie ich Ihre Anforderungen umsetzen kann - kostenlos und unverbindlich.
Kostenloses ErstgesprächWeitere interessante Artikel
Webanwendung entwickeln lassen: Kosten 2026
Was kostet es, eine Webanwendung entwickeln zu lassen? Realistische Budgets nach Umfang, wo die Kosten wirklich entstehen und wie Sie ein ...
Was passiert mit Ihrer Software, wenn die Entwicklerin ausfällt?
Bus-Faktor eins: Ihre Software hängt an einer Person. Was Sie als Auftraggeber in der Hand haben müssen (Code, Zugänge, Doku, Deployment) und ...
Backup ohne Restore-Test ist kein Backup
Ein Backup, das nie zurückgespielt wurde, ist eine Hoffnung. Wie Sicherung, Aufbewahrung und Restore-Test zusammen ein belastbares Backup ...