SSP Documentation
SSP Website Speed Monitor
Admin Screen
Top-level menu SSP Speed Monitor (performance icon) opens a single page with three tabs:
Dashboard
- Live — current 1-minute server load (auto-refreshing).
- Controls & Settings — enable throttle, set Ceiling, choose sources to throttle, toggle admin-bar live number.
- Averages — overall average and max observed load.
- Load Throttle — current status (ACTIVE/IDLE) with ceiling and current load.
- Throttle Sources & Events — counts by source, top URLs, and a detailed events table.
Analytics
- Every hour of today — per-hour averages for the current day.
- Every day of the week — overall averages Mon–Sun.
- Every week this month — week-of-month averages.
- Every month this year — Jan–Dec averages.
- All years — per-year rows, average, and max.
Sources
- LIVE breakdown that sums to the current 1-minute load by allocating load proportionally to request counts.
- Sources: WP-Cron, Heartbeat, AJAX (other), Admin, Frontend, Other.
Tip: Use “Reset analytics data” on Dashboard to clear minute + hourly logs (safe; throttle log & sources counters remain).
How It Works
- Activation ensures/creates four tables and schedules a per-minute logger; it also writes an initial sample.
- Per-minute logger records the 1-minute load average and upserts a row keyed by
YYYYMMDDHHMM
. - Per-hour aggregator recomputes hourly averages from minute rows for the current hour and upserts an hourly row.
- Always-on source counting increments a per-minute counter for the request’s source class (cron, heartbeat, ajax_other, admin, frontend, other).
- Throttle optionally suppresses WP-Cron spawns and/or disables Heartbeat when the load meets/exceeds your ceiling; events are logged.
- AJAX auto-refresh updates Live, Averages, Throttle, Analytics tiles, Sources, and admin-bar number every ~10s.
- Fallback seeds a minute sample once per minute on traffic even if WP-Cron is stuck.
- Degraded mode (no
sys_getloadavg()
): the plugin logs 0.00 so analytics still populate.
Data Model (Tables)
Per-minute log
Table | wp_ssp_load_log |
---|---|
Keys | PK id , UNIQUE minute_key (BIGINT), index ts |
Columns | ts DATETIME , minute_key BIGINT (YYYYMMDDHHMM), load FLOAT |
Per-hour aggregates
Table | wp_ssp_load_hourly |
---|---|
Keys | PK id , UNIQUE hour_key (BIGINT), index ts |
Columns | ts DATETIME (last update), hour_key BIGINT (YYYYMMDDHH), avg_load FLOAT , sample_count INT |
Throttle events
Table | wp_ssp_throttle_log |
---|---|
Keys | PK id , indexes ts , source |
Columns | ts DATETIME , source VARCHAR(32) (cron_spawn | heartbeat_block | other), url TEXT , ip , ua |
Request sources (per-minute counters)
Table | wp_ssp_request_sources |
---|---|
Keys | PK id , UNIQUE minute_key , index ts |
Columns | ts DATETIME , minute_key BIGINT , cron , heartbeat , ajax_other , admin , frontend , other |
Note: Legacy installs automatically heal
minute_key
to BIGINT.Logging & Aggregation
Per-minute logger
- Runs via WP-Cron schedule every 60s.
- Upserts
ts
,minute_key
,load
. - Fallback seeding guarantees at least one write per minute on traffic.
Per-hour aggregator
- Recomputes the average from minute rows for current hour window.
- Upserts
avg_load
andsample_count
. - Analytics tiles read from hourly where possible, minute otherwise.
Scheduling
- Cron schedule key:
ssp_wsm_every_minute
(interval 60s). - Hook:
ssp_wsm_log_every_minute
. - On deactivation the event is unscheduled.
Dashboard
- Live shows the current 1-minute load and the last refresh time.
- Controls & Settings:
- Enable Load Throttle — master toggle.
- Ceiling — threshold; when
load ≥ ceiling
the throttle engages. - Sources to Throttle — WP-Cron and/or Heartbeat (AJAX).
- Show Admin Bar Load Number — toggles the live number in the top bar.
- Reset analytics data — truncates minute + hourly tables.
- Averages — overall average & max observed, for quick health checks.
- Throttle box — Enabled, Ceiling, Current load, and Status (ACTIVE/IDLE).
- Throttle Sources & Events — counts by source, top URLs by frequency, and a detailed events table (header shows “URL”, no “(truncated)”).
Analytics
- Every hour of today — bars scaled to the max hour; uses hourly table, falls back to minute.
- Every day of the week — Mon–Sun overall averages.
- Every week this month — week-of-month averages (1..5).
- Every month this year — Jan..Dec averages with month labels.
- All years — per-year rows with total rows, average, and max.
Sources (LIVE)
The Sources tab tracks request counts for the current minute and allocates the live 1-minute load proportionally so the components sum to the total.
Sources tracked
- WP-Cron
- Heartbeat
- AJAX (other)
- Admin
- Frontend
- Other
How allocation works
- Within the current minute, let
N
be the total requests across sources. - Each source gets
live_load × (source_count / N)
. - Bars are scaled to the largest allocated component for visual clarity.
Note: Source counters are written on every request (independent of the throttle) and upserted per minute.
Load Throttle
Behavior
- When enabled and
load ≥ ceiling
:- WP-Cron spawns (requests to
wp-cron.php
) are suppressed via HTTP filter, and a throttle event is logged. - Heartbeat is disabled by deregistering the script; a once-per-minute event is logged while active.
- WP-Cron spawns (requests to
- Each event records time, source, and (when available) URL.
Why throttle?
- To reduce non-essential background load spikes during heavy traffic.
- To keep the site responsive by delaying cron and editor heartbeat until load falls.
Caution: Throttling cron may delay scheduled tasks; choose a ceiling that balances responsiveness with task timeliness.
Admin Bar
- Shows the live 1-minute load as a number.
- Color shifts to red when the value is ≥ 1.00; otherwise green.
- Toggle visibility in Controls & Settings.
AJAX & Auto-refresh
- Every ~10 seconds an authenticated AJAX request returns updated HTML for:
- Live, Averages, Throttle box, Throttle events
- Per-hour today, Weekday, Week-of-month, Monthly, Years
- Sources (LIVE)
- The response also includes the numeric live value to repaint the admin-bar node.
- No-cache headers and a nonce are used; visibility-change triggers a refresh when you return to the tab.
Reset & Degraded Mode
Reset analytics
- Dashboard → Reset analytics data truncates per-minute and per-hour tables.
- Does not clear throttle events or source counters.
Degraded mode
- If
sys_getloadavg()
is unavailable, the plugin logs0.00
as load. - All tiles and charts still function so you can verify the pipeline.
Troubleshooting
No data appears
- Confirm WP-Cron runs (traffic or a system cron hitting
wp-cron.php
). - Use the fallback seeding by simply visiting the Dashboard; it writes once per minute via transient.
- Check DB user permissions for creating/altering tables.
Live number is always 0.00
- Your environment may lack
sys_getloadavg()
; this is expected in some hosts/containers. - Analytics will still populate; consider enabling host-level metrics for real load values.
Throttle never engages
- Enable Throttle and set the Ceiling below your current load for testing.
- Ensure the specific source (WP-Cron or Heartbeat) is checked to be throttled.
Throttle blocks too aggressively
- Raise the ceiling, or uncheck the source you don’t want to block.
- Remember WP-Cron suppression can delay scheduled tasks.
Admin-bar number missing
- Enable “Show Admin Bar Load Number” on Dashboard.
- Verify you’re logged-in and the admin bar is visible.
Test / Verification
- Visit Dashboard and confirm a Live value appears (may be 0.00 in degraded mode).
- Click Reset analytics data, then wait ~1–2 minutes; verify per-hour today begins to fill.
- Enable Load Throttle, set Ceiling to
0.00
temporarily, and tick both sources. Confirm:- Status shows ACTIVE.
- Throttle Sources & Events table starts logging events.
- “Top URLs” lists
wp-cron.php
when cron spawns are suppressed.
- Open the Sources tab and trigger various requests (navigate front-end, admin, run AJAX). Observe counts and allocated load change, summing to the live number.
- Restore a sane ceiling (e.g., 25.00) and disable throttle if desired.
Tip: If your site has very low traffic, set up a system cron to hit
wp-cron.php
every minute to guarantee samples.