Zum Hauptinhalt springen

Laravel Pulse — Konfiguration und Abschaltung

Stand: 3. September 2026

Pulse ist in dieser App kein blosses Dashboard, sondern die Leitung, über die die Server-Metriken überhaupt entstehen. Wer es „einfach abschaltet", nimmt das Server-Dashboard und die CPU-/RAM-/Disk-Alarme mit — ohne Fehlermeldung.

Diese Seite hält fest, was am 3. September 2026 abgeschaltet wurde, was bewusst anblieb, und wie man es zurückholt.


Die Leitung, kurz​

5 Recorder  ──►  pulse_values
│ (Servers, Swap, Postgres, PublicStorage, ActiveUsers)
│
▼ alle 5 Minuten
server:snapshot ──► server_metrics (90 Tage Verlauf)
│
├──► Admin-Server-Dashboard (Charts aus server_metrics,
│ KPI-Karten live aus pulse_values)
└──► CheckServerAlerts (CPU-/RAM-/Disk-Alarme)

Die Recorder feuern nicht von selbst. Sie hängen an SharedBeat bzw. IsolatedBeat, und beide werden ausschliesslich vom Daemon pulse:check ausgelöst. Steht der Daemon, steht die ganze Kette.


Was abgeschaltet wurde — die neun teuren Recorder​

Abgeschaltet sind die Recorder, die pro Request, pro Query und pro Job schreiben:

RecorderFeuerte bei
CacheInteractionsjedem Cache-Zugriff
Exceptionsjeder Exception
Queuesjedem Queue-Ereignis
SlowJobsjedem Job über der Schwelle
SlowOutgoingRequestsjedem ausgehenden HTTP-Aufruf über der Schwelle
SlowQueriesjeder Query über der Schwelle
SlowRequestsjedem Request über der Schwelle
UserJobsjedem Job mit Benutzerbezug
UserRequestsjedem Request mit Benutzerbezug

Sie waren die teuerste Schreiblast der Datenbank: die sechzehn teuersten Statements in der Produktion waren allesamt insert into pulse_aggregates.

Das war ein Last-Problem, kein Platz-Problem. pulse:purge räumt die Tabellen zweimal täglich ab, weshalb sie es nie unter die zwanzig grössten geschafft haben. Teuer waren die Schreibzugriffe und die Sperren, nicht die Bytes.

Der Schalter steht im Default von config/pulse.php:

'enabled' => env('PULSE_SLOW_QUERIES_ENABLED', false),

Was anblieb — und warum es nicht angefasst werden darf​

Fünf Recorder laufen weiter. Sie hängen alle am Beat, schreiben also eine Handvoll Zeilen alle ~15 Sekunden statt pro Request, und kosten damit praktisch nichts:

RecorderLiefert
Servers (Laravel Pulse)den system-Snapshot: CPU, RAM, Disk
SwapMetricsSwap-Auslastung
PostgresMetricsVerbindungen, Cache-Trefferquote
PublicStorageMetricsBelegung der public-Disk
ActiveUsersMetricsgleichzeitige Sitzungen

⚠️ Servers ist tragend, obwohl es ein Standard-Recorder ist. server:snapshot liest genau dessen system-Snapshot aus. Er hat als einziger keinen eigenen enabled-Schalter in der Konfiguration — ein fehlender Schlüssel bedeutet bei Pulse „an".

⚠️ PULSE_ENABLED=false ist NICHT der Weg, Pulse abzuschalten. Der Schalter macht Pulse::record() zum No-op und nimmt alle fünf mit. Das Server-Dashboard wird flach, CheckServerAlerts verstummt — beides ohne Fehlermeldung. Es fällt erst bei einem Ausfall auf, den dann niemand meldet.

Festgehalten wird das in tests/Feature/Pulse/PulseRecorderBudgetTest.php. Der Test prüft beide Hälften in einer Datei, damit sie nicht auseinanderdriften: die neun sind aus, die fünf sind an.


Das Dashboard​

Zwei Seiten waren erreichbar, und beide sind aus:

AdresseWas es warZustand
/admin/pulsedas eingebettete Dashboard im Admin-Layoutantwortet 404
/pulsePulses eigene Seite (Ziel des iframes)nicht mehr registriert

Die zweite ist die, die man übersieht: Hätte man nur die eingebettete Seite abgeschaltet, wäre das echte Dashboard weiter erreichbar gewesen — abgeschaltet nur dort, wo jemand hinsieht. AppServiceProvider::register() ruft dafür Pulse::ignoreRoutes().

Aus heisst 404, nicht „leere Seite". Mit den neun Recordern aus wären fast alle Kacheln leer, und eine leere Kachel liest sich wie ein Defekt statt wie eine Entscheidung. Der Navigations-Eintrag verschwindet aus demselben Grund mit.


Zurückholen​

Nichts davon braucht eine Code-Änderung. Alles hängt an der .env:

# Die Seite und ihren Eintrag in der Navigation zurückholen
PULSE_DASHBOARD_ENABLED=true

# Und die Recorder, deren Kacheln man sehen will — einzeln
PULSE_SLOW_QUERIES_ENABLED=true
PULSE_SLOW_REQUESTS_ENABLED=true
PULSE_EXCEPTIONS_ENABLED=true

Danach php artisan config:clear && php artisan config:cache.

Die Recorder einzeln einzuschalten ist Absicht. Wer eine bestimmte Frage hat („welche Query ist langsam?"), braucht einen Recorder — nicht alle neun und damit die volle Last zurück.


Was am Server laufen muss​

Daemon pulse:checkmuss weiterlaufen. Er löst die Beats aus, an denen die fünf Recorder hängen. Ohne ihn steht das Server-Dashboard still.
PULSE_ENABLEDmuss true bleiben oder gar nicht gesetzt sein.
pulse:workwird nicht gebraucht — der Ingest-Driver ist storage, es wird direkt in die Datenbank geschrieben.
pulse:purgeläuft weiter, 02:07 und 14:07 UTC, Heartbeat pulse_purge. ⚠️ Es ist ein Alias von pulse:clear und macht TRUNCATE auf alle drei Tabellen — es hält kein Zeitfenster ein, PULSE_STORAGE_KEEP wirkt darauf nicht. Die Minute darf kein Vielfaches von 5 sein: server:snapshot läuft alle fünf Minuten, und auf derselben Minute las es das eben geleerte pulse_values und schrieb eine Zeile aus lauter NULL.
pulse:check-sizeläuft weiter (wöchentlich, Alarm ab 2 GB).

Verwandt​

  • config/pulse.php — die Recorder samt ausführlicher Begründung im Kopf des Blocks
  • config/postbox.php → pulse.dashboard_enabled — der Schalter für die Seite
  • Admin-Monitoring — das Server-Dashboard
  • Scheduler-Übersicht — pulse:purge, pulse:check-size