Using Devel's Webprofiler for Performance Analysisfor Drupal 11 , 10 , 9 , and 8

Last updated :  

The previous lesson introduced Webprofiler as a tool for finding which module costs you time. This lesson goes deeper into the toolbar itself — the specific panels it exposes, and how to read each one correctly, since a profiler you don't know how to interrogate properly is barely more useful than not having one.

What you'll learn in this lesson

  • The panels Webprofiler's toolbar actually exposes, one by one
  • How to drill from the toolbar into a full request profile
  • Comparing two requests to isolate what changed

The toolbar panels

  • Time: total request time, broken into initialization vs. actual controller execution — a large "initialization" share often points at too many enabled modules rather than anything your own code did.
  • Database: every query executed, with individual timing and the exact SQL — including duplicate queries, flagged explicitly so N+1 patterns jump out visually rather than requiring manual counting.
  • Cache: hit/miss counts per cache bin — a bin showing mostly misses under normal repeat traffic is a real signal something's preventing that data from caching correctly.
  • Services: which services got instantiated on this request — useful for spotting an unexpectedly-constructed expensive service, exactly the kind of case the previous section's lazy-services lesson addressed.

Drilling into a full profile

# Every profiled request gets a token; view its full detail page directly:
# /admin/reports/profiler/{token}
# The toolbar itself links straight to this for the current page's own request.

The toolbar is a compact summary; the full profile page behind it shows the complete data — every query's exact SQL and calling location, every service's full construction chain, timeline data down to individual milliseconds.

Compare two profiles, don't just read one in isolation. A single profile tells you what happened on one request — it doesn't tell you whether that's normal or a regression. Profile the same page before and after a code change (or against a known-good deploy) and diff the query counts and timings directly; that comparison is often far more informative than either profile read alone.

A concrete reading exercise

A profile showing 45 total queries, 40 of them identical except for one ID parameter, each taking 2-3ms: individually each query looks harmless (2-3ms is fast!) — but the Database panel's duplicate-query count is the signal that matters here, not any single query's speed. This is exactly the N+1 pattern from the previous lesson, and it's precisely what the duplicate-count feature exists to make visually obvious rather than something you'd have to notice by scrolling through 45 nearly-identical rows.

Quick check: the Services panel shows a service you didn't expect got constructed on a page that shouldn't need it. What earlier lesson's technique is the likely fix, once you confirm it's genuinely expensive and rarely used? If you said marking it lazy: true, you've connected this lesson's diagnostic tool back to the previous section's actual fix correctly.

Key takeaways

  • Webprofiler's toolbar panels (Time, Database, Cache, Services) each answer a different diagnostic question — know which one to check first for a given symptom.
  • The Database panel explicitly flags duplicate queries — the fastest way to spot an N+1 pattern without manual counting.
  • Drill from the toolbar into the full /admin/reports/profiler/{token} page for complete detail on any specific request.
  • Compare profiles before/after a change rather than reading one in isolation — a single profile can't tell you whether what you're seeing is normal.

Coming up next

You've now got real request-level visibility into time, memory, and services. Next, we go one layer deeper on the query side specifically — using Devel to log and analyze every database query a request makes.