Appearance
Top
Live metrics in the terminal: requests, queries and cache per second, the busiest pages, right now — php artisan top.
kitloom/top · admins: kitloom/top-filament, kitloom/top-nova
Video lessons
Recorded in the Filament admin; the Nova admin works the same way.
php artisan top on a kitloom site: the terminal screen of Laravel Top (leventcz/laravel-top, MIT), which shows what the site is doing right now — requests, database queries and cache operations per second, how long a request takes and how much memory it uses, and the busiest pages — the way the top command of a server shows its processes. The figures are averages over the last five seconds and refresh every second while you watch; nothing is kept.
This module brings Top in and makes it fit a kitloom site: the site's pages are listed by their template instead of the one route every page shares, a site without Redis still boots and says what is missing, administrators get a Live screen in the Filament admin and AI agents a reading of the load. The admin section is kitloom/top-filament or kitloom/top-nova.
Top, Pulse, Telescope, the page inspector
| Tool | What it shows | Use it for |
|---|---|---|
| Top | The last five seconds, live, in the terminal: requests, queries and cache per second, the busiest pages | "What is the site doing right now?" — during a traffic spike, after a deploy, while a campaign runs |
| Pulse | Totals and averages over hours and days: slowest pages, queries, jobs, servers | How the site does in general |
| Telescope | Every recorded request, query, job and exception, one by one | Why one thing went wrong or was slow |
php artisan kitloom:inspect <url> | One page: its queries, what it read, why it is slow | Making one page faster |
Top sees only HTTP requests: queue jobs and console commands are not counted.
What it needs
| Why | |
|---|---|
Redis, and the phpredis extension (or the predis/predis package, with REDIS_CLIENT=predis) | Top keeps its counters there for a few seconds. They are shared, so the screen shows every server of the site, not only the one you run the command on |
The pcntl PHP extension in the console | The screen is drawn by php artisan top, which needs it to leave the terminal clean when you press Ctrl+C. Every Linux build of PHP has it |
Top uses the site's default Redis connection (REDIS_HOST, REDIS_PORT, REDIS_PASSWORD in .env); TOP_REDIS_CONNECTION names another connection of config/database.php.
Without Redis the site works as before: the module's badge in the admin says no Redis client or Redis is down with what to do, and php artisan top says the same instead of failing.
Watching the site
On a server of the site:
bash
php artisan topThe screen has three boxes and a table:
| What | |
|---|---|
| HTTP | Requests per second, the average time a request took (ms), the average peak memory of a request (MB) |
| Database | Queries per second, the average time the queries of one request took (ms) |
| Cache | Cache hits, misses and writes per second |
| Routes | The twenty busiest, each with its method, name, requests per second, memory and duration |
Press Ctrl+C to stop. Top records only while someone watches: when no top runs and the admin's Live screen is closed, a request costs one Redis EXISTS and nothing more.
Pages by template
Every page of a kitloom site goes through one route, so Top itself would show the whole site as one line. The module names each request of a page by the template it resolved to, as Pulse names its slow pages:
| Name | The page |
|---|---|
front-page | The home page |
home | The posts page, when the home page is a static page |
single-post, single-book, single-product … | One record of the type |
page | A page |
category, tag, taxonomy-genre … | A term's archive |
archive-book … | A post type's archive |
author, date, search | Those archives and the search results |
404 | Nothing found |
cached page | A page the page cache answered: no template was resolved |
The admin's screens and the site's own routes (/admin/posts/{record}/edit, /livewire/update, /login, /wp-json/…) keep Top's own name, their route. name_pages: false in the configuration leaves everything to Top.
In the admin
The Top section of each admin shows whether the site can record for Top:
| Badge | Meaning |
|---|---|
| ready | Redis answers; run php artisan top to watch |
| watching | Someone runs php artisan top or has the Live screen open: every request records its metrics |
| no Redis client | REDIS_CLIENT names a client that is not installed |
| Redis is down | The connection does not answer; the tooltip says which and why |
The Filament admin has a Live screen under Top: the same figures and the same table, refreshed every two seconds while it is open — for whoever has no terminal at hand. In Nova the live screen is the terminal.
Permission: view_top opens the Live screen, the admin section and the agents' tool. Administrators have it; the terminal itself asks nobody.
For AI agents
With kitloom/ai installed, an agent whose user has view_top gets top_snapshot: one reading of what Top shows — requests, queries and cache per second, the busiest pages by template. The tool turns recording on, waits the five seconds Top averages over, and reads, so a call takes about five seconds. Off with ai.register in the configuration.
Configuration
php artisan vendor:publish --tag=kitloom-top-config writes config/kitloom-top.php:
| Key | Default | What |
|---|---|---|
name_pages | true | The site's pages by their template; false — Top's own names, the route |
ai.register | true | The top_snapshot tool for agents |
filament.register, nova.register | true | The Top section of each admin |
Top's own config/top.php (php artisan vendor:publish --tag=top) keeps the Redis connection and the recording mode: TOP_RECORDING_MODE=always records every request whether or not someone watches, for an application that reads the Top facade itself.
Deactivating
Deactivating Top on the Modules screen also stops loading leventcz/laravel-top (unless the application requires it in its own composer.json): the top command and its listeners go with the module. Nothing stays behind: the counters in Redis expire by themselves within ten seconds.
For developers
Kitloom\Top\TopRepository(singleton) wraps Top'sLeventcz\Top\Contracts\Repository: it names the page before saving, makes the Redis repository on first use, and turns every Redis failure intoKitloom\Top\TopUnavailable— except insave()andrecorderExists(), where a request never fails for its metrics.Kitloom\Top\PageName(scoped) is the request's name: it listens to the site'sMainQueryResolvedandPageNotFound, and toRequestHandledfor the page cache'sX-Site-Cache: hit.Kitloom\Top\TopStatus(scoped) is what the admins show:status()(ready,recording,unavailable),label(),tone(),explanation(),allows($user).- Tests without Redis:
Kitloom\Top\Testing\WatchesWithFakeTopputsKitloom\Top\Testing\FakeTopRepositorybehind the module's repository and subscribes Top's listeners, which Top does not subscribe under a console.