=== Page Speed Benchmark ===
Contributors: matrixlab, imtiazepu
Tags: performance, speed, database, debug, monitoring
Requires at least: 6.4
Tested up to: 7.1
Requires PHP: 8.1
Stable tag: 1.0.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Find the pages over your redline. Server time, database queries and outgoing HTTP calls per page, with on-demand runs and before/after snapshots.

== Description ==

**Page Speed Benchmark** measures how long WordPress takes to build each page on your server, and shows you where that time goes: database queries, outgoing HTTP calls, or PHP and rendering. Set a **redline**, a time no page should take longer than, and see at a glance which pages are over it and why.

Before you change something, **run a benchmark**. Make the change, run again, and **compare the two snapshots** page by page. No guessing whether that new plugin, query fix or cache setting actually helped.

🆘 **[Support](https://wordpress.org/support/plugin/mtx-psbench/#new-post)**

---

Some slowness happens on your server, before the first byte of the page leaves it: an account page waiting 600 ms on a payment API, or a plugin running the same query 300 times to build an order list. For logged-in users that time is rarely cached.

Page Speed Benchmark records it. Every sampled page load keeps its server time, its database queries with the file that ran each one, and every outgoing HTTP call with its time and status. The Overview puts every page against your redline, slowest first, and names what takes the most time on each.

Everything runs inside your own WordPress site. Nothing is sent to an outside service.

---

== 🚀 Key Features ==

* **Redline at a glance**: every page against the time you set, slowest first, with how many pages are over it
* **Cause first**: each page's bar names its biggest cost, such as "HTTP 820 ms" or "DB 590 ms", and shows how far past the redline it runs
* **Where the time goes**: the median split into database, outgoing HTTP and PHP and rendering
* **Slowest queries**: the ten slowest per page, with the theme or plugin file that ran each one
* **Repeated queries**: spot the N+1 pattern, the same query run over and over on one page
* **Outgoing HTTP calls**: URL, method, status and time of every external request made while building the page
* **On-demand runs**: load the pages you pick a number of times and watch every load finish
* **Before and after snapshots**: compare two runs page by page, with time, queries and SQL time side by side
* **Real-visit sampling**: one in every N requests from logged-in users is measured, 1 in 5 by default
* **CSV export** of the Overview
* **Settings that save as you change them**: drag the redline and see which pages would be marked slow
* **Nothing added to your front end**: the plugin loads only on its own admin screen

---

== ⚙️ How it works ==

* **Sampling**: one in every N requests from logged-in users is measured (1 in 5 by default). Visitors who are not logged in are never measured, and unsampled requests do no extra work.
* **Query timing**: for a request it is measuring, the plugin turns on WordPress's `SAVEQUERIES` so each query's time and caller are logged. Other requests are left alone. If your `wp-config.php` sets `SAVEQUERIES` to `false`, the plugin respects it and records query counts only.
* **Outgoing HTTP**: calls made through the WordPress HTTP API while building the page are timed with their URL, method and status.
* **On-demand runs**: pages are loaded from your own site, one at a time, as the administrator who started the run. A background worker carries long runs on, so they work even where WP-Cron is disabled.
* **Live updates**: through the WordPress Heartbeat API, off by default and on by themselves while a run is in progress.
* **Storage**: samples and runs are kept in two database tables of your own site. Nothing is sent to an outside service.

---

== Installation ==

**⬇️ Option 1: Install from WordPress.org (Recommended)**

1. 🔑 Log into your WordPress admin
2. 🔍 Go to **Plugins > Add New** and search for **Page Speed Benchmark**
3. 🖱️ Click **Install Now**, then **Activate**

**📦 Option 2: Manual Upload**

1. ⬇️ Download the plugin zip from WordPress.org
2. 📂 Go to **Plugins > Add New > Upload Plugin**
3. 📤 Upload the zip file and click **Install Now**
4. ✅ Click **Activate Plugin**

**🚀 Getting Started**

1. Go to **Tools > Page Speed Benchmark**
2. Open **Settings** and drag the **redline** to the time no page should take longer than
3. Browse your site while logged in to collect samples from real visits, or open **Runs & snapshots**, pick some pages and start a run to measure them straight away
4. Back on the **Overview**, open any page over the redline to see its slowest queries and outgoing HTTP calls
5. Make a change, run the same pages again, and compare the two snapshots

---

== Frequently Asked Questions ==

= ⚡ Does it slow my site down? =

Only the requests it samples do any extra work, and only logged-in users are sampled. For an unsampled request the plugin decides "not this one" and stops. Visitors who are not logged in are never measured. You can sample less often, or switch real-visit recording off, under Settings.

= 👤 Why only logged-in users? =

Pages for logged-out visitors are usually served from a page cache, so measuring them says little about how fast WordPress builds them. Logged-in traffic (shop managers, members, customers in their account area) is where slow pages hurt and caches rarely help.

= 💾 What does the plugin store, and for how long? =

For each sample: the page path, the template file, the user ID, the response status and the measurements above. Slow samples also keep their slowest queries and HTTP calls. Samples from real visits are deleted after 30 days by default (you can choose 1 to 365). Samples from on-demand runs are kept until you delete the run. Everything is stored in two database tables of your own site.

= 🗑️ What happens to my data if I uninstall the plugin? =

By default your samples, snapshots and settings are preserved, so reinstalling brings everything back. If you want a clean removal, switch on **Delete all data when the plugin is deleted** in Settings > Uninstall before you delete the plugin.

= ⏱️ Why does it say "Query timing is off"? =

To time queries, WordPress needs the `SAVEQUERIES` constant. The plugin switches it on for sampled requests only. If your `wp-config.php` sets `SAVEQUERIES` to `false`, the plugin respects that: query counts are still recorded, but not their times.

= ⚙️ How do on-demand runs work without WP-Cron? =

Many hosts disable WP-Cron, so runs don't use it. Starting a run makes a signed, non-blocking request back to your own site, which processes loads for up to 20 seconds and then hands over to the next request. If a run stops reporting, the next live update restarts it. The worker endpoint accepts only requests signed with your site's secret keys.

= 🔑 Are my pages loaded as a logged-in user during a run? =

Yes: as the user who started the run, so you measure what that user sees. The plugin creates a short-lived login session for the run's requests and destroys it after each step.

= 🧱 Does it work with page caching plugins? =

Yes. Runs load pages "with caches as they are", so a run measures what your users get. Logged-in requests usually bypass page caches, which is why the numbers reflect how fast WordPress itself is.

= 🔒 Does it send data anywhere? =

No. The plugin makes no requests to outside services. The only network requests it makes are the run loads to your own site.

= 🌐 Is it multisite compatible? =

It works per site: activate it on each site you want to measure. Each site keeps its own samples and settings.

== Screenshots ==

1. Overview: every page against your redline, with where its median time goes
2. Page detail: the median split into database, outgoing HTTP and PHP time, with the time past the redline striped
3. The slowest sample's queries, the file that ran each one, repeated queries and outgoing HTTP calls
4. Runs & snapshots: a benchmark in progress, one bar per load, and before/after comparison
5. Settings: drag the redline and see which pages cross it; every change saves on its own

== Changelog ==

= 1.0.0 =
* 🎉 Initial release
* 🆕 Overview: every page against your redline, slowest first, with a bar that names what takes the most time
* 🆕 Page detail: the median split into database, outgoing HTTP and PHP time, the slowest queries with the file that ran each one, repeated queries, and every outgoing HTTP call
* 🆕 Real-visit sampling of server time, database queries, outgoing HTTP calls, memory and HTML size, for logged-in users only
* 🆕 On-demand runs: load the pages you pick a number of times and watch each load finish
* 🆕 Snapshots with page-by-page before and after comparison
* 🆕 Settings save as you change them; drag the redline and see which pages would be marked slow
* 🆕 CSV export of the Overview
* ✅ Live updates through the WordPress Heartbeat API, off by default and on by themselves while a run is in progress
* ✅ Nothing loaded from a CDN, and nothing added to your front end
* ✅ Suggested text for your privacy policy, under Settings > Privacy
* ✅ Your data is kept when the plugin is deleted, unless you switch on "Delete all data when the plugin is deleted"

== Upgrade Notice ==

= 1.0.0 =
🎉 Initial release.

== Support ==

* 🆘 **Free support**: the [WordPress.org support forum](https://wordpress.org/support/plugin/mtx-psbench/#new-post)

== Privacy Policy ==

Page Speed Benchmark does not send data to any outside service and does not use cookies of its own.

When real-visit recording is on, a sampled request from a logged-in user stores the page path, the template file, the user ID and timing measurements in your site's database. These records are deleted automatically after the retention period you set (30 days by default), and all of them are removed when the plugin is deleted if the administrator has switched on "Delete all data when the plugin is deleted". The plugin adds suggested wording for this to your site's privacy policy guide under Settings > Privacy.
