The Exp Debug bar
This page is for developers and administrators who debug a page: slow, wrong, or full of warnings. The classic debug report at the bottom of a page became a pinned bar with tabs, a live summary, and controls for the debug settings and the caches, so you can switch debugging on, look, and switch it off again without opening an INI file. Added 2026-10-02. Reference with every server function and test: debug bar guide.
Switch it on for yourself only
In settings/override/site.ini.append.php, show the debug output only to your own address (see the switches at the
end of this page):
[DebugSettings]
DebugOutput=enabled
DebugByIP=enabled
DebugIPList[]=203.0.113.10Clear the INI cache (php bin/php/ezcache.php --clear-tag=ini --allow-root-user) and reload a page: the bar is pinned
at the bottom.
What you see
- The pinned bar shows page time, SQL count and time, peak memory, templates used, warnings and errors (amber or
red past the thresholds). With the SQL query cache on it also shows the cache's hit rate and the database time it
saved for the request, also in percent of the page's time (
QC 83 % · -186 ms (186 %): a page of 100 ms would have taken about 286 ms without the cache); the SQL count beside it counts only what reached the database. Each value opens its tab. The title "Exp Debug" and the logo sit at the right end, the page summary on the left. - The panel above the bar (60% of the window by default, scrolling on its own) has the tabs Messages, Settings, Cache, Timing, SQL, Templates, Included files, Memory, Rendering, User and Server. Every section of the classic report is still there with its old id.
- Resize the panel: drag the strip on the panel's top edge (mouse, pen or touch), or focus it and use the arrow
keys (16 px, with Shift 64 px; Home and End for the lowest and highest). A double-click gives the default height
back. The height stays between 120 px and the window's height minus the bar, and is remembered per user in the
preference
expdebugbar_panel_height, so the panel opens at that height on the next page and in another browser. Without logging in (the bar shown by IP) the height is kept in the browser (localStoragekeyexp-debug-panel-height), never in a session. Details: The panel's height. - Copy Messages on the Messages tab copies the messages that are shown (the level buttons and the filter box applied) to the clipboard as plain text: per entry a line "Level: source", a tab and the time, then the message, with a blank line between entries. It uses the browser's clipboard and, where that is not available (a page on plain http), a hidden text field; a line next to the button says how many messages were copied or that the copy failed.
- Minimise: click the Exponential symbol at the left end (or press Enter or Space on it) and the whole bar becomes a 40 px tab in the bottom right corner showing only the symbol and the error count.
- Keep open on reload (short "Keep open" in the bar, the whole words as its tooltip): the bar remembers whether it was open (browser
localStoragekeysexp-debug-keepandexp-debug-open); unticked, the details start closed on each page. - Readable in light and dark mode; no empty strip under the copyright any more.
Change settings from the bar
The Settings tab reads and changes every debug setting per scope, logs each change and can undo it. The
kernel registers 35 settings in nine groups (debug output, who gets debug, templates, database, translations,
mail, debug conditions, caching, extensions); settings/debugbar.ini describes them and four presets
(Template work, SQL tuning, Everything, Off). Extensions add settings with their own debugbar.ini blocks, and
the debug conditions of debug.ini are discovered automatically.
The Cache tab lists the caches and clears them through the cache manager, showing when each was last cleared (or "never").
The bar starts with the request: its HTTP status and module/view, green, amber for a redirect, red from status 400; it opens the Rendering tab, which starts with an overview (module view, view cache, cache blocks, templates) and shows its parts as sub-tabs: controller, template tree, content view cache, cache blocks and templates.
The User tab (chip <login> · VC <profile>, with a person icon) opens with an overview of the user and has four
sub-tabs (cache profile, preferences, roles and policies, session). It shows the user's cache profile, the fingerprint of the parts of the content view
cache key that depend on the user, so two users can tell whether they share the cached views; their preferences and
role assignments with links to the roles; and, in a section loaded only when it is opened, the
policies of those roles, a page at a time, by role and by search (content/read also finds the wildcards that grant
it), with classes, sections, siteaccesses and nodes by name; and the user's own PHP session as a table, loaded when
its sub-tab is shown, secrets masked, grouped by extension, searchable. The tab, as the Rendering tab, is for whoever gets the
debug output, logged in or not, and for setup/setup; whoever gets the debug output also reads the settings, the
cache list, OPcache and APCu, but changes nothing without the policies (debugbar.ini ReadAccess, privileged for
the stricter rule)
(details).
Who may use it
Whoever gets the debug report reads everything the bar shows, by default: the settings with file paths, the change
log, the IP test, the cache list, the policies of their roles, OPcache and APCu. Changing a setting needs the policy
setup/setup, clearing a cache setup/managecache, both with the form token. debugbar.ini [DebugBarSettings] ReadAccess=privileged keeps the reading to those policies too, the stricter rule; a site that gives
the debug report to visitors it does not trust with its configuration sets it
(details). Nobody reads other people's data: the session is
always the visitor's own, the change log comes without who made each change and the IP and user lists are masked for
a reader without setup/setup. Debug output on a public address shows every visitor their own session: set
ReadAccess=privileged in production.
Settings
| File | Block | Key | Default | Scope |
|---|---|---|---|---|
settings/debugbar.ini | DebugBarSettings | Settings[] | the 35 kernel settings | installation |
settings/debugbar.ini | Setting_<id> | File, Block, Variable, Type, Label, Group, Help | per setting | installation |
settings/debugbar.ini | Preset_<id> | Name, setting values | four presets | installation |
The classic debug block: heading, section ids and phone-sized output (6.0.7)
The classic debug output (the block at the bottom of a page when debugging is on) became easier to use in January 2025 (release 6.0.7) without changing what it reports. The debug bar above builds on it: every section of the classic report keeps the ids listed here.
What changed
The heading tells you why you see debug. The heading of the block now names the switch that enabled it:
(By User)when[DebugSettings] DebugByUseris on,(By IP Address)whenDebugByIPis on. On a shared team server you see at once that the output is only for you and not for every visitor.Every section has an id. Each part of the block is wrapped in a
divwith a stable id, so a stylesheet can hide, reorder or restyle it:Id Section main-debug-tablethe table of notices, warnings and errors main-resources"Main resources" (time, memory) timing-points"Timing points" time-accumulators"Time accumulators" included-files"Included files" (inner table debug_includes)ezjscpackerusagecontainerthe CSS and JS files loaded through the packer (from the ezjscoreextension)A responsive stylesheet.
design/standard/stylesheets/debug.csslets the block scroll inside the page (#debug { overflow: auto; }) and wrap its content, so debugging on a phone or a narrow window does not widen the page.
Examples
Show only the error table and the timing, hide the rest:
#debug #main-resources,
#debug #time-accumulators,
#debug #included-files,
#debug #ezjscpackerusagecontainer { display: none; }Move the timing points above the error table (when #debug is a flex
container):
#debug { display: flex; flex-direction: column; }
#debug #timing-points { order: -1; }Add the rules to a stylesheet of your design extension.
The switches (reminder)
All in settings/site.ini, block [DebugSettings]:
| Key | Default | Meaning |
|---|---|---|
DebugOutput | disabled | Master switch. Nothing is shown when disabled. |
DebugByIP | disabled | When enabled only the addresses in DebugIPList[] get the output. |
DebugIPList[] | empty | Addresses or networks (192.0.0.0/27). |
DebugByUser | disabled | When enabled only the user ids in DebugUserIDList[] get the output. |
DebugUserIDList[] | empty | User (content object) ids. |
ScriptDebugOutput | disabled | Output for scripts. |
AlwaysLog[] | error | Debug types always written to the log, with or without output. |
Never enable DebugOutput for everybody on a production site: the block shows
SQL, file names and settings. Use DebugByIP or DebugByUser.
Related pages
- Debug bar guide, runnable classes
- The INI command (same editor class), the audit trail (setting changes are audited), template path comments
- Upgrade checklist of 1-2 October 2026
- Changelogs: 6.0.4, 6.0.7, 6.0.10, 6.0.15
- History: October 2026, August 2025, January 2025 (heading and ids, 6.0.7), August 2024 (responsive block, 6.0.4)
Become an Exponential Partner
Partners share their information, provide funding, contribute back and develop the products with us, and that is how Exponential grows. A partner website and dashboard are planned for mid-2027: please become a partner today to speed up our growth rate and land new features faster.