maantje/pulse-database
A Laravel Pulse card that surfaces database health and performance metrics, including query throughput, slow queries, connections, and transaction activity, helping you spot bottlenecks in real time.
Install the package (you already need Laravel Pulse on Laravel 10+):
composer require maantje/pulse-database
Confirm Pulse is installed — this card is purely a Pulse dashboard widget, so if php artisan pulse:install hasn't been run, do that first (/pulse should already be reachable).
Register the recorder in config/pulse.php:
'recorders' => [
// ...
\Maantje\PulseDatabase\Recorders\DatabaseRecorder::class => [
'enabled' => env('PULSE_DATABASE_ENABLED', true),
'sample_rate' => env('PULSE_DATABASE_SAMPLE_RATE', 1),
// package-specific options — verify against the README
// 'connection' => env('DB_CONNECTION'),
// 'tables' => ['users', 'orders'],
],
],
Add the card to your Pulse dashboard. If you haven't published it yet:
php artisan vendor:publish --tag=pulse-dashboard
Then in resources/views/vendor/pulse/dashboard.blade.php:
<livewire:pulse-database cols="4" />
(Exact tag — pulse.database, pulse-database, or a namespaced vendor::card — depends on the version; check the tagged component in vendor/maantje/pulse-database/src.)
First use case: Open /pulse and confirm the card renders table sizes, row counts, and connection status. If it's empty, run php artisan pulse:check once — Pulse recorders only populate on the pulse:check schedule (or pulse:work in Redis mode).
Where to look first: config/pulse.php for the recorder entry, resources/views/vendor/pulse/dashboard.blade.php for layout, and vendor/maantje/pulse-database/src/Cards if you need to understand what's actually being shown.
pulse_values snapshot. There is no real-time querying — the card shows whatever the last sample captured.dashboard-local.blade.php / dashboard-production.blade.php per environment (Pulse's view config supports this). Put the database card in the production dashboard where schema health actually matters, and skip it on local where the schema is noisy.PULSE_DATABASE_SAMPLE_RATE low (e.g. 0.1) on large schemas. The recorder is cheap on small DBs and expensive on 500-table MySQL instances because of information_schema scans.tables/skip_tables option, use it — measuring only business-critical tables gives a clearer signal and avoids measuring Laravel internals (migrations, sessions, cache).pulse.slow-queries, pulse.usage, and pulse.laravel-requests in the same row. The value of "database too big / too many tables" is only apparent when correlated with query latency and request volume.connection options) — don't assume the default mysql connection is the only one worth watching.php artisan vendor:publish --tag=pulse-database-views if available) and add color thresholds — e.g., green under 5 GB, amber at 20 GB, red at 50 GB. This converts a passive dashboard into a signal.php artisan pulse:check to a throwaway CI job; this catches recorder misconfiguration (bad connection name, missing permissions) before it silently blanks the production dashboard.pulse:check (or your pulse:work daemon) runs. In production, confirm the schedule is actually active — this is the single most common "it doesn't work" cause.information_schema permissions. Some managed MySQL providers (PlanetScale, some Aurora IAM roles) restrict or rate-limit information_schema queries. You'll see logged errors and no data. Check the app log after the first recorder run.pg_class.reltuples is only accurate after ANALYZE. If numbers look wrong, run ANALYZE on the tables you're measuring — don't assume the recorder is broken.du -h if you need bytes on disk.connection is configured (often DB_CONNECTION). A mismatch between env and config produces empty results without an explicit error in some versions — always log and check after first deploy.pulse_values / pulse_entries and are pruned by Pulse's own pulse:prune schedule. If you're not pruning, these tables will become one of the largest in your schema — ironically what this card is meant to catch.config/pulse.php, remember php artisan config:cache (or config:clear if you don't cache). A stale cached config keeps the recorder disabled silently.<livewire:pulse.database /> 404s the component, list the package's registered components or check the README for the canonical tag for your version.storage/logs/laravel.log, then query SELECT * FROM pulse_values WHERE key LIKE '%database%' directly. If rows exist but the card is empty, the problem is the Livewire view; if no rows exist, it's the recorder/config.config/pulse.php at your subclass if you need extra metrics (index counts, bloat estimates, per-table growth deltas). That lets you upgrade the package without merge conflicts.How can I help you explore Laravel packages today?