Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Users Online Laravel Package

highideas/laravel-users-online

Track which users are online in your Laravel app with this lightweight package. It records activity via cache or database drivers, lets you check online status, list active users, and configure timeouts, with simple helper methods and Blade-friendly access.

View on GitHub
Deep Wiki
Context7

Getting Started

This package adds lightweight "who's online" tracking to a Laravel app: a middleware stamps activity for the current user (or session), and a small query layer lets you count or list users seen within a configurable time window. It is a small, single-purpose package — you should be able to read the whole src/ directory in ten minutes, which is the first thing to do given its age.

Minimal path:

  1. composer require highideas/laravel-users-online
  2. Publish and inspect what it gives you: php artisan vendor:publish --provider="HighIdeas\UsersOnline\UsersOnlineServiceProvider" (confirm the exact provider namespace from composer.json / src/ — the publish output tells you the real config and migration filenames).
  3. php artisan migrate for the tracking table (typically something like users_online keyed by user/session with a updated_at-style timestamp).
  4. Register the middleware. On Laravel ≤10 add the alias to app/Http/Kernel.php and attach it to the web group; on Laravel 11+ append it in bootstrap/app.php via $middleware->web(append: [...]).
  5. Render the count somewhere: a dashboard card, an admin "online now" panel, or a navbar badge.

First use case to target: a read-only admin widget ("12 users online") on your existing dashboard. It is the lowest-risk integration, it validates that the middleware is actually firing, and it does not touch any user-facing request path. Once that number moves, you understand the package well enough to build anything else on it.

Where to look first, in order: the published config file (window/minutes, guard, table name), the middleware (what it writes and when — handle vs terminate), the migration (indexes and column types), and finally the facade/model you'll query from your controllers.

Implementation Patterns

Attach the middleware narrowly at first. Put it on the web group only after you've confirmed behaviour, and consider running it on an explicit route group instead while evaluating. Every request through the group performs a write or an upsert — that cost should be a deliberate decision, not a side effect of the default web group.

Exclude noisy routes. Health checks, asset routes, webhook endpoints, and the login/register pages are either unauthenticated or high-frequency. Use ->withoutMiddleware(...) on those routes or scope the middleware to an authenticated group so you aren't writing a row per ping.

Cache the count, don't query per render. The count is a "good enough" figure, not a ledger. Wrap it in Cache::remember('users_online_count', 30, fn () => ...) and accept up to 30s of staleness — this turns a per-page-view aggregate query into one query per 30 seconds across the whole app.

Polling is the pragmatic real-time option. For a live counter, setInterval + a tiny JSON endpoint returning { count: n } is fine and avoids broadcasting infrastructure. If you already run Laravel Echo, push the count on a UserActivity event instead — but don't add broadcasting just for this.

Multi-guard awareness. If you have admin and web guards, decide explicitly which guard's users the package tracks. Most simple "online" packages assume the default guard; if you need both, run two instances of the middleware with different config or fall back to tracking sessions rather than users.

Prune on a schedule. Add a scheduled command (or a model prune call) to delete rows older than a few times your online window — e.g. ->dailyAt('03:00') removing anything older than 7 days. Without pruning the table grows monotonically, which is the most common way this kind of package becomes a problem six months in.

Separate "online" from "active". online is a state (seen in the last N minutes); activity logging is a different concern. If you need "last seen 3 days ago" or audit trails, use spatie/laravel-activitylog or a last_seen_at column on users rather than stretching this package.

Testing pattern. In feature tests, hit a route with actingAs($user), then assert against the package's query layer. Because tracking is time-window based, use $this->travelTo() / Carbon::setTestNow() to verify that a user falls out of the online window rather than relying on sleeps.

Extension point. If the bundled model doesn't fit, most of these packages let you point a config key at your own model class or subclass theirs. That is the cheapest way to add scopes (scopeOnline, scopeForGuard) without forking.

Gotchas and Tips

It is unmaintained — treat it as a code sample. Last release was October 2019, which predates Laravel 8+. Expect friction on modern versions: string-based model $dates/$casts, Kernel.php-only middleware registration, and possibly a service provider that doesn't declare mergeConfigFrom. Before installing, check the composer.json illuminate/support constraint against your framework version. If it doesn't fit, the honest move is to read the middleware and reimplement it in ~40 lines with a last_seen_at cache entry — you get the same feature with none of the dead-code risk.

Silent failure is the default failure mode. If the middleware isn't registered, isn't on the right route group, or is short-circuited by an earlier middleware, the count is just 0 — no error, no warning. Verify with php artisan route:list -v that the middleware is actually attached, and temporarily dd() inside the middleware once during setup.

Config cache will bite you. After php artisan config:cache, edits to the published config are invisible. If changing the online window "does nothing", run php artisan config:clear first.

Timezone and window semantics. "Online in the last 5 minutes" depends on whether timestamps are stored in UTC (Laravel default) and compared with now(). If you see users never appearing online, or everyone always online, inspect the raw timestamp in the table before assuming the config window is wrong.

Middleware ordering matters. If your auth middleware runs after this one, Auth::user() is null and the package silently tracks sessions/guests instead of users. Put the tracking middleware after StartSession and Authenticate in the group.

Terminable vs inline writes. If the package uses terminate(), the write happens after the response is sent — meaning your test assertions can run before the row exists. Call $kernel->terminate($request, $response) in tests, or assert with assertDatabaseHas after a full request cycle.

Guests and bots inflate the number. Unauthenticated tracking counts crawlers as "online". For a meaningful dashboard, combine with the auth guard or filter on user agent; otherwise your "users online" is really "requests in flight".

Don't build permission logic on it. The online list is eventually-consistent and trivially stale. Never use it to gate access, allocate work, or make billing decisions — it's a display metric.

Fork-readiness. Because the surface area is tiny, keep all your call sites behind a single service class or view composer (e.g. OnlineUsers::count()), so that swapping the package for a roll-your-own implementation later is a one-file change rather than a codebase-wide search.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core