Skip to content

Why is this page slow? One-page inspection for a Laravel site ​

The complaint never comes as "the site is slow". It comes as "the category page is slow", or "the home page takes two seconds since Tuesday". You have Pulse, Telescope or Debugbar, and each of them answers a different question. Pulse says which requests were slow over the last hour, averaged over everyone. Telescope records every request, and finding the one you mean is a search. Debugbar shows the queries of the page you are on — in development, where the data is small and the page is fast.

What the complaint asks for is simpler: draw this one page once, as a visitor would get it, and tell me everything it did. Which template drew it. Every query it ran, with its time. Which queries ran twice. Whether the cache would have kept it, and if not, why. kitloom has that now, for one address, in three places.

Ask an agent first ​

The fastest way to use it is not to open anything. An agent connected through kitloom/ai has the site_inspect_page tool, as the user whose key it holds:

"Why is /category/dried-fruit/ slow?"

The agent draws the page, reads the inspection and answers in words — say, forty-one queries in thirty milliseconds, one of them run eight times with different ids, the product images read per product instead of for the list, and the page not cached because the address carries a sort parameter nobody declared. Then it can look at the module that runs the query, or clear the cache with site_cache_clear, with exactly the rights its key gives it. The tool reads only; it needs manage_options, as the Cache settings do.

In the admin bar ​

For a person, the same report sits on the page itself. Once Admin Bar → Settings → Show Inspect in the bar is on, every page of the site shows Inspect in the toolbar to users who manage the site's settings. A click draws the page once more and opens a panel under the bar:

  • Template — the file of the theme that drew the page, and the candidates it was chosen from, most specific first, the way WordPress's template hierarchy orders them (single-post-reading-middlemarch-slowly, single-post, single, singular, index).
  • Queries — how many, in how long. Exact duplicates first: the same SQL with the same values run more than once, something read twice that could have been read once. Then repeated with other values: the same SQL once per row, the N+1 that a list of posts makes when each one reads its own terms. Then the five slowest.
  • Cache — whether a guest's copy of this address would be kept and, when not, why: the cache is off, the address has a query parameter nobody declared, a module keeps the request out. And whether a copy is in the cache right now.
  • Timing — the main query on its own, then the whole page, with peak memory.
Inspect switched on, the panel on the home page: template, queries, duplicates and repeats, cache, timing

It is off until the owner switches it on: a click draws a page, and nobody should be able to ask a server for that by default. Guests never see it, and a page the cache keeps never carries it, because the bar is not cached either.

From the console ​

On a server, or in a script before a deploy:

bash
php artisan kitloom:inspect /category/dried-fruit/
php artisan kitloom:inspect /account/ --as=edith     # as a user: a login, an email or an id
php artisan kitloom:inspect / --json                  # the whole inspection as data

The report prints the same sections, the queries sorted by time with the duplicates and repeats in tables of their own, and the dependency keys the page read — the rows and lists the page cache would keep it with, which is how you find out that a page depends on a whole table when it should depend on one row.

Why not Debugbar in production ​

Laravel Debugbar answers the same question for a developer: open the page, read its queries. The reason it stays off in production is not that it could not run there. It collects on every request, for everyone, and writes itself into every response — a cost on every page and, if the gate is ever misconfigured, the site's SQL on a public page. So it is switched off where the slow page actually is, with the real data, the real cache and the real traffic.

The inspector turns that around. Nothing is collected until someone asks: the listener the page cache already has hands statements to a collector only while an inspection runs, and the rest of the time costs nothing. It draws the one address asked for, as the user who asked, and changes nothing in what visitors get — the page is drawn for the report, not served. Only a user who manages the site's settings can ask, only once the owner switched it on, with a throttle on the route. Nothing is stored. That is what lets it live on the production site, where the question comes up.

It also knows things a generic bar does not: the template hierarchy the page was chosen from, the main query's result, and the page cache's verdict with the keys it would keep the page with — and it answers the console and an agent in the same shape as the panel.

How it is built, in short ​

The inspector lives in the core of the site, next to the page cache, because that is where the pieces already are. The page cache listens to every QueryExecuted event to learn what a page read; while an inspection runs, the same listener hands each statement to a per-request collector, with its SQL, bindings, time and the tables it touched, as the cache's own parser reads them. The address is drawn through the same Site::render() the console and the agents use, with the same visibility rules as the request would have — a draft is a 404 for a visitor and a page for its editor. Then the main query is asked on its own, for what it found and how long it takes alone. Nothing is stored, no new table, no dependency: a collector, a grouping, a DTO.

Pulse still answers for the site over time, and Telescope still records everything. This answers the question as it is asked: this page, now.

Try it ​

Open a sandbox in one click, with no sign-up: Filament or Nova. The setting and the route are in the Admin Bar guide; the command, the tool and what each section means are in the site package's "Inspecting a page".

Last updated:

kitloom — modules and themes for Laravel.
Contact · Pricing · Services · License · Refunds · Privacy · Community · YouTube · [email protected]