Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Filament Laravel Pulse Laravel Package

dotswan/filament-laravel-pulse

Filamental Laravel Pulse integrates Laravel Pulse monitoring into your Filament admin panel, providing a ready-made dashboard to view application performance, slow requests, queues, cache, and usage metrics without leaving Filament.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and verify Pulse first. This package is a thin Filament presentation layer over laravel/pulse; almost every failure people hit is actually a Pulse install or ingestion problem, not a widget problem.

composer require laravel/pulse
php artisan vendor:publish --provider="Laravel\Pulse\PulseServiceProvider"
php artisan migrate            # creates pulse_entries, pulse_values, pulse_aggregates, pulse_*_keys
composer require dotswan/filament-laravel-pulse

Register the plugin on the panel you actually use (usually app/Providers/Filament/AdminPanelProvider.php):

use Dotswan\FilamentLaravelPulse\FilamentLaravelPulsePlugin;

public function panel(Panel $panel): Panel
{
    return $panel
        ->plugin(FilamentLaravelPulsePlugin::make());
}

Confirm data is flowing before touching the UI. Open /pulse (the native Pulse dashboard) and check that requests/servers are being recorded. If that page is empty, the Filament widgets will be empty too. For local work:

php artisan pulse:check      # server metrics, run as a long-lived process
php artisan pulse:work       # queue ingestion worker

Where to look first:

  1. config/pulse.php — enabled, storage, ingest, recording settings decide whether anything reaches the tables.
  2. config/filament-laravel-pulse.php (publishable) — widget-level defaults, thresholds, cache TTLs.
  3. The plugin class itself — it registers the default widget set; this is your map of what's available.
  4. A single widget class (e.g. the slow-queries widget) — read getData() to understand exactly which pulse_* table and time window it queries.

First real-world use case: add PulseUsage + PulseServers to the main dashboard so you can see throughput and app-server health alongside business metrics, then move the heavier widgets (slow queries, exceptions, slow jobs) onto a dedicated "Monitoring" page so you don't slow down the page your team opens all day.

Implementation Patterns

Plugin-wide vs. per-page registration

The plugin registers widgets globally for the panel. That's fine for a small set, but most teams end up with a dedicated page and register widgets there instead, so widgets are lazy-loaded only when someone opens monitoring:

// app/Filament/Pages/Monitoring.php
use Dotswan\FilamentLaravelPulse\Widgets\{PulseUsage, PulseServers, PulseSlowQueries, PulseExceptions};

protected static string $view = 'filament.pages.monitoring';
protected static ?string $navigationIcon = 'heroicon-o-chart-bar';

protected function getHeaderWidgets(): array
{
    return [
        PulseUsage::class,
        PulseServers::class,
    ];
}

protected function getFooterWidgets(): array
{
    return [
        PulseSlowQueries::class,
        PulseExceptions::class,
    ];
}

public function getHeaderWidgetsColumns(): int|array
{
    return 2;
}

Trim the global registration down to what's cheap (usage/servers) and keep the expensive ones on the page. Filament lazy-loads each widget via a separate Livewire request, so a page with nine widgets fires nine requests — a broken widget shows as a permanent "Loading…" card and nothing in the page error log.

Dashboard-as-a-product

Common pattern: separate "Overview", "Performance", and "Reliability" pages, each with three or four widgets. Restrict via canAccess() so the reliability page (exceptions, slow jobs) is visible to devs/on-call only:

public static function canAccess(): bool
{
    return auth()->user()?->hasAnyRole(['admin', 'on-call']);
}

Grouping and sizing

Pulse widgets are Filament widgets, so the usual column API applies. Wide cards ($columnSpan = 'full') for graphs, 1 or 2 for stat cards. If you're mixing with non-Pulse widgets on the same dashboard, put the Pulse ones in a separate header section — the default card heights don't always match and you get ragged rows.

Coexistence with the native Pulse dashboard

Running both is normal and recommended during rollout: native /pulse for deep-dives and debugging, Filament widgets for the at-a-glance view. Don't let the Filament plugin become the only way to reach Pulse — when a widget misbehaves, the native page tells you whether it's a presentation bug or a data bug in seconds.

Subclassing for custom thresholds or filtering

Rather than editing vendor code, extend a widget and override the data method or the threshold properties. This is the cleanest extension point for things like "only show slow queries over 500ms" or "group by route prefix":

class OurSlowQueries extends PulseSlowQueries
{
    protected function getData(): array
    {
        $data = parent::getData();
        // filter / relabel here
        return $data;
    }
}

Then reference OurSlowQueries::class in the page. Same approach for changing chart colors to match your panel theme.

Deployment and operations

Monitoring widgets are only as good as the ingestion setup behind them:

  • pulse:check on one node (or a scheduled command), not all web nodes.
  • pulse:work under Supervisor, separate from your normal queue workers, so a stuck app queue doesn't blind you.
  • Pulse is disabled by default outside local. Set PULSE_ENABLED=true in staging/production or your widgets will render empty forever and look broken.
  • If you use the Redis ingest driver, the widgets still read the pulse_* tables — make sure pulse:work is actually draining Redis into them.
  • Trim/clear on a schedule (pulse:clear per type, or configure the trim) — otherwise pulse_entries grows unbounded and the slow-query/slow-request widgets become the slowest thing in your app.

Gotchas and Tips

Empty widgets almost always mean one of four things: PULSE_ENABLED is false, the Pulse migrations were never run, pulse:check/pulse:work aren't running, or your cache store is misconfigured so Pulse cards can't persist. Check /pulse first; it eliminates the widget layer immediately.

Missing pulse_* tables throw SQL errors inside a lazy-loaded request. The page renders fine, the widget spins, and the actual exception is buried in storage/logs/laravel.log or the livewire request in Telescope. If a single card is stuck, hit the Livewire update endpoint directly or check the log — don't assume it's a CSS issue.

Widgets show aggregated, slightly stale data. Pulse cards are cached (default ~15s, configurable via PULSE_CACHE and the package config). During an incident, don't debug the widget — check the raw tables. If numbers look frozen, clear the cache before assuming ingestion broke.

Auth is not inherited from Pulse's gate. Native Pulse protects /pulse with the viewPulse gate. These widgets render inside your panel and rely on Filament's panel access / canView(). If you assumed the gate covered the widgets, you may have just exposed server names and exception traces to every panel user. Add canView()/canAccess() explicitly.

Cost scales with table size. Slow-queries, slow-requests, slow-jobs, and exceptions scan pulse_entries/pulse_aggregates over a time window. On a busy app after a few weeks, a dashboard with all of them becomes noticeably slow. Mitigations: keep only usage/servers on the default dashboard, aggressive trimming, and don't put Pulse widgets on a page that polls.

Widget polling compounds the problem. If you set a polling interval on a page with several Pulse widgets, you're re-running those aggregate queries every N seconds for every open tab. For monitoring, prefer manual refresh or a long interval (60s+).

Tenancy isn't modeled. Pulse records by key/type with no tenant column. In a multi-tenant panel, a tenant-scoped Pulse page either shows global data (likely a data-leak concern for exception messages) or needs custom filtering on pulse_entries. Decide deliberately rather than inheriting whatever the default widget shows.

Filament major-version compatibility. Check the package's composer.json constraints against your Filament version before upgrading the panel — this ecosystem is small and lags major Filament releases. Pin the plugin version in composer.json if you upgrade Filament incrementally.

Dark mode and theme drift. Chart colors and card backgrounds in Pulse-derived widgets don't always pick up a custom Filament theme. If widgets look out of place, override the chart color properties in a subclass rather than patching vendor views.

Publish the config once, then stop. php artisan vendor:publish --tag=filament-laravel-pulse-config gives you thresholds and cache settings. Keep the published file minimal and comment why each value differs from default — future you will not remember whether a threshold was tuned or accidental.

Testing. Don't unit-test the widgets against real Pulse tables. Seed a handful of rows into the relevant pulse_* table in a test case (or use Pulse's own fakes where available) and assert the widget renders; anything more couples your tests to Pulse internals.

Debugging checklist when a card is wrong, in order: native /pulse correct? → raw table has recent rows? → cache cleared? → log shows an exception on the lazy-load request? → config threshold changed? That order resolves roughly everything.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast