laravel-glimpse maintained by pascalkleindienst
⚡ Glimpse Analytics
Privacy-first, server-side analytics for Laravel 12+.
No cookies. No JavaScript tracking pixel. No GDPR consent banners.
Just clean, fast, anonymous analytics built entirely on the server.
Features
- Zero client-side footprint — tracking is 100% server-side via a Laravel middleware
- Session-based unique visitors — derived from Laravel's existing session ID (SHA-256 hashed, never stored raw)
- No PII stored — IPs are one-way hashed with your app key; no names, emails, or identifiers
- Cookie-free — no new cookies introduced; uses the session cookie your app already sets
- Livewire dashboard — a Pulse-style real-time dashboard at
/glimpse - Custom events —
Glimpse::event('checkout', ['plan' => 'pro']) - GeoIP — country, region, city, language (MaxMind or SxGeo, optional)
- Device detection — browser, OS, platform (desktop/mobile/tablet)
- Referrer classification — organic, social, paid, email, referral, direct
- Pre-aggregated — dashboard queries never touch raw tables; fast at any scale
- Queue-driven — zero latency added to your requests
Requirements
| Dependency | Version |
|---|---|
| PHP | ^8.4|^8.5 |
| Laravel | ^12.0|^13.0 |
| Livewire | ^3.6.4|^4.0 |
Installation
composer require pascalkleindienst/laravel-glimpse
php artisan glimpse:install
glimpse:install will:
- Publish
config/glimpse.php - Publish and run the database migrations
- Inject
TrackVisitormiddleware intobootstrap/app.php - Run a health check and print next steps
Quick Start
1. Register the middleware
The install command does this automatically. If you need to do it manually, add to bootstrap/app.php:
->withMiddleware(function (Middleware $middleware) {
$middleware->web(append: [
\LaravelGlimpse\Http\Middleware\TrackVisitor::class,
]);
})
2. Start the queue worker
Glimpse dispatches a queued job per request so tracking adds zero latency:
php artisan queue:work
3. Enable the scheduler
Add to your crontab (or use Laravel's built-in scheduler):
* * * * * php /path/to/your/app/artisan schedule:run >> /dev/null 2>&1
Glimpse auto-registers two scheduled commands:
glimpse:aggregate— every 5 minutes (aggregates raw data)glimpse:prune— daily at 03:00 (deletes data beyond the retention window)
4. Open the dashboard
https://your-app.com/glimpse
Configuration
Publish the config file:
php artisan vendor:publish --tag=glimpse-config
GeoIP Setup
Geo resolution is disabled by default (driver = null). To enable:
MaxMind GeoLite2 (recommended)
- Sign up for a free MaxMind account and download
GeoLite2-City.mmdb - Place the file at
storage/app/glimpse/GeoLite2-City.mmdb - Set in
.env:
GLIMPSE_GEO_DRIVER=maxmind
GLIMPSE_MAXMIND_DB=/absolute/path/to/GeoLite2-City.mmdb
SypexGeo (no sign-up required)
- Download
SxGeoCity.datandSxGeo.phpfrom sypexgeo.net - Place both files at
storage/app/glimpse/ - Set in
.env:
GLIMPSE_GEO_DRIVER=sxgeo
Artisan Commands
| Command | Description |
|---|---|
glimpse:install |
Install Glimpse (publish, migrate, wire middleware) |
glimpse:aggregate |
Roll raw data into aggregate buckets (auto-scheduled) |
glimpse:prune |
Delete data beyond retention window (auto-scheduled) |
glimpse:backfill |
Re-aggregate a historical date range |
Backfill historical data
# Backfill the last 90 days
php artisan glimpse:backfill --days=90
# Backfill a specific range
php artisan glimpse:backfill --from=2024-01-01 --to=2024-03-31
# Process in smaller chunks to limit memory usage
php artisan glimpse:backfill --days=365 --chunk=7
How It Works
Session identity
On every request the TrackVisitor middleware computes:
session_hash = SHA-256(laravel_session_id)
This is stored as the visitor identity. The raw session ID is never persisted. When the session expires (default 2 hours in Laravel), so does the identity — genuinely ephemeral.
Request lifecycle
HTTP Request
│
├─ TrackVisitor middleware (sync — reads cache only)
│ └─ Dispatch ProcessVisitJob to queue
│
└─ Response returned immediately ← zero DB writes in the request
Queue worker (async)
└─ ProcessVisitJob
├─ GeoResolver (IP → country/city)
├─ DeviceResolver (UA → browser/OS/platform)
|- LanguageResolver (Accept-Language Header → language)
├─ ReferrerResolver (referer → channel)
└─ Write to glimpse_sessions + glimpse_page_views
Aggregation
Every 5 minutes, glimpse:aggregate reads raw rows and upserts pre-computed buckets into glimpse_aggregates. The
dashboard only reads from glimpse_aggregates — it never queries raw tables, so it's fast at any volume.
Privacy
Glimpse is designed to be GDPR/ePrivacy compliant by default:
- No cookies introduced — uses the session cookie already set by Laravel
- No PII stored — IPs are one-way hashed (SHA-256 + app key) before storage
- No third-party requests — all data stays on your server
- No cross-site tracking — identifiers are session-scoped
- No fingerprinting — User-Agent is parsed but never stored
Legal note: Glimpse minimizes data collection but you are responsible for your own compliance. Consult a legal professional for advice specific to your jurisdiction.
Testing
composer test
License
MIT — see LICENSE.