Description
Velocity Forge measures Core Web Vitals on your own site, from your real visitors: LCP, INP, CLS, TTFB and FCP. Every measurement is stored in your own database. The measuring script is served from your site, nothing is loaded from a CDN, and no field reading leaves the site.
It does not stop at the number. A slow interaction is reported with the control that was hit, and whether the time went on a busy main thread, on your own handler or on the repaint afterwards. A slow first paint is reported with the element and the file it loaded. Two cards on the Monitoring screen list the ten controls that cost the most interaction time and the five elements that delay the first paint, each with the file and the plugin behind it. A figure is shown only once an element has at least three measurements.
When an update slows the site down, the plugin tells you what changed. Before an update replaces any file it takes a snapshot of the scripts and stylesheets your front page loads, and afterwards the regression row names the assets the update added, removed or resized. You can set budgets for LCP, INP, CLS and TTFB, and the site owner gets an e-mail when a regression lands.
The changes the free plugin makes are small and reversible. It adds LCP hints to the detected hero image (fetchpriority="high" and a preload), decoding="async" to images and lazy loading below the fold, and speculation rules for prefetch and prerender with a cart, checkout and add-to-cart exclusion that cannot be switched off. Safe Mode disables all of it in one click, from the admin bar as well, and a recovery drill lets you test the escape hatches on a day when nothing is wrong. Velocity Forge is not a page cache: it recognises seventeen caching and optimisation plugins and stands aside where their work overlaps.
Free
- Core Web Vitals collection from real visitors (LCP, INP, CLS, TTFB, FCP), 30 days of history by default, up to 365 days if you ask for it in Settings
- Element, file and plugin behind each slow measurement
- Trend chart of the 75th percentile over 30 days, with the same numbers in a table
- Regression monitor with an asset difference after updates, and an e-mail to the site owner
- Performance budgets for LCP, INP, CLS and TTFB
- LCP hints and lazy loading, speculation rules
- Page profiler: audit single pages or batches of up to 50 URLs of your own site
- Asset inventory: every script and stylesheet handle with its owner
- Database health: autoloaded options, expired transients, overdue cron, and the heaviest autoloaded options with the plugin that wrote them
- Cache plugin coexistence
- Safe Mode, rollback manager and recovery drill
Pro add-on (separate plugin, not part of this download)
- The Optimiser: asset rules (defer, async, delay until interaction, dequeue, preload, preconnect), critical CSS, WebP and AVIF image conversion, autoload and transient cleanup
- Rules that take themselves back when real visitors measure a regression
- Regression alerts to Telegram, Slack or your own webhook
- CSV export of field data
- AI Performance Advisor, which reads your field data and returns an ordered plan without applying anything
- Scheduled lab audits through your own PageSpeed Insights key, which also check the Total Blocking Time budget
The free plugin’s own requests all go to your own site. Details are under External services.
Documentation: https://velocityforge.app/docs/
External services
Field data from the beacon is stored in your own database and is never sent anywhere by this plugin. The separate Pro add-on, if you add it, lists its own requests in its readme.
This free plugin’s own performance work does make HTTP requests, and every one of them is aimed at your own site: the page profiler fetches the pages of this site you audit or batch-scan (a URL on another host is refused), the regression monitor fetches your front page after you update a plugin or theme so it can compare the assets before and after, the asset inventory sends a HEAD request to each script and stylesheet your pages load from this site to read its size (assets served from other hosts are listed without one), and the recovery drill makes a real loopback request to your own secret panic route when you press its button. None of them is aimed at us or at anyone else.
The code also names some third-party hosts — js.stripe.com, paypal.com/sdk, www.google.com/recaptcha, challenges.cloudflare.com and the chat widgets of Intercom, Drift, HubSpot, Crisp, Tawk.to, Zendesk and Olark. They are match patterns, not services: a script from one of them that is already on your pages is recognised and left alone, so payments, captchas and chat keep working. This plugin never connects to any of them.
Telemetry. This free plugin sends no telemetry and has no switch for it. With the separate VelocityForge Pro add-on installed, Settings shows “Share anonymous usage signals” and “Also include sanitised error context”, both off by default, and Pro sends nothing until you turn the first on. When the last Forge plugin or add-on on a site is deleted, everything Forge stored on the site is removed, on every site of a network (the statistics settings and the install ID included); a plugin’s own content follows its own “delete data” setting. While another Forge product stays, only the deleted one’s own share goes.
Bundled libraries
- web-vitals 4.2.4 by Google Chrome, licensed Apache-2.0 (compatible with this plugin’s GPLv2-or-later). This is the script that measures LCP / INP / CLS / TTFB / FCP in the visitor’s browser. It is bundled with the plugin and served from your own site — it is not loaded from a CDN, and it makes no request of its own. Source: https://github.com/GoogleChrome/web-vitals
The Pro add-on
The Pro add-on is a separate plugin with its own readme, and the requests it makes are described there. This plugin makes none of them.
Installation
- Upload the
velocityforgefolder to/wp-content/plugins/, or install through Plugins Add New. - Activate VelocityForge through the Plugins menu.
- Open VelocityForge Dashboard to run your first page audit.
- Visit VelocityForge Settings to tune thresholds and enable modules.
FAQ
-
Can I run it alongside my caching plugin?
-
Yes. Velocity Forge is not a page cache and does not want to be one. It recognises seventeen caching and optimisation plugins, and its overlapping work stands down while one of them is active. The notice names every feature that stepped back, not only the obvious overlap.
-
An update slowed the site down. What does Velocity Forge tell me?
-
Which assets changed. Before an update replaces any file, the plugin fetches your real front page and reads its script and stylesheet queue. Afterwards the regression row reads the difference and names what was added, what disappeared and what grew. “LCP is up 400 ms” is a symptom; “this update added three render-blocking stylesheets” is something you can take to its author.
-
What happens if I break something?
-
Every change has a rollback path. Revert the single rule, press Safe Mode in the admin bar on whichever screen you noticed the problem, use the secret panic URL shown on the Rollback screen, or add
define('VELOCITYFORGE_PANIC', true);to wp-config.php. The wp-config.php line is checked before any database read, because on the day you need it the database is often the problem. -
How do I know the escape hatches work before I need them?
-
Run the recovery drill on the Rollback screen. It presses the real hatches, including a genuine loopback request to your secret panic route, and puts everything back exactly as it found it. It writes no files.
-
Does it send my data anywhere?
-
No measurement leaves your site. The free plugin makes requests of its own, and every one goes to your own site: the page profiler fetches the pages you audit, the regression monitor reads your front page after an update, the asset inventory sends a HEAD request to each script and stylesheet your pages load from this site, and the recovery drill calls your own panic route when you press its button. The free plugin sends no telemetry.
-
Do I need an account or API key for the free version?
-
No. Measuring and diagnosing happen entirely on your own server. See External services for exactly what this download does and does not contact.
-
Can Velocity Forge undo a rule on its own?
-
Only with the Pro add-on, only for a rule you have just created, and only after refusing six ways: no licence, the beacon switched off, fewer measurements than your sample floor, Safe Mode on, a protected handle, or a rule you pinned. When it acts, it reverts that one rule, records the reason on the rollback event and e-mails you the numbers and how to put it back. Below the sample floor the verdict is “inconclusive” and the rule stays as it was.
Reviews
There are no reviews for this plugin.
Contributors & Developers
“Velocity Forge – Core Web Vitals, Page Speed & Performance” is open source software. The following people have contributed to this plugin.
ContributorsTranslate “Velocity Forge – Core Web Vitals, Page Speed & Performance” into your language.
Interested in development?
Browse the code, check out the SVN repository, or subscribe to the development log by RSS.
Changelog
1.3.2
- When AI credits run out, the message no longer promises a monthly reset and links to the page where you buy credits.
- The plugin is listed as “Velocity Forge – Core Web Vitals, Page Speed & Performance” in the Plugins list and on wordpress.org.
- The logo in the admin screens is the new mark.
1.3.1
- With the VelocityForge Pro add-on installed, Settings Privacy & uninstall has a second box, “Also include sanitised error context”, under “Share anonymous usage signals”. It cannot be ticked while the usage box is empty.
- Turning the usage box off now also deletes the statistics queued and not yet sent and the stored error-context choice; the second box is empty when usage is ticked again. A save that does not carry the usage box (another setting saved on its own) no longer switches the choice off.
1.3.0
- New: when you have not named any pages to watch, the Monitoring screen offers “Suggested pages”: your home page, then the pages with the most recorded visits, or your shop pages, with WooCommerce, while there are none yet. Nothing is saved until you press “Watch these pages”.
- New: a page that is still short of observations now says how long it may take to get enough, in the readiness checklist and beside “Insufficient data” in the baseline table: “≈ 3 days at the current traffic”, “no visits recorded yet”, or “not within the baseline window at the current traffic” when the window cannot hold that many. It is an estimate, never a promise of a verdict, and the last wording is held back during the first two days of recording.
- Reading the busiest pages is limited to the newest 50,000 records, so the Monitoring screen opens quickly on a site with millions of records; a smaller site is read in full.
- The new lines are translated in all 15 shipped languages.
1.2.6
- Deleting the plugin leaves the job queue the Forge plugins share in place while another Forge plugin or add-on is still on the site. The check used to miss add-ons, and Rank Forge installed from wordpress.org, so the queue could be dropped while a neighbour still had jobs in it.
- Requires WordPress 6.6 or newer. The database health check asks WordPress which autoload values it loads on every request, and WordPress answers that only from 6.6. Sites on WordPress 6.5 stay on 1.2.5.
1.2.5
- The recovery drill checks the secret panic URL with a one-off secret instead of the site’s own, and verifies TLS like any other request.
- The readme no longer describes the Forge Suite admin layer, which this download does not include.
1.2.4
- Field data is kept for up to a year on every install; the three-month ceiling without the Pro add-on is gone.
- The licence screen, the plan badge in the header and the upgrade card moved into the Pro add-on. This plugin only notes which features the separate add-on provides, with a link to its product page.
- A scan on the Assets screen runs only from the screen’s own Scan button or “Create rule” link, which now carry a nonce.
- The readme lists the third-party hosts VelocityForge recognises on your pages and never contacts.
1.2.3
- The recovery drill no longer writes into wp-content. It checks the panic constant, the secret panic URL, the safe-mode option and the autoload backups, and leaves the filesystem alone.
- The page profiler and the asset inventory stay on this site: a pasted URL on another host is refused, and scripts or styles served from another host are listed without a size instead of being fetched.
- The notice about an outdated Pro add-on appears on VelocityForge screens, the plugin list and the dashboard only.
- The usage-telemetry switch appears only where something honours it — the Pro add-on — instead of in every install.
- Request input is sanitised where it is read, database queries are prepared or documented, and admin output is escaped.
1.2.2
- This release needs VelocityForge Pro 1.2.0 or newer. An older add-on is switched off whole rather than left running: 1.2.0 is where the free screens started promising that a rule which begins applying is measured against real visitors for a day and reverted on its own, and every part of that decision is in the add-on — beside a 1.1.x add-on the sentence is printed and nothing measures anything. Nothing you have saved is touched, an admin notice names both versions and what stopped, and installing the current add-on brings all of it back.
- Deleting the last Forge product on a site now clears the job queue the Forge plugins share — its table, its two scheduled events and its version marker. While any other Forge product is still installed, deleting this one leaves the queue exactly as it is, because the pending jobs in those rows are that product’s too.
- Admin script globals carry the full velocityforge prefix instead of spf.
1.2.0
- New: a measurement now names what it points at. An interaction is recorded with the control that was hit and with the time split three ways — the wait before the handler ran, the handler itself, and the repaint afterwards — plus whether the page was still loading at the time. A largest paint is recorded with its element and the file that element loaded. Those live in their own table and are counted rather than read one at a time, because “one visitor waited 340 ms on button.add-to-cart” is an anecdote and “this is the p75 of two hundred interactions, and three hundred of those milliseconds are the handler” is a task.
- Two cards on the Monitoring screen say it out loud: the ten controls that cost the most interaction time and the five elements that most delay the first paint, each with the file and, where it can be established, the plugin that shipped it. The owner is resolved from a prefix table, then from this site’s own enqueued handles, then from a filter — and where none of the three answers it says “theme” or nothing, never a confident wrong name.
- Every figure is a 75th percentile per element over 28 days, and an element appears only once it has at least three measurements. A p75 of two measurements is the larger of two under a borrowed name.
- An LCP file is linked only when its host is your own site. Resource URLs arrive through an unauthenticated beacon, so a stranger’s link is named but never made clickable.
- New: the regression says what the update changed. Immediately before an update replaces any file, VelocityForge fetches your real front page and reads its script and stylesheet queue out of the served HTML — the rendered page, not the handle registry — and afterwards the regression row names what the front end gained, lost or resized. A non-2xx response is refused before the body is parsed, because a bulk update serves a 503 maintenance page that parses perfectly into an empty list, which would have made your whole real asset queue look like an addition.
- That snapshot is bounded on purpose: at most twenty-four assets are sized per run, and sizing stops after a three-second budget, so updating twenty plugins cannot eat
max_execution_timefrom inside the installer. Both the page fetch and the size probes go through the SSRF guard, because the URLs come out of somebody else’s HTML. - New: the Database screen names owners. The twenty heaviest autoloaded options are listed with the plugin that wrote each one, resolved from the option-name prefix. Read-only, as the free health report has always been.
- New: the recovery drill (free). One button runs four independent checks — the panic constant, a real loopback request to the secret panic route with a one-off secret, the safe-mode option’s round trip, and the autoload backups table — and puts everything it touched back exactly as it found it, the stored secret included. A drill that left the secret changed would have broken the escape hatch it exists to verify.
- New: Safe Mode in the admin bar, on the front end as well as in wp-admin, because a broken site is usually noticed on the front end. It calls the same rollback manager the form does, so it lands in the same audit trail rather than becoming a second way to write the same state.
- New in Pro: rules that take themselves back. A rule that starts applying is measured for a window — 24 hours by default, settable 6 to 72 — against what real visitors measured the week before. If LCP or INP is worse by more than your threshold it is reverted through the same call your own button makes, the reason
auto-watchis written onto the rollback event, and you get an e-mail with the numbers and how to put it back. It refuses on no licence, no beacon, too few measurements, Safe Mode, a hard-railed handle and a pinned rule; one watch is open per rule and one verdict is taken per watch, so a retried job cannot revert twice or send a second e-mail. The free plugin carries the table and announces that a rule was created or enabled; every decision is in the add-on. - Pro alerts are configurable by a person. Bot tokens, webhook URLs and HMAC secrets used to sit in a JSON textarea in clear text and be printed straight back into it. They are now encrypted at rest and shown only as their last four characters, the screen is a card per channel with Add, Remove and a “Send test” that really sends and writes nothing, and an empty field means “leave it as it is” — so the first save through the new form re-encrypts an old clear-text value without you doing anything. The test path runs the same https-only, no-private-address guard as the save path, so it cannot be used to probe your internal network.
- New: a Total Blocking Time budget, 300 ms, in the same map as LCP, INP, CLS and TTFB. It is honest about itself: no field source populates it, because TBT needs a long-tasks trace the beacon does not capture, so it is read only by the Pro lab audits’ comparison. Banding needed no new code — it keys off the metric name and does not care which instrument produced the value.
- The lab-audit panel’s status line is now the run’s own state instead of a fixed “Queued — refresh in a minute”: nothing started says nothing, an open run says when it was queued, and a finished one repeats exactly the wording the history table uses, so the two can never disagree.
- Five more caching and optimisation plugins are recognised — Jetpack Boost, SiteGround Optimizer, WP-Optimize, Breeze and WP Fastest Cache — bringing the list to seventeen. The coexistence notice now names every feature we stood down rather than only the overlapping one: for a plugin that owns the whole asset pipeline the optimiser stands down entirely, and a banner claiming we had only stepped back from minification while four other features were silently off was worse than saying nothing.
- New: the trend, on the Monitoring screen. Thirty days of daily 75th percentile for LCP, INP, CLS and TTFB, so a regression row has the fortnight either side of it to be read against. A percentile rather than an average, because the average of a day where nine visitors waited a second and one waited eleven is two seconds, and two seconds is a number nobody experienced. A day with no measurements is a gap in the line, never a zero.
- Free, and it draws whatever it has. On a site with the Pro add-on and scheduled lab audits switched on, the same chart carries a second line.
- New in Pro: scheduled lab audits. Lighthouse runs against a list of your pages once a day through your own PageSpeed Insights key — your key, your Google quota, your billing relationship with Google, and no proxy of ours in between. The key is encrypted at rest with a value from wp-config.php and is never shown back to you.
- Lab results are ordinary measurements in the ordinary table, so the trend, the regression history, the e-mail and the Telegram / Slack / webhook alerts all treat them the same way. They are never compared against a real visitor’s measurement, though: a reading from Google’s edge and a reading from a browser in Jakarta are not the same instrument, and comparing them reports a regression whose only cause is the yardstick.
- New: a Speculation panel. WordPress 6.8 prefetches the next page on its own, conservatively and with no way to say “but not that link” short of writing a filter. This screen gives you the two controls — prefetch or prerender, and how eagerly — plus a list of paths to leave alone.
- It steers the rule set WordPress already prints rather than adding one of its own. That is not tidiness: a page may carry several speculation rule sets and the browser takes their union, so a second one can only add speculation, never take it away. “Prerender the site but never the cart” is unreachable any other way.
- Cart, checkout, my-account, logout, anything carrying a nonce and anything carrying
add-to-cart=are excluded and cannot be switched on. Cart and checkout paths are read from the site — a shop whose cart lives at /basket/ is excluded at /basket — rather than guessed from slugs. Prefetch is railed as tightly as prerender, because a prefetch reaches the server too, and a speculated add-to-cart link puts a product in a real basket. - The exclusions you write are checked and a bad line is refused, not repaired. One pattern the browser cannot read makes it discard every speculation rule on the page, so the screen drops the line and tells you how many it dropped.
- Defaults reproduce what WordPress does today — prefetch, conservative — so upgrading changes nothing about your pages until you move a control.
- On WordPress below 6.8 the panel says so plainly and the settings still save, ready for the upgrade. Nothing here is greyed out and nothing asks about a licence.
1.1.0
- Five things that were Pro are now Free, because their code was in this download all along. WordPress.org rejected a plugin like ours in August for exactly that — a licence check standing on top of code the free user already has — and it was right to. What moved:
- LCP hints.
fetchpriority="high"on the hero image and the matching<link rel="preload">. WordPress core has set fetchpriority on its own LCP guess since 6.3, so this was a charge for the platform. - Field-data retention. Free was clamped to seven days, which is too short to see a weekly pattern twice. It is thirty by default now, and will honour up to ninety.
- Batch scans. Twenty-five URLs free, two hundred paid. There is now one cap, fifty, for everybody: it exists so a shared host survives a batch of synchronous self-requests, and that reason does not care who paid.
- The regression e-mail. It was repaired in 1.0.1 and sold as Pro in the same release. Charging for a fix is not a business model. Detection was already free; being told is free too.
- The database health report. Reading how much your site autoloads was never worth money.
- LCP hints.
- What Pro is now, stated plainly: the optimiser (asset rules, critical CSS, WebP/AVIF conversion, autoload and transient cleanup) as a single purchase rather than three separate keys; regression alerts delivered to Telegram, Slack or a webhook; a year of field data with CSV export; and the AI advisor. Every one of them is code that ships in the add-on.
- No screen in the free plugin greys a control out because you have not paid. Where a feature lives in the add-on, the page says so in a sentence and shows you the part that is free — the asset inventory, the autoload table, the health numbers, the regression history.
- Existing Pro licences are unaffected: the three optimiser keys became one, and everything they covered stays included.
- Every field measurement now records what it points at — the LCP element, the interaction target, the node that shifted, and for an interaction the split between input delay, processing and presentation. VelocityForge has always downloaded the build of web-vitals that carries this; it used to throw it away on arrival.
- Fixed: no schema change had ever reached a site that already had the tables. Every migration was written as
CREATE TABLE IF NOT EXISTS, and dbDelta reads the table name straight afterCREATE TABLE— so it believed the table was calledIF, found none, and compared no columns, while the stored version number recorded a migration that had not happened. Corrected, and a test now fails on any migration written that way.
1.0.2
- The Core Web Vitals beacon now measures. The bundled copy of Google’s web-vitals library had never been vendored — a placeholder file shipped in its place, so the measuring script was never defined and every field-data screen stayed empty on every install. web-vitals 4.2.4 is now bundled for real. If your beacon has been on and showing nothing, this is why.
- Removed “Scheduled CWV Monitoring” from the Pro feature list. No recurring audit was ever implemented behind it: the licence key unlocked nothing, so it should not have been sold. Post-update regression detection is unaffected — it is free, always on, and continues to fill the Monitoring screen. Regression e-mails remain Pro.
- Removed a daily cron left behind by that feature. It had no handler, so it woke wp-cron once a day to do nothing; existing sites are cleaned up automatically on upgrade.
- Translations caught up with the plugin. The catalogue had not been regenerated since 1.0.0, so the regression e-mail, the field-data export screen and the rewritten Monitoring notice all rendered in English on the fifteen translated locales. All fifteen are complete again, and Arabic, Hindi and Chinese now declare their plural rules instead of borrowing English ones.
1.0.1
- Regression alerts actually send. The “Email me on regressions” toggle had existed since launch with nothing behind it.
- Field-data CSV export, streamed — the half of “90-day retention” that was advertised and missing.
- Removed two licence entries with no code behind them (per-page profiles was a second name for asset rules; agency reports was not built).
1.0.0
- Initial public release. WordPress.org Free core; Pro features delivered by the separate VelocityForge Pro add-on.
