Wer Jobs in der Windows-Aufgabenplanung (Task Scheduler) laufen lässt, stolpert früher oder später über unerklärliche Laufzeitunterschiede. Ein PHP-Skript, das auf der Kommandozeile in 5 Minuten durchläuft, braucht plötzlich 20 Minuten, wenn es über die Windows-Aufgabenplanung ausgeführt wird. Gleicher Benutzer, gleiche Rechte, gleicher Code – vierfache Ausführungszeit. Was war da los?
Nach stundenlangem Debugging, Process Monitor Sessions und unzähligen Konfigurationsvergleichen war die Lösung erschreckend einfach: Die Windows-Aufgabenplanung setzt standardmäßig eine niedrigere Prozesspriorität. Der Standardwert für Tasks in der Aufgabenplanung ist 7 (Below Normal), nicht etwa 4-6 (Normal) wie man erwarten würde. Diese scheinbar kleine Differenz kann bei I/O-intensiven Operationen zu massiven Performance-Einbußen führen.
Die Windows-Prioritätsstufen im Detail lauten:
| Wert | Priorität | Beschreibung |
|---|---|---|
| 0 | Realtime | Höchste Priorität (Vorsicht!) |
| 1 | High | Hohe Priorität |
| 2-3 | Above Normal | Über Normal |
| 4-6 | Normal | Standard für interaktive Prozesse |
| 7 | Below Normal | DEFAULT in Aufgabenplanung |
| 8-9 | Below Normal | Noch niedriger |
| 10 | Idle | Niedrigste Priorität |
Das Problem mit der Priorität in der Aufgabenplanung ist mehrschichtig: Wenn man einen Task exportiert und das XML ansiehst, wird man oft keine Priority-Einstellung finden. Windows verwendet dann stillschweigend den Standardwert 7. Die GUI zeigt diesen Wert beim Export an, aber er ist nicht explizit im Task gespeichert. Die niedrigere Priorität führt nicht nur zu weniger CPU-Zeit, sondern auch zu:
- Gedrosselten Disk-I/O-Operationen
- Niedrigerer Netzwerk-Priorität
- Schlechterem File-System-Caching
- Verzögerungen bei Datenbankzugriffen
Selbst wenn man denselben Benutzer verwendet und "Mit höchsten Privilegien ausführen" aktiviert, läuft der Task in einer anderen Windows-Station/Desktop-Umgebung mit anderen Prioritäten. Um das Problem zu identifizieren, kann man mit Hilfe von PowerShell alle Tasks mit ihrer tatsächlichen Priorität auflisten:
38b7fa6c77dc344401485cd338ea4128
Fast alle meine Tasks liefen mit Priorität 7. Wir korrigieren nun spezifisch die Priorität mehrerer Tasks auf einmal:
38b7fa6c77dc344401485cd338ea4128
Nach dem Setzen der Priorität auf 4 (Normal) lief mein PHP-Skript wieder in den erwarteten 300 Sekunden. Hat man Aufgaben mit einem spezifischen Benutzerkonto konfiguriert, lässt sich das auch einfach in Zeile 10 wiefolgt mitgeben:
38b7fa6c77dc344401485cd338ea4128