jhumanj/laravel-model-stats
Laravel Model Stats lets you track and query statistics for your Eloquent models over time, making it easy to add counts, trends, and date-based metrics to dashboards and reports with minimal setup.
Install the package
composer require jhumanj/laravel-model-stats
Publish the config (and assets/migrations if the package ships them)
php artisan vendor:publish --provider="Jhumanj\ModelStats\ModelStatsServiceProvider"
The published config/model-stats.php is the single most important file — it is where you register the models that appear on the dashboard, set the route prefix, and configure middleware.
Register the models you care about in config/model-stats.php. The package is config-driven: a model only shows up on the dashboard if it is listed there. Start with three to five tables that matter to the business (e.g. User, Order, Post) rather than every model in the app.
Run migrations if the published migrations add a stats/snapshot table, then hit the dashboard route (default /model-stats in most versions).
First use case: point it at your core tables and use the growth-over-time view as a lightweight "is the product growing?" dashboard — useful in a weekly standup or as a sanity check after a deploy. Treat it as read-only reporting, not a metrics platform; it is not a replacement for a proper analytics/BI tool.
config/model-stats.php and think of it as the dashboard menu. Order the entries by importance — the first models are the ones people see.['web', 'auth', 'can:viewModelStats'] and define a viewModelStats Gate that checks for an admin role. This is the single most common production integration point.local/staging, or register the service provider conditionally, so production users never see it unless you deliberately want them to. A typical pattern: enable it always in local, and in production only behind your admin guard./model-stats. The package's dashboard is a self-contained page, so a link/iframe is the cleanest integration.app/Console/Kernel.php (or the modern routes/console.php schedule) once per day. Verify whether your version is query-on-request or snapshot-based before scheduling anything — this is the one detail that varies most between releases.'Users' instead of App\Models\User::class) — the raw class name is noise for non-developer stakeholders.composer.json constraints before installing on Laravel 11/12 — you may need to fork it, relax constraints, or pin an older Laravel. Do this spike before committing to it in a real project.vendor:publish --force for the package's public assets.config/model-stats.php in production, run php artisan config:clear / config:cache. A model "missing" from the dashboard is almost always a cached config or a typo in the class name.created_at indexes. Most dashboards aggregate by date on the primary table. On large tables this is a full scan. Add an index on created_at (or whatever column the package groups by) before pointing it at your orders table.SoftDeletes, the "total" count usually excludes trashed rows while "created per day" includes them historically. Decide which number you want and document it — someone will ask why the two charts disagree.created_at in the database's timezone vs. the app's timezone shifts daily buckets. Set DB_TIMEZONE/APP_TIMEZONE consistently or accept off-by-one-day boundaries at the edges./model-stats clashes with an existing route, change the prefix in config rather than editing the package's routes. Remember route caching (route:cache) after changes.vendor/. If you need custom charts, publish the assets/config, override the route in your own controller, or fork the package — the surface area for extension is small.config:clear? (3) is the middleware blocking you? (4) were assets published? (5) is the table actually populated? Ninety percent of "it doesn't work" reports resolve to one of these five.How can I help you explore Laravel packages today?