Production checklist
Collected from integrating the package into live projects. Each item is a decision — not every app needs all of them.
Before deploying
Section titled “Before deploying”- Dashboard behind auth —
dashboard.middlewarewithauthand a gate (Dashboard) - Whoami decided — keep it public with the throttle, protect it with
whoami.middleware, orwhoami.enabled = false(Whoami) - Queue worker processes
visits.queue(below) - Scheduler runs
schedule:runevery minute;visits:prune --forcescheduled if you want retention (Rollups) - Real client IPs — behind a load balancer, CDN or Cloudflare configure Laravel’s trusted proxies; otherwise every visit has the proxy’s IP and geo
- Geo provider — the default HTTP chain makes one external request per uncached IP; MaxMind GeoLite2 is local (Geo)
- Office IPs in
exclude_ips -
exclude_pathscovers non-page routes of your app (Livewire, file downloads, health checks, admin) - Full-page cache —
Set-Cookieignored by the cache, beacon on cached pages (Client integration) - Shared cache store on several servers — geo results and the visitor budget use the default cache store
Migrations
Section titled “Migrations”php artisan migrate runs the package migrations together with the app’s. In a project with unrelated pending or broken migrations, run only the package’s:
php artisan migrate --path=vendor/fomvasss/laravel-visits/database/migrationsA dedicated queue
Section titled “A dedicated queue”RecordVisitJob runs for every page view — the highest-volume, lowest-priority job in most apps. Give it its own queue so a traffic spike doesn’t delay emails or payments:
VISITS_QUEUE=visitsWith Horizon, a small supervisor of its own:
'defaults' => [ // ... 'supervisor-visits' => [ 'connection' => 'redis', 'queue' => ['visits'], 'balance' => 'auto', 'maxProcesses' => 2, 'memory' => 128, 'tries' => 1, 'timeout' => 30, ],],tries => 1: a retry of an analytics job is worth little, and a job that failed after writing the event would record it twice. The job usually takes milliseconds; the slow part is an uncached geo lookup over HTTP (3-second timeouts per provider in stevebauman/location’s default config, times the fallbacks).
Horizon reads supervisors at start — restart it after the change.
Identity on token APIs
Section titled “Identity on token APIs”- User model uses
HasVisits— logged-in users of a Bearer-token API reconnect to their visitor (Visitor identity) - Logins that issue tokens without
Auth::login()dispatchLoginthemselves; guest checkouts callVisits::identify()(Visitor identity) -
collect.middlewarefits the clients:['web']for same-origin Blade,['api']for SPAs on other origins and mobile apps,['web']plus a CSRF exception for both (Client integration)
Minimal tracking on a busy site
Section titled “Minimal tracking on a busy site”If you need attribution and conversions rather than a page-view trail:
'page_views' => 'first_only',Plus explicit Visits::track() calls at the points that matter — lead form, order placed, payment confirmed (with inheritFrom in the webhook). See Page views and Custom events.
“I don’t see any visits”
Section titled ““I don’t see any visits””-
Is a worker running?
RecordVisitJobwaiting in the queue looks exactly like no tracking. Checkqueue:failedtoo. -
Is
TrackVisitin thewebgroup?Terminal window php artisan tinker --execute="var_dump(in_array(\Fomvasss\Visits\Http\Middleware\TrackVisit::class, app('router')->getMiddlewareGroups()['web'] ?? [], true));"On versions before 0.9.2 the registration could be lost on Laravel 11+ apps configured through
bootstrap/app.php— upgrade. -
Is the path excluded?
exclude_paths, the dashboard path itself, non-GETrequests and missing consent are all skipped silently. -
Is it a bot? Bot rows are hidden by default; the Sessions list has Include bots.
-
Is the IP excluded or over the budget?
exclude_ipsandrate_limit.visitor_budgetdrop events without a trace — a load test from one machine with one visitor id hits the budget fast. -
Overview empty, lists not? Overview reads rollups — run
visits:aggregateor wait for the scheduler. -
Demo data mixed in?
visits:seed-demorows useexample.testURLs.
Pre-1.0 versions
Section titled “Pre-1.0 versions”The package is 0.x. Composer’s caret on 0.x does not cross minor versions: ^0.11 allows 0.11.* only. Raise the constraint by hand to pick up a new minor version, and read Upgrading first.