Title: Dragon Speed Doctor &#8211; Find What Slows Your Site Down
Author: Dragon Core
Published: <strong>September 18, 2026</strong>
Last modified: October 2, 2026

---

Search plugins

![](https://ps.w.org/dragon-speed-doctor/assets/banner-772x250.png?rev=3702091)

![](https://ps.w.org/dragon-speed-doctor/assets/icon-256x256.gif?rev=3711734)

# Dragon Speed Doctor – Find What Slows Your Site Down

 By [Dragon Core](https://profiles.wordpress.org/dragoncoreltd/)

[Download](https://downloads.wordpress.org/plugin/dragon-speed-doctor.1.1.8.zip)

 * [Details](https://test.wordpress.org/plugins/dragon-speed-doctor/#description)
 * [Reviews](https://test.wordpress.org/plugins/dragon-speed-doctor/#reviews)
 *  [Installation](https://test.wordpress.org/plugins/dragon-speed-doctor/#installation)
 * [Development](https://test.wordpress.org/plugins/dragon-speed-doctor/#developers)

 [Support](https://wordpress.org/support/plugin/dragon-speed-doctor/)

## Description

Every slow WordPress site raises the same question: **which plugin is doing this?**
Dragon Speed Doctor answers it with measurements, not guesswork.

Install the measurement loader, press Run diagnosis, and the doctor times your site
over a few minutes of internal test requests, with each plugin briefly left out 
of those test requests only, then tells you what each plugin actually costs:

 * **Per-plugin timing, front-end and wp-admin:** “Adds about 180–260ms to page 
   loads.” Real measured ranges, never invented precision. When results are too 
   noisy to trust, it says so instead of making a number up.
 * **Asset audit:** every script and stylesheet on your pages, attributed to the
   plugin that ships it, with sizes and render-blocking flags. Sometimes a plugin’s
   PHP is fast but it sends 900KB of JavaScript to every visitor, and the doctor
   catches that too.
 * **Database signals:** autoloaded-option weight (a common hidden slowdown) with
   probable owners.
 * **Plain-English verdicts** with Low / Medium / High impact badges, sorted worst
   first, and an Inconclusive badge when the timings cannot support an answer.
 * **Before/after comparison:** run a scan before updating plugins and another after,
   and see what changed. A rolling history of recent scans is kept automatically.
 * **Dependency awareness:** plugins that declare they need another plugin (a WooCommerce
   payment gateway, say) are measured together and labelled honestly; a plugin the
   site cannot run without is reported as “could not be measured”, never as harmless.
 * **WP-CLI**: `wp speed-doctor scan`.

Visitors are never affected: plugin loading is only altered for the doctor’s own
internal, cryptographically signed test requests. Your live traffic always sees 
the site exactly as configured.

#### Features

 * **Per-Plugin Timing** – What each plugin costs on the front end and in wp-admin,
   as honest measured ranges
 * **Asset Audit** – Every script and stylesheet on your pages, attributed to the
   plugin that ships it, with render-blocking flags
 * **Database Signals** – Autoloaded-option weight and probable owners, a common
   hidden slowdown
 * **Plain-English Verdicts** – Low, Medium, High and Inconclusive badges, sorted
   worst first, no jargon
 * **Before & After** – Scan before updating plugins and again after, and see exactly
   what changed
 * **Dependency Awareness** – Plugins that cannot be separated are measured together
   and labelled honestly
 * **Honest Confidence** – Rates a plugin Low only when the top of every measured
   range stays at or below 100ms, never calls a difference smaller than the server’s
   own noise a cost, and says “inconclusive” when the server is too noisy, or when
   a small cost on one page sits next to a page that was not measured, instead of
   inventing a number
 * **WP-CLI** – `wp speed-doctor scan` for scripted or scheduled diagnosis
 * **No External Services** – Everything runs on your own server; nothing is sent
   anywhere

Everything above is free, fully functional and unlimited.

#### How it measures

The method is built for noisy shared hosting: repeated interleaved timings, medians
with confidence bands, warmup passes discarded, early stopping when a result is 
already clear, retries for passing server errors, and honest “inconclusive” verdicts
when server noise wins. Script and stylesheet weight counts towards a plugin’s badge
only for what it loads on front-end pages; wp-admin-only assets are listed on the
Assets tab but never described as shipped to visitors. A pre-scan check verifies
your site can be measured (loopback requests allowed, no page cache serving the 
test requests, no background jobs adding noise) before anything runs.

#### The measurement loader

Timing a plugin’s absence requires briefly loading the site without it, for signed
internal requests only. A small helper file in `mu-plugins` does this. It is installed
only when you click Install loader on the Doctor screen (or run `wp speed-doctor
scan`), shown there with its status, does nothing for any normal request, and is
removed automatically when you deactivate the plugin. Once installed, it is brought
up to date by itself after each plugin update, and a loader you removed stays removed.

#### Dragon Speed Doctor Pro

[Dragon Speed Doctor Pro](https://dragoncore.ltd/plugins/dragon-speed-doctor-pro)
is an optional annual add-on that keeps the doctor running:

 * Scheduled scans, weekly or daily, plus a follow-up scan after every plugin, theme
   or WordPress update.
 * A 12-month performance history with the biggest movers between any two scans.
 * Slowdown alerts by email, Slack or signed webhook, sent only after a second scan
   confirms them, naming what changed.
 * A per-plugin breakdown of the database queries and outgoing HTTP calls behind
   each verdict.

Nothing in this plugin is locked or limited without it.

### External services

None. The doctor measures your site by requesting your own pages from your own server.
Nothing is sent to Dragon Core or any third party. No telemetry, no accounts, no
cloud.

### Credits

The WordPress.org listing icon is drawn with glyphs from Lucide (https://lucide.
dev), ISC License. Copyright (c) for portions of Lucide are held by Cole Bemis 2013-
2022 as part of Feather (https://feathericons.com, MIT License). All other copyright(
c) for Lucide are held by Lucide Contributors 2022. The plugin itself does not include
these icons.

## Screenshots

[⌊The Doctor tab: install the measurement loader, then run a diagnosis. The latest
verdicts are summarised at the top.⌉⌊The Doctor tab: install the measurement loader,
then run a diagnosis. The latest verdicts are summarised at the top.⌉[

The Doctor tab: install the measurement loader, then run a diagnosis. The latest
verdicts are summarised at the top.

[⌊Results: plain-English verdicts with impact badges, worst first. Low-impact plugins
are folded away.⌉⌊Results: plain-English verdicts with impact badges, worst first.
Low-impact plugins are folded away.⌉[

Results: plain-English verdicts with impact badges, worst first. Low-impact plugins
are folded away.

[⌊Assets: what every plugin ships to your pages, with render-blocking counts.⌉⌊Assets:
what every plugin ships to your pages, with render-blocking counts.⌉[

Assets: what every plugin ships to your pages, with render-blocking counts.

[⌊Database: autoloaded option weight and probable owners.⌉⌊Database: autoloaded 
option weight and probable owners.⌉[

Database: autoloaded option weight and probable owners.

[⌊A diagnosis running: preflight checks passed, with live progress and elapsed time.⌉⌊
A diagnosis running: preflight checks passed, with live progress and elapsed time
.⌉[

A diagnosis running: preflight checks passed, with live progress and elapsed time.

## Installation

 1. Upload the `dragon-speed-doctor` folder to `/wp-content/plugins/`, or install via
    the Plugins screen.
 2. Activate the plugin.
 3. Go to Tools  Speed Doctor, install the measurement loader, and run a diagnosis.

## FAQ

### Why is my WordPress site slow?

Usually one of four things: a plugin doing heavy work on every request, a plugin
shipping large scripts to every page, bloated autoloaded options in the database,
or slow hosting. The doctor measures the first three directly and tells you which
plugin is responsible, so you fix the actual cause instead of guessing.

### Is it safe to run on a live site?

Yes, with one caveat. Visitors are never served a modified site. Plugin loading 
changes only for the doctor’s own signed internal requests. The caveat: a scan sends
a few hundred requests to your server over several minutes, which adds load. On 
a busy site, run it at a quiet time, or enable host-safe mode in Settings to slow
it down further.

### How is this different from Query Monitor?

Query Monitor is a superb developer tool that inspects the current request in deep
technical detail. The doctor answers a different question, namely which plugin to
blame, by measuring whole pages with and without each plugin, and it answers in 
sentences rather than stack traces. Many people will want both.

### Is this a profiler?

Not in the function-call sense. It does not hook into PHP or list which functions
ran. It measures whole page loads with and without each plugin, so the result is
a per-plugin cost in milliseconds rather than a call tree. The asset and database
audits are separate, single-pass checks.

### Why is a plugin measured together with others?

Some plugins fatal when a plugin they depend on is missing, such as a WooCommerce
extension without WooCommerce. When a plugin declares that dependency, the doctor
measures the group as a whole, and the verdict names every plugin in it.

### Why does a plugin say “could not be measured”?

If the site keeps returning a server error whenever one plugin is left out of the
test requests, something else on the site probably depends on it without declaring
so. The same goes for a page that loads normally with every plugin active but answers
not-found, another error, or nothing at all while that one plugin is left out. The
doctor retries a few times in case the error was a passing hiccup, then reports 
the plugin as could not be measured, with the error code, rather than guessing at
its cost. The page is still measured for every other plugin.

### Does it work on multisite?

Yes. Each site runs its own diagnosis. Plugins activated for the whole network are
measured along with the site’s own when the diagnosis is run by a network administrator,
by a schedule or from WP-CLI; a site administrator’s diagnosis covers the site’s
own plugins. The measurement loader in `mu-plugins` is shared by the network, so
deactivating the doctor on one site removes it until it is installed again from 
the Doctor screen; the preflight blocks a scan with that reason rather than reporting
every plugin as harmless. Uninstalling removes the data of every site that opted
in.

### Can I close the tab during a diagnosis?

A diagnosis started from the Doctor tab runs while that tab is open. If you reload
or come back to the Doctor tab within 15 minutes, it carries on where it stopped;
the Doctor tab also offers Cancel diagnosis while one is running.

### Does it work behind a reverse proxy or in a container?

Usually yes, automatically. If your server cannot reach its own public URL, define`
DRAGONSPEEDDOCTOR_LOOPBACK_BASE` in `wp-config.php` with an address the server can
reach (for example `http://app-container` or a private IP). Only the scheme, host
and port are used; any path on the address is ignored because each request keeps
its own path. The doctor keeps the correct Host header so WordPress routes normally.
For safety the override is honoured only when the host is `localhost`, a loopback,
private or link-local IP address written in full (dotted IPv4 or bracketed IPv6),
or a hostname whose every DNS address is in one of those ranges. Anything else, 
including a name that does not resolve, is ignored, so measurement traffic never
leaves your infrastructure.

## Reviews

There are no reviews for this plugin.

## Contributors & Developers

“Dragon Speed Doctor – Find What Slows Your Site Down” is open source software. 
The following people have contributed to this plugin.

Contributors

 *   [ Dragon Core ](https://profiles.wordpress.org/dragoncoreltd/)

[Translate “Dragon Speed Doctor – Find What Slows Your Site Down” into your language.](https://translate.wordpress.org/projects/wp-plugins/dragon-speed-doctor)

### Interested in development?

[Browse the code](https://plugins.trac.wordpress.org/browser/dragon-speed-doctor/),
check out the [SVN repository](https://plugins.svn.wordpress.org/dragon-speed-doctor/),
or subscribe to the [development log](https://plugins.trac.wordpress.org/log/dragon-speed-doctor/)
by [RSS](https://plugins.trac.wordpress.org/log/dragon-speed-doctor/?limit=100&mode=stop_on_copy&format=rss).

## Changelog

#### 1.1.8

 * Every Speed Doctor action checks its security token and your permission itself,
   and request values are read through WordPress’s own sanitizers.
 * The measurement loader validates its request headers the same way. Scans measure
   exactly as before.
 * Fixed: uninstalling one copy of the plugin while another copy is active no longer
   stops with an error.

#### 1.1.7

 * Multisite: network-activated plugins are measured only by a network administrator
   or by a scheduled or WP-CLI scan. A site administrator’s diagnosis covers the
   site’s own plugins, so it can never load the site without a plugin the network
   requires, and never lists what the network runs.
 * Once a page’s own time is known, each further request to it may take up to three
   times that (never less than 10 or more than 30 seconds), so a slow page does 
   not hold a diagnosis for half a minute per request.

#### 1.1.6

 * Verdicts are more honest on noisy hosts: a difference smaller than the server’s
   own noise is never reported as a cost, a result needs at least four timings on
   each side, and a plugin that looks costly but is not yet certain gets a few extra
   timings before the verdict. Large sites take four samples per plugin instead 
   of three.
 * A page that fails with every plugin loaded no longer blames every plugin, and
   a page cache, a rate limit or a single hiccup no longer condemns a plugin or 
   drops a page: only three failures in a row count.
 * The measurement loader is refreshed automatically after a plugin update, and 
   a loader you removed on purpose stays removed. Measurement requests tell page
   caches not to store them, and cannot save rewrite rules or trigger a recovery-
   mode email.
 * Signed measurement requests are bound to the exact address and query they were
   signed for, accept GET only, expire within five minutes, and are signed with 
   the site’s security keys as well as the stored secret.
 * A loopback base naming an IPv4-mapped IPv6 address of a public host is refused,
   and only http and https bases are accepted.
 * Sites whose stored address is http while pages are served over https, or whose
   WordPress address differs from the site address, are measured from WP-CLI and
   scheduled scans again.
 * Plugins that depend on several others are grouped with all of them. Assets inside
   noscript or template blocks, module preloads, data blocks and nomodule scripts
   are no longer counted as render-blocking; symlinked plugin folders are sized;
   a base href is honoured.
 * The Assets and Database tabs say when a page or the options table could not be
   read instead of showing a healthy zero, and the change column compares wp-admin
   as well.
 * A diagnosis that cannot be saved or read is reported as an error, two diagnoses
   cannot start at once, and a request the host cuts off replays at most one measurement.
 * Uninstall deletes data only when the opt-in really says yes.
 * Developers: `dragonspeeddoctor_scan_stale_after` filters how long a running diagnosis
   may go quiet before it is reclaimed; results carry `extended`, `extra_requests`,`
   throttled` and asset `audited`/`failed` counts; the loader’s marker now ends 
   with a tag tied to the request.

#### 1.1.5

 * A page failure is blamed on the plugin that was left out, so one plugin no longer
   spoils the results for others.
 * A missing loader stops the scan with a clear reason instead of reporting All 
   clear.
 * Network-activated plugins are measured on multisite.
 * The Database tab attributes more options to the plugins that own them.
 * Uninstall runs per site on multisite.

#### 1.1.4

 * Results the timings can’t settle are shown as Inconclusive instead of low impact,
   and a page that wasn’t measured is named.
 * Plugins that couldn’t be measured are retried and reported, not called harmless.
 * Scans can be resumed after a reload and cancelled.
 * Only assets loaded on your pages count toward the badge.
 * Some earlier verdicts may change when viewed after the update.

#### 1.1.3

 * Every screen, email and alert is now translatable, so community translations 
   from translate.wordpress.org cover the whole plugin. Counts use proper plural
   forms, and numbers and dates follow your site’s language.
 * Scan dates and owner labels follow your site’s language.

#### 1.1.2

 * Added: an “Upgrade to Pro” link on the Plugins screen, a one-line pointer at 
   the foot of the Speed Doctor screen, and a single dismissible note after three
   diagnoses (or one diagnosis at least three days old). All three disappear when
   Dragon Speed Doctor Pro is active; nothing in the free plugin is locked or changed.

#### 1.1.1

 * Fixed: a diagnosis that did not measure wp-admin (for example when wp-admin kept
   failing to load) logged PHP warnings while working out the results. An unmeasured
   page is now simply treated as inconclusive.
 * Fixed: the measurement loader could fatal if another plugin asked it for measurement
   details on an ordinary request. It now answers “not a measurement request”.
 * Changed: the results summary no longer shows a “0 low impact” badge.

#### 1.1.0

 * Fixed: a homepage that redirects to another page on the same site (for example/
   to /en/, or to a landing page) made the preflight check fail with a message about
   firewalls. The doctor now follows up to three redirects within the site and measures
   the page they lead to. A redirect to a different site, or to a page that errors,
   is reported with its own message.
 * Added: each diagnosis records the plugin, theme and WordPress versions it measured,
   and the site’s overall response time per page, so later diagnoses can be compared
   against them.
 * Developers: new `dragonspeeddoctor_tool_plugins` filter and `dragonspeeddoctor_verdict_details`
   action (under each verdict on Results); `dragonspeeddoctor_page_set` receives
   the scan source as a second argument; `dragonspeeddoctor_scan_complete` receives
   the scan’s environment as a third argument; new `dragonspeeddoctor_signed_request`
   action on verified measurement requests.

#### 1.0.7

 * Changed: the Doctor tab is now one guided card with two numbered steps. Step 
   1 installs the measurement loader; step 2, Run diagnosis, unlocks once the loader
   is in place. Installing or removing the loader no longer reloads the page.
 * Added: a summary of the latest diagnosis on the Doctor tab (impact counts and
   the plugins that need attention), and the same counts plus a Run again button
   at the top of Results.
 * Changed: on Results, plugins with low impact are grouped in a collapsible section
   so the ones worth acting on come first.
 * Fixed: a plugin rated High because of the scripts and styles it ships, but with
   only a small timing cost, showed no reason for the rating. The verdict now also
   states the asset weight whenever it is heavy enough to affect the rating.
 * Added: the Database tab marks the autoload total as Healthy or Above 800KB.
 * Added: live progress now shows the elapsed time, and the browser warns before
   you leave the page while a diagnosis is running.
 * Changed: preflight checks read OK, Warning or Blocked (translatable), and the
   Results, Assets and Database tabs link straight to the Doctor tab when there 
   is no diagnosis yet.
 * Fixed: a loader install or removal that failed was not reported; the reason is
   now shown.
 * Fixed: if a request failed during a diagnosis, the Run diagnosis button stayed
   disabled until the page was reloaded, and a failed start left the screen on “
   Checking…”. A diagnosis interrupted by a dropped request now picks up where it
   left off when you click Run diagnosis again, instead of being refused as already
   running.
 * Fixed: the Dragon Core mark was missing from the page title.

#### 1.0.6

 * Added: an occasional, dismissible request for a WordPress.org review once the
   doctor has produced results, shown only on its own screen.
 * Changed: listing title and tags for the WordPress.org directory.

#### 1.0.5

 * Fixed: two active plugins whose Requires Plugins headers point at each other (
   or a longer loop of them) made the dependency grouping recurse until PHP ran 
   out of memory before a diagnosis could start. Chains are now walked without recursion,
   and every plugin in such a loop is measured as one group.
 * Changed: readme wording tidied.

#### 1.0.4

 * Fixed: asset sizes were reported as 0 for scripts and styles with a scheme-relative(//),
   http:// or document-relative address, for percent-encoded file names, on subdirectory
   installs, and when wp-content lives outside the WordPress folder. Every address
   is now resolved against the page it was found on, then located with the site 
   path stripped and wp-content resolved to its real directory. Only files inside
   the WordPress and wp-content folders are ever read.
 * Fixed: the asset table could attribute a plugin’s scripts to “core/other” when
   the address differed from the site’s wp-content URL in scheme, letter case or
   a www. prefix, or used ../ segments. Attribution now matches on the resolved 
   host and path.
 * Fixed: DRAGONSPEEDDOCTOR_LOOPBACK_BASE with a path (for example http://app-container/
   wp) doubled that path on subdirectory installs and timed 404 pages. The base 
   is now used as an origin only; each request keeps its own path.
 * Security: the loopback base is validated more strictly. IP literals must be a
   full dotted IPv4 or bracketed IPv6 address in a loopback, private or link-local
   range (integer, shorthand and public IPv6 forms are refused), and a hostname 
   is accepted only when every address it resolves to is in such a range. Unresolvable
   names are refused.
 * Fixed: activation recorded the install as complete even when the scans table 
   or the signing secret had not been stored. Both are now verified first; an incomplete
   install is retried on the next admin load and shown as an admin notice until 
   it succeeds. Existing sites are checked once on upgrade.
 * Fixed: a diagnosis that could not be started, saved or finished in the database
   is now reported as an error instead of appearing to start or finish without results.

#### 1.0.3

 * Wording tidied across the readme and the plugin screens for clarity. No functional
   changes.

#### 1.0.2

 * Readme: changelog and upgrade notice now cover 1.0.1, which shipped without entries.
 * Code comments reworded to describe the filter hooks they document.

#### 1.0.1

 * Safety: during a measurement request the active-plugins list can no longer be
   written back to the database, so a probe can never deactivate your other plugins.
 * Reliability: an abandoned scan is reclaimed after 15 minutes so it cannot block
   future scans; the measurement loader is refreshed before each run.

#### 1.0.0

 * Initial release: per-plugin timing attribution (front-end and wp-admin), asset
   audit, database signals, plain-English verdicts, before/after comparison, WP-
   CLI.

## Meta

 *  Version **1.1.8**
 *  Last updated **2 days ago**
 *  Active installations **Fewer than 10**
 *  WordPress version ** 6.2 or higher **
 *  Tested up to **7.1.2**
 *  PHP version ** 8.0 or higher **
 *  Language
 * [English (US)](https://wordpress.org/plugins/dragon-speed-doctor/)
 * Tags
 * [performance](https://test.wordpress.org/plugins/tags/performance/)[plugin profiler](https://test.wordpress.org/plugins/tags/plugin-profiler/)
   [site-speed](https://test.wordpress.org/plugins/tags/site-speed/)[slow](https://test.wordpress.org/plugins/tags/slow/)
   [speed](https://test.wordpress.org/plugins/tags/speed/)
 *  [Advanced View](https://test.wordpress.org/plugins/dragon-speed-doctor/advanced/)

## Ratings

No reviews have been submitted yet.

[Your review](https://wordpress.org/support/plugin/dragon-speed-doctor/reviews/#new-post)

[See all reviews](https://wordpress.org/support/plugin/dragon-speed-doctor/reviews/)

## Contributors

 *   [ Dragon Core ](https://profiles.wordpress.org/dragoncoreltd/)

## Support

Got something to say? Need help?

 [View support forum](https://wordpress.org/support/plugin/dragon-speed-doctor/)