johnpaulmedina/nova-metric-polling
A Laravel Nova package that adds automatic polling to metric cards, keeping dashboards refreshed with live data without manual reloads. Configure polling intervals to display up-to-date metrics, trends, and progress values in your Nova admin panel.
Architecture fit. The package is a narrow extension of Laravel Nova's dashboard metric cards (Value/Trend/Partition/Progress), adding setInterval-style refresh so cards update without a full page reload. Architecturally it sits on top of a proprietary, closed-source admin panel — the fit is tight but the surface area is tiny. This is a 200-line convenience wrapper, not infrastructure. It is only relevant if the organization has already standardized on Nova; it has zero value outside that context, and Nova itself is a per-project paid license ($99–$299+), which means every environment (dev, staging, prod, and any client projects) needs its own license before this package can even be evaluated.
Integration feasibility. Low-to-moderate effort, gated on one unknown: Nova major-version compatibility. The last release (2023-07-08) predates Nova 5 (released 2024, which moved to Vue 3). Nova 4 uses Vue 2; if this package ships Vue 2 component syntax or relies on Nova 4 mixins, it will not run on Nova 5 without a fork. Install is a standard composer require plus asset publishing, but the actual contract is with Nova's private, undocumented internals — the package cannot pin against a stable public API because one does not exist. That is the core feasibility risk, not the install itself.
Technical risk. High, and concentrated in three places:
calculate() — which for Trend/Value metrics is often an aggregate over a large table. This interacts badly with metrics that lack cacheFor(), and it scales with concurrent viewers × card count ÷ interval, not with user count.Key questions to resolve before committing:
cacheFor() on the underlying metric, or bypass it?Stack fit. Laravel 9/10 + Nova 4 is the safe target. Confirm composer.json constraints for laravel/nova, php, and the JS toolchain before anything else — that single file determines whether this is a 30-minute spike or a dead end. If you are on Nova 5, plan to fork and port from day one.
Migration path. Purely additive — no schema, no data migration, no route changes. Rollback is removing the card registrations and the composer entry. That low blast radius is the package's main redeeming quality and the reason a spike is cheap. It also means you can prototype the same behavior in-house with a custom Nova card and a setInterval against a small JSON endpoint in roughly the same effort — which is the realistic alternative to adopting this.
Compatibility. Do not trust the README. Verify against your exact Nova version in a scratch environment: render one Value metric and one Trend metric, confirm the poll fires, confirm the payload shape matches what the Vue component expects, and confirm the card degrades gracefully when the endpoint 500s. If it works, vendor-pin the commit SHA (not a version range) and record the Nova version it was validated against in your dependency notes.
Sequencing.
cacheFor() to every metric you intend to poll before enabling anything beyond the spike.Maintenance. Budget for ownership. Realistically this becomes an internal fork the moment Nova ships its next minor. Assign a named owner, vendor the code into your repo (or a private Composer path repo) rather than pulling from Packagist, and add a smoke test that asserts the poll endpoint returns data for each registered metric. Without that, the failure mode is silent: cards stop refreshing and nobody notices for weeks because stale numbers look plausible.
Support. No vendor, no SLA, tiny community. GitHub issues on a 7-star repo are effectively a suggestion box. Escalation path is "the one engineer who read the Nova source." Factor that into the on-call story — this should never be on a page-worthy path.
Scaling. The math is unforgiving. 20 admins with a dashboard open, 6 metric cards, 30-second interval ≈ 240 metric resolutions per minute, each potentially a multi-second aggregate. Multiply by the number of dashboards and add background browser tabs nobody closed. Mitigations, in order of effectiveness: enable cacheFor() on every polled metric, enforce a minimum interval (60s+, not 5s), pause polling when the tab is hidden (visibilitychange), and cap the number of polled cards per dashboard. If the underlying metrics are expensive, this package is the wrong tool and a pre-aggregated rollup table is the right one.
Failure modes to design around:
Ramp-up. Low for anyone fluent in Laravel + Vue — a mid-level engineer can read the whole package in under an hour. The non-obvious cost is Nova-internals fluency: debugging why a card stopped polling requires understanding how Nova resolves and serializes metric data, which is undocumented. One engineer absorbs that; it should not be spread across the team.
Recommendation. Do not adopt as a dependency. Spike it, and if the pattern is wanted, reimplement it internally as a custom Nova card (~a day of work) so you control Nova-version compatibility and can add the visibility-pause, request-abort, and error-surfacing behavior this package almost certainly lacks. The package's only genuine advantage is that the spike is cheap — which is exactly the reason to use it as a proof of concept and not as production infrastructure.
How can I help you explore Laravel packages today?