Everything
about
Speed
of Light.

Install it and let it tune itself, or
take full control of every setting.

Written for version 1.5.32WordPress 6.0+ and PHP 7.4+

Get started

Getting started

Speed of Light (Pro) turns your pages into ready-made HTML files and serves them to visitors before WordPress has to do any work. On licensed and trial sites, its cloud engine also loads your pages in a real browser and works out what to fix: the main image, layout shifts, CSS and fonts. This guide covers requirements, installation, your license, and checking that caching works.

Speed of Light caches pages for logged-out visitors only. These are always served fresh and never stored:

  • Logged-in users, WooCommerce carts and checkout.
  • Admin screens, REST requests and form submissions.
  • Any request carrying a recognized session cookie. More than 20 cookie patterns are built in.

There are no per-user cache copies, so one visitor can never see another visitor's cart.

Requirements

  • WordPress 6.0 or higher, tested up to WordPress 7.1.
  • PHP 7.4 or higher. On older PHP the plugin doesn't load. It shows a notice instead, so it can never run on an unsupported version.
  • A license or free trial for the cloud features (cloud optimization, Insights scans and Autopilot). Page caching works without one.
  • Write access to wp-content/ and wp-config.php, so the plugin can install its cache drop-in and turn on WP_CACHE. Most hosts allow this.

Installation and setup

Install the plugin

In wp-admin, go to Plugins → Add New → Upload Plugin, choose the zip file you downloaded and click Install Now. You can also unzip it and upload the folder to wp-content/plugins/ over SFTP.

Run only one full-page cache plugin at a time. Deactivate any other page-cache plugin first. Speed of Light never overwrites another plugin's cache drop-in. It pauses its own page caching and tells you which plugin is in the way.

Activate the plugin and your license

Click Activate on the Plugins screen. A new SOL item appears in the admin menu. Open it and enter the license key from your purchase email. This turns on cloud optimization, Insights, Autopilot and automatic updates. See Licensing & free trial.

Let the safe defaults do their work

A fresh install turns on page caching, cache preloading, gzip/Brotli compression, LCP hints, lazy loading and speculative prefetch, and starts warming the cache. It makes no changes to your login page or the WordPress admin.

Tools that can change how a page looks or behaves (Critical CSS, Remove Unused CSS, JavaScript delay and HTML minify) stay off until you turn them on. On licensed and trial sites, Autopilot can also apply a short list of publisher-safe fixes after checking your real pages. See Autopilot & Recommendations.

Check that pages are cached

On activation, Speed of Light writes its drop-in to wp-content/advanced-cache.php and adds WP_CACHE to wp-config.php. This also works when the file already contains define( 'WP_CACHE', false ), and with Bedrock-style setups.

To check, open your site in a private window, load a page twice and look at the response headers in your browser's developer tools. X-SOL-Cache: HIT means the page came from the cache. BYPASS means it was deliberately not cached, and SOL → Health tells you why.

If wp-content/ or wp-config.php isn't writable, Cache → Local Cache explains the problem in plain English. Fix the permissions, or ask your host to, and setup retries by itself. A missing drop-in is also repaired automatically.

Finding your way around

  • Dashboard: status, recommendations and quick actions.
  • Insights: cloud page checks, Autopilot, Core Web Vitals and server details.
  • Cache: Local Cache, Local Queue (the preloader), Cached URLs, Edge Cache (Cloudflare), CDN and Exclusions.
  • Object Cache: optional Redis.
  • Optimize: CSS, JavaScript, Images, Bulk Compression and Preconnect.
  • Settings: Tweaks, Debloater, Admin, Export / Import, Logs and Reset.
  • Clean: database cleanup.
  • Health: the Alerts centre and a one-click self-check.

What next

Run Insights → Check my site to see how your pages perform, and keep an eye on the Alerts centre. When you're ready, these are worth exploring:

  • A Redis object cache.
  • Cloudflare edge caching.
  • The opt-in CSS and JavaScript tools. Check your key pages after turning each one on.

Every plan is the complete plugin. All features are on every tier. Tiers differ only by the number of sites. Questions? Email help@speedoflight.pro.

NextAutopilot & Recommendations

Get started

Autopilot & Recommendations

Speed of Light tunes itself in two ways. Recommendations is a short list on the Dashboard: each item says what it would change and why, and you decide. Autopilot works on licensed and trial sites. It applies a small set of publisher-safe changes that the cloud has checked on your real pages, re-checks the pages afterwards and undoes anything that causes a problem. Both follow one rule: a setting you change by hand is yours, and neither will change it back.

There is no global "performance level" to pick. Each feature has its own switch, and the riskier tools (Critical CSS, Remove Unused CSS, JavaScript delay, HTML minify) stay off until you turn them on.

What a fresh install does

A new install starts with the safe basics on: page cache, cache preload, gzip/Brotli compression, LCP hints, lazy loading and speculative prefetch. It makes no changes to your login page or wp-admin.

On first activation, Speed of Light also applies a few recommendations, once, that are safe on any site:

  • Compress cached pages (uses Brotli when your server has it).
  • Serve images as WebP and WebP as the image format, if your server can make WebP files.
  • Cache commenter avatars, if comments are open on new posts.
  • 103 Early Hints, if Cloudflare is in front of the site.

If another full-page cache plugin is active, nothing is applied. You'll see a notice asking you to deactivate the other plugin, and the safe defaults are applied on a later activation once the conflict is gone.

The environment profile

Every recommendation is based on a read-only profile of your site. The profile never changes a setting. It is refreshed every 12 hours and straight away when you activate or deactivate a plugin or save Cloudflare credentials. It notes:

  • Server: web server (LiteSpeed, NGINX or Apache), PHP and WordPress versions, OPcache, multisite.
  • Compression and caching: Brotli and gzip support; whether a persistent object cache is active and whether Redis is available.
  • Images: Imagick or GD, and whether WebP and AVIF can be encoded.
  • Cloudflare: whether it is connected in the plugin, and whether it is proxying your traffic right now.
  • Managed hosts with their own page cache: Kinsta, WP Engine, SiteGround, SpinupWP, Pantheon, WordPress.com / WP Cloud, GridPane, RunCloud and Cloudways.
  • Your site: WooCommerce, Easy Digital Downloads, multilingual plugins, open comments, your theme, page builders, and any other caching or optimization plugin.

Recommendations

When there is something worth changing, the Dashboard shows "We found N optimizations for your site". Expand it to see each item with its reason and a Turn on or Turn off link, or click Apply all (N). The same advice appears under the matching toggle as "Recommended for your site".

These are suggested but never switched on for you:

  • Self-host Google Fonts and Preload fonts.
  • Lightweight video embeds and Self-host third-party scripts.
  • Minify CSS, Minify JavaScript and Delay JavaScript (safe mode).
  • Remove Unused CSS. It is recommended for simple sites, and recommended off when a page builder is present or another plugin already optimizes CSS.
  • 103 Early Hints, which only takes effect with Cloudflare in front of the site.

Recommendations never fight your setup. If another plugin (for example Autoptimize) already minifies your CSS and JavaScript, Speed of Light recommends leaving its own minify and delay off and names the plugin that is doing the work.

Your choices are kept

Applying a recommendation doesn't lock the setting, so the advice can change as your site changes. Changing a setting yourself does: Speed of Light records it as your choice, and neither Recommendations nor Autopilot will change it again. If you switch AVIF on when WebP is recommended, AVIF stays on.

Autopilot

Autopilot lives in SOL → Insights → Autopilot. On licensed and trial sites it runs unless you switch it off. If you do, it stays off.

Autopilot only ever turns on these publisher-safe changes:

  • Page cache and long-life caching for static CSS and JavaScript files.
  • Preloading the main (LCP) image and giving it fetchpriority="high".
  • Adding missing image dimensions.
  • Responsive image serving (serving WebP copies that already exist).
  • Font optimization (self-hosting and preloading Google Fonts).
  • Instant navigation.

It never touches JavaScript delay, Critical CSS, Remove Unused CSS or video embeds. It never converts or resizes your media library files either: converting the library only starts when you click it yourself.

The cloud checks your pages

Pages are loaded in a real browser at desktop and phone widths. The cloud approves only fixes it considers safe for each page. If any page flags a fix as risky, it is skipped for the whole site.

Autopilot applies one change set

It applies the approved fixes in the background, at most once a day, then clears and re-warms the page cache so visitors get pages built with the new settings.

It verifies with a rescan

Your pages are checked again. If the site returns server errors, or the new scan marks a change as unsafe, Autopilot restores your previous settings and won't try that change again for 14 days. If the cloud can't be reached during this step, Autopilot keeps the changes and retries the check later instead of rolling back.

A few more details:

  • Check my site only scans. Any fixes Autopilot finds are applied in the background a few minutes later.
  • Undo last changes restores the settings you had before Autopilot's last change set, and they won't be re-applied automatically.
  • The Alerts centre tells you when Autopilot turns something on or undoes a change (see Alerts centre).
  • Pages that only have a borrowed template plan never drive Autopilot (see Large sites).

Optional fixes you apply yourself

Click Show technical details on the Autopilot tab to see each page's findings. Where the plugin can fix something, there is a Fix it button, and Apply N safe fixes applies them all at once. These fixes only happen when you click. They can include the opt-in tools Autopilot leaves alone, so check your key pages afterwards. For what each finding means, see Insights & Health.

NextLicensing & free trial

Get started

Licensing & free trial

Speed of Light (Pro) has one plan, and every tier gets every feature. The only difference between tiers is how many sites you can use it on. This page covers the tiers, the free trial, what happens when a license expires, and how to move a license between sites.

Tiers

TierSitesPrice
Solo1 site$20 per year
Studio50 sites$99 per year
AgencyUnlimited sites$179 per year

Prices are in US dollars and billed yearly. Checkout is handled securely by Freemius and accepts cards and PayPal. Because the features are the same on every tier, moving up or down a tier only changes your site count.

The 7-day free trial

  • Every tier starts with a 7-day free trial. A card is required at checkout.
  • The trial is the full product, including cloud optimization, Insights scans and Autopilot. Health shows the trial as an active license.
  • When the 7 days are up, the trial converts to a paid yearly subscription unless you cancel before it ends.

About refunds: we can't offer refunds once a trial has converted to a paid subscription. That is what the trial is for: try everything on your real site, and if it isn't right for you, cancel during the 7 days and you won't be charged.

Cancelling

Cancel from your account page at speedoflight.pro/account or from the Freemius customer portal. If anything is unclear, email help@speedoflight.pro and we'll help.

Activating your license

Install and activate the plugin

Upload the plugin zip under Plugins → Add New → Upload Plugin and activate it. Page caching starts working right away.

Activate your license

Open SOL in the wp-admin menu. Until a license is active, the SOL screens show the license activation screen. Enter the license key from your purchase email.

Done

Cloud optimization, Insights and Autopilot switch on automatically. There is no separate API key to paste. Your license, plan and renewal date are on the Account page in the SOL menu.

Moving a license to another site

Each activation uses one of your tier's sites. To move a license, deactivate it on the old site from that site's Account page, then activate it on the new site. If the old site no longer exists, or you'd like a hand, email help@speedoflight.pro with both site addresses.

On a staging copy of a live site, Speed of Light pauses Cloudflare changes until you confirm the new address, so a copy can never purge or reconfigure your live zone (see Cloudflare edge).

If your license expires

Keeps working:

  • Page caching.
  • The local optimizations you've turned on.
  • Your settings.

Stops until you renew:

  • Cloud optimization.
  • Autopilot.
  • Cloud scans in Insights.
  • Plugin updates and support.

Your site stays cached and fast. Speed of Light shows an alert explaining that cloud optimization is paused, with a button to your Account page. Renew and the cloud features resume.

Questions about billing, tiers or your license? Email help@speedoflight.pro.

NextPage cache

Caching

Page cache

The page cache turns each page into a ready-made HTML file on disk. When a logged-out visitor asks for a cached page, they get that file straight away. Loading WordPress, running plugins, querying the database and rendering the theme are all skipped. This is the biggest speed win the plugin delivers, and most sites need no configuration at all.

Page caching is always on. There is no switch to flip. Everything below covers the few cases where a page should not be cached, how freshness works, and how to control both.

How a cached page is served

Speed of Light installs a small drop-in, wp-content/advanced-cache.php, and sets WordPress's WP_CACHE flag. The drop-in runs before WordPress finishes loading, so a cache hit is answered without booting WordPress core, your plugins or your theme. On each request it:

  1. Works out which cached file matches this request (see Cache variants below).
  2. Checks that the request is a normal, logged-out page view and that a fresh file exists.
  3. Sends the stored HTML and stops. If there is no valid file, WordPress builds the page as usual and the result is stored for next time.

How to tell whether a page was cached

Look at the X-SOL-Cache response header in your browser's developer tools, in a private window:

  • HIT: served from the cache.
  • MISS: no cached copy existed yet. This one was built and stored.
  • BYPASS: deliberately not cached, for example because of a cookie or a private header. SOL → Health tells you why.

Every response also carries X-Cache-Plugin: SpeedOfLight.Pro, but that header only shows the plugin is active. It doesn't mean the page was a cache hit. Cached pages also support Last-Modified / 304 Not Modified.

Safe writes, and the original page as a fallback

Each cache file is written to a temporary file first, checked, and only then moved into place. A visitor never gets a half-written page. If any optimization step fails, returns nothing or would cut the page short, the original page is served instead and the event is logged. A cache-write error can't blank a page.

Gzip and Brotli

Compress cached pages is on by default. When a page is cached, a gzip (.gz) copy is stored with it, plus a Brotli (.br) copy when your server has the Brotli extension. Browsers that accept compression get the pre-compressed bytes, and the plain file remains as a fallback.

Cache variants

One URL sometimes needs different versions for different visitors. Speed of Light stores these as separate files, chosen by the request, never by who the visitor is:

  • Scheme: http and https are cached separately.
  • Language: on Polylang and WPML sites, the language cookie is part of the key, so each visitor gets the right translation.
  • Device: only with Separate mobile cache (advanced), which is off by default. Responsive themes should leave it off and share one version.
  • WebP: with Serve WebP images when available (on by default), browsers that accept WebP get a version that points at WebP images.
  • Encoding: the Brotli and gzip copies.

What is never cached

Logged-in users and sessions

Logged-in users are never cached, even when your site uses a custom login cookie name. Speed of Light also skips the cache when it sees any of 21 built-in cookie patterns:

  • WordPress login cookies (wordpress_logged_in, wordpress_sec, wordpress_no_cache).
  • Password-protected posts (wp-postpass) and commenters (comment_author).
  • WooCommerce and Easy Digital Downloads carts and sessions.
  • Cart and session cookies from other store and booking plugins, such as YITH, Ecwid and Bookly.

Cookies you add under Excluded Cookies (regex) are added to this list. They don't replace it.

Pages that set a cookie or are marked private

A page isn't stored when the response sets a cookie, or sends a Cache-Control header containing private, no-store or no-cache. These responses get X-SOL-Cache: BYPASS and are never given a public cache header. WPML and Polylang language cookies are the exception, because they don't change who the visitor is.

If a theme or plugin sets a cookie on every visit, caching would quietly stop working. The Health check Pages can be stored in the cache and the Alerts centre name the cookie or header and the page it was seen on. If the cookie never changes what a page shows, allow it:

// Let pages that set this harmless cookie be cached. A trailing * matches a prefix.
add_filter( 'sol_cache_allowed_set_cookies', function ( $names ) {
    $names[] = 'my_theme_banner_seen';
    return $names;
} );

Request types

A request is also skipped when:

  • It isn't a GET request, so form submissions are never cached.
  • The response isn't a normal 200 OK. This includes 404 pages, even when a theme sends them with a 200 status.
  • It is wp-admin, the login page, the REST API (/wp-json/) or XML-RPC.
  • It is a feed, trackback, robots.txt, a preview or a search results page.
  • The URL ends in .ico, .txt, .xml or .xsl, or the output isn't a complete HTML document.
  • The page is password-protected and the password hasn't been entered.
  • The URL has a query string, unless every parameter is a known tracking parameter (utm_*, gclid, fbclid, msclkid and many more). Shared campaign links still get the cached page. Developers can add parameters with the sol_cacheable_query_params filter.

Excluding your own pages

Cache → Exclusions lets you keep specific pages out of the cache. Excluded pages are also skipped by the preloader and by every optimization, so they are served exactly as your theme renders them. You can exclude by:

  • Post IDs and post types (singles and their archives).
  • Excluded Page Paths, one per line, matched against whole path segments from the start of the path:
    • /cart matches /cart and /cart/…, but not /cartoons.
    • A trailing * makes a prefix: /form* matches /forms and /formula.
    • A line that starts with ^, or is wrapped in #…#, is a regular expression.
    • The default list is /wp-admin, /wp-login.php, /xmlrpc.php, /wp-json, /cart, /checkout and /my-account. On update, an untouched old default list is replaced with this one, and a list you have edited is kept.
  • Excluded URLs, one per line, with * wildcards.
  • Excluded Query Strings (regex) and Excluded Cookies (regex).

Excluding a page from code

Define the standard DONOTCACHEPAGE constant while a page is being built, and it won't be stored:

if ( ! defined( 'DONOTCACHEPAGE' ) ) {
    define( 'DONOTCACHEPAGE', true );
}

For finer control, use the sol_bypass_cache filter. It receives the plugin's own decision. Return true to skip caching for this request:

add_filter( 'sol_bypass_cache', function ( $bypass ) {
    return $bypass || is_page( 'live-scores' );
} );

Both of these decide whether a page is stored. They run inside WordPress, which is too late to stop a copy that is already cached from being served. Clear that page once after adding the rule.

Cache lifetime and automatic clearing

Cache Expiry

Set the lifetime under Cache → Local Cache → Cache Expiry: Never, 1 hour, 6 hours, 10 hours (recommended), 12 hours, 24 hours, 7 days or 30 days. New installs use 10 hours.

Many forms and buttons include WordPress security tokens (nonces), which stop working after 12 to 24 hours. So pages that contain a token for logged-out visitors are always rebuilt within 10 hours, whatever the lifetime setting, even Never. Per-Path Cache TTL lets you give specific URL patterns their own lifetime. The most specific pattern wins.

Clearing when content changes

Under Cache Clearing Rules, these are all on by default: Clear cache when posts are saved, …when comments change, …when taxonomies edited, …when users change and Clear cache on plugin/theme changes. Here is what each event clears:

  • A post or page is published, updated or deleted: its page, its paginated, comment-page and AMP copies, the blog index, its post-type archive, its category, tag and term archives (including parent terms), its author archive and date archives. On multilingual sites, linked translations are cleared too.
  • An approved comment is added, edited, approved, unapproved or deleted: only its post, that post's comment pages and archives. Comments waiting for approval don't clear anything.
  • A user profile is updated: only that author's archive.
  • A category, tag or other term changes: the site cache, once per request. With Clear cache when taxonomies edited off, only that term's archive is cleared.
  • A site-wide design change: the whole page cache, once per request. This covers menus, the Customizer, theme options, widgets, block-theme templates, template parts, global styles, synced patterns and page-builder templates.
  • WooCommerce: stock changes clear the product. New orders clear the ordered products, the shop page and product archives.

Repeated saves of the same post within two minutes are grouped into one clear. Accented and non-Latin URLs are cached and cleared under one key, however they were percent-encoded.

Extreme Cache Mode (off by default) never clears automatically and sets the lifetime to Never. It is only for sites that clear the cache themselves. Leave it off unless you are sure.

Clearing manually

The SOL menu in the admin bar offers Purge Local Cache and, while you view a post, page or archive, Purge Page Cache. When Cloudflare is connected it adds Purge Edge Cache, and when Speed of Light's Redis object cache is active, Flush Object Cache. The Dashboard's Quick actions and wp sol clear work too. A full clear also asks supported host caches (SiteGround, SpinupWP, WP Engine, Pantheon and Cloudways/Breeze) and Cloudflare, when connected, to purge their copies.

If you change content directly in the database, or through a route that doesn't fire WordPress hooks, Speed of Light can't know about it. Clear the affected pages by hand.

HTML minify

Minify HTML output and Minify embedded styles & scripts (under Cache → Local Cache) are opt-in and off by default, because they rewrite every cached page. In 1.5.30 the minifier was rebuilt to be careful:

  • Comments are removed only outside scripts, styles, templates and preformatted text.
  • Protected elements end only at their own closing tag.
  • Whitespace inside attributes is kept.
  • A page that would lose its closing </html>, or shrink by more than 30%, is served unminified instead.

Check a few pages after turning it on.

Built to stay working

  • The drop-in no longer deletes itself during plugin updates, and a missing drop-in is rebuilt automatically. You'll see a notice and an alert when that happens.
  • If another plugin owns advanced-cache.php, Speed of Light never overwrites it. It pauses page caching and tells you which plugin to deactivate.
  • Plugin upgrades run once, behind a lock, not on many visitor requests at the same time.
  • On multisite, deactivating Speed of Light on one site doesn't switch caching off for the rest of the network.

NextObject cache (Redis)

Caching

Object cache (Redis)

Object caching is optional. The page cache already serves finished HTML to your visitors. The object cache helps the parts of WordPress that still run: wp-admin, logged-in users, WooCommerce carts and checkout, search, and the first visit to any page. If you don't have a Redis server, leave it off. You lose none of the page-caching speed.

The two caches do different jobs:

  • The page cache stores the finished HTML of a page and serves it to logged-out visitors without running WordPress.
  • The object cache stores the results of database lookups: options, posts, terms, user data, and anything a plugin asks WordPress to remember. WordPress normally throws these away after every request. With a persistent object cache in Redis, they survive between requests, so the same query doesn't hit MySQL again and again.

What powers it

Speed of Light has its own Redis object-cache engine. Turning it on installs a drop-in called object-cache.php in wp-content. WordPress then uses Redis for its object cache on every request, front end and admin alike. The drop-in is stamped with Speed of Light's name, so the plugin can recognize it, keep it up to date and remove it cleanly. It uses the phpredis extension when your server has it. Otherwise it uses the Predis library, which ships with the plugin, so all you need is a reachable Redis server.

Enabling object caching

Open Object Cache

Go to SOL → Object Cache. If no Redis server can be reached, it says so and won't let you enable caching. Page caching keeps working either way.

Enter your connection

Pick a quick setup preset: Local Redis — TCP (127.0.0.1, port 6379), Local Redis — Unix socket or Remote Redis — TLS (encrypted). Or fill in the host, port, database (0–15) and password yourself. The password is write-only: it is never sent back to your browser, and leaving the field blank keeps the saved one. Click Save connection.

Test the connection

Test connection checks your saved settings without touching the live cache. A success reads like "Connected via TCP (0.4 ms, Redis 7.2)". A failure explains what went wrong, such as the wrong host, password or port, or a firewall.

Enable the object cache

Click Enable object cache. Speed of Light tests the connection again first. If Redis can't be used, it doesn't enable anything and tells you why. Your site keeps using the normal WordPress cache, so nothing breaks.

The drop-in is written to a temporary file and then moved into place, so a visitor never loads a half-written file. If another plugin already owns object-cache.php, Speed of Light won't overwrite it and asks you to remove the other one first.

Host settings are respected

Many managed hosts define their Redis connection with WP_REDIS_* constants in wp-config.php. Speed of Light reads settings in this order: what you saved in the plugin, then its own SOL_REDIS_* constants, then the host's WP_REDIS_* constants. Plain default values never override a host's own settings, so a pre-configured server works out of the box.

Where your password is stored

Connection settings are written to wp-content/sol-object-cache-config.php with owner-only permissions (0600), so other accounts on shared hosting can't read it. Non-secret settings you changed are also mirrored into wp-config.php as SOL_REDIS_* constants. The password never is. If you prefer, define the password yourself in wp-config.php.

Keys, expiry and shared Redis servers

  • Unique per site. Every key gets a prefix built from your database details and a secret salt, so several sites can share one Redis server safely. Set your own under Key prefix (optional), or with WP_CACHE_KEY_SALT.
  • Nothing lives forever. Keys expire after 30 days by default, so a value left behind by an outage or a missed update can't stay forever. Change this with WP_REDIS_MAXTTL or SOL_REDIS_MAXTTL (in seconds).
  • Flush only touches your keys. Flushing removes this site's prefixed keys only, never other applications' data in the same Redis database.

If Redis goes down

A Redis outage never takes your site down. If Redis is unreachable (stopped, blocked, wrong password or a network drop), the drop-in tells WordPress the cache isn't persistent for that request:

  • Transients fall back to the database, exactly as they would without an object cache, so they keep working and aren't lost.
  • Other cached data only lasts for the current request. Your site runs as it would with no object cache: a few more database queries, but no errors.
  • The panel shows Enabled — running in memory with the reason, and the Alerts centre says "Redis isn't answering, so the object cache is running in fallback mode".
  • When Redis comes back, the first connected request flushes this site's keys once, so nothing cached before the outage can be served stale.

For an emergency switch-off without removing the drop-in, define WP_REDIS_DISABLED or SOL_REDIS_DISABLED as true in wp-config.php.

Value compression and serialization

Compress cached values is on by default. Values over 1 KB are compressed with the best codec your server has (zstd, then lzf, lz4 and gzip), and stored compressed only when that is actually smaller. Each value records which codec wrote it, so older values still read correctly after a change. If a codec goes missing, that value is simply a cache miss. If the igbinary extension is installed, it is used automatically for smaller, faster values. Values that can't be stored safely, such as closures, are skipped.

Live diagnostics

Once running, the panel shows the hit ratio, hits and misses, backend and status, transport (Unix socket, TCP or TLS), client (phpredis or Predis), serializer, compression, max TTL and the last connection error. With phpredis, it also shows Redis server health: version, memory used, the maxmemory policy, evicted and expired keys, uptime, clients, operations per second and key count.

Watch evicted keys. A steadily climbing number means Redis is full and is throwing data away to make room, so your instance needs more memory or a different eviction policy.

Multisite

A network has one object-cache.php drop-in and one connection setup, managed for the whole network. Each site's keys are still kept separate, and network-wide data is shared where WordPress expects it. Deactivating Speed of Light on one site leaves the object cache in place for the rest of the network.

WP-CLI

# Drop-in state, connection, hit ratio and Redis version
wp sol object-cache status

# Install or remove the drop-in
wp sol object-cache enable
wp sol object-cache disable

# Refresh the drop-in to the current plugin version
wp sol object-cache update-dropin

# Flush only this site's keys
wp sol object-cache flush

# Detailed diagnostics, and the global / non-persistent cache groups
wp sol object-cache diagnostics
wp sol object-cache groups

Standard commands such as wp cache flush also work while the drop-in is active.

Updating and removing

The drop-in refreshes itself when the plugin updates, and an Update drop-in button appears if it is ever out of date. Turning object caching off (in the panel or with wp sol object-cache disable) flushes this site's keys, removes the drop-in and the SOL_REDIS_* block from wp-config.php, and leaves your host's WP_REDIS_* constants alone. Every other Speed of Light feature keeps working.

NextPreloader

Caching

Preloader

A cache only helps visitors who arrive after a page has been cached. The first visitor to a new or just-cleared page normally waits while it is built. The Preloader removes that wait. It visits your own pages in the background and writes the cache files before a real person asks for them, so visitors get a cache HIT from the first request.

What the Preloader does

The Preloader keeps its work list in its own database table and fills it in small steps. It also requests each page exactly as a modern browser would.

  • Where the URL list comes from. With Automatic sitemap discovery (on by default), it reads your sitemaps in this order: a custom sitemap, then Yoast, Rank Math, WordPress core, or the one listed in robots.txt. Without a sitemap, it falls back to your published posts and pages. A Custom sitemap URL must be on your own domain (www and non-www both count), or it is ignored.
  • Most important first. By default it warms the 50,000 most important URLs: home page, recently changed content, main archives, then everything else newest first. Anything beyond that is cached on its first visit. See Large sites.
  • Honest counts. A page counts as cached only when a readable cache file exists on disk. If a page answered but no file was written, the Preloader writes it from the response when that is safe.
  • Exclusions are respected. Anything excluded from caching is never queued, warmed or optimized.

Automatic warming

You rarely need to start a preload by hand:

  • A first preload starts by itself after activation.
  • When pages are cleared because you edited content, the affected URLs are queued again and re-warmed in the background.
  • When Cloudflare is connected, rebuilt pages are also refreshed at the edge.

Warms the version your visitors read

With Serve WebP images when available on (the default), browsers that accept WebP get their own cached version of each page. The Preloader sends the same Accept header a real browser sends, so it warms that version, not one nobody reads. If you turn on Separate mobile cache (advanced), it warms the mobile version too.

Runs by itself, no cron setup needed

A preload keeps going after you close the dashboard, even on hosts that disable WP-Cron. Three things keep it moving:

  • Background loopback. After each batch, the Preloader sends a small internal request that starts the next one.
  • WP-Cron fallback. A scheduled event picks up the next batch on hosts that block loopback requests.
  • Stall watchdog. If both are blocked, the next admin page load nudges the crawl forward. This runs at most once a minute and never starts a new crawl.

Gentle on your server

The Preloader adjusts to how your server responds:

  • In standard mode it starts with 2 parallel requests and pauses at least 10 seconds between batches.
  • It halves its speed on timeouts, on 429, 503 or 508 responses, when most responses are 5xx errors, or when pages are very slow. It speeds up again after three healthy rounds.
  • After three bad rounds in a row it pauses for 10 minutes.
  • Timed-out pages are retried later, never in the same batch. A page that still fails is left to be cached on its first visit.

The Alerts centre tells you when the Preloader is "running slowly to protect your server" or has paused. The progress view shows the current rate, an estimated time remaining and a time-per-1,000-URLs estimate. Redirects to other pages on your site are followed, and the final page is warmed.

Turbo Mode

Turbo Mode starts at full speed with shorter pauses for a fast rebuild, for example after a big import. It still backs off if your server struggles, and switches itself off when the queue is empty. Use standard mode on shared or modest hosting.

When a firewall or CDN blocks the crawl

Some CDNs, web application firewalls and security plugins answer automated requests with 403 Forbidden, even though browsers load the page fine. If nothing could be cached, the error message names what blocked the crawl:

  • Cloudflare or another CDN edge (with the Cloudflare Ray ID when there is one).
  • ModSecurity, a web application firewall on your server.
  • Wordfence.
  • Your web server itself: nginx, Apache or LiteSpeed.

Each recorded failure keeps the HTTP status, the server that answered and a short snippet of the block page, so your host can find the rule. The 20 most recent failures are kept.

To let the Preloader through, allow your own server's IP address in the blocking layer. Preloader requests also carry an X-SOL-Preload: 1 header and a user agent ending in SpeedOfLightPreloader/. These help you recognize the requests, but anyone can copy a header, so allowlisting by IP is safer.

Developers can adjust preload requests with the sol_preload_request_args, sol_preload_user_agent and sol_preload_sslverify filters. Preload requests always go to your site's own address, and the SpeedOfLightPreloader/ marker is always kept. Plugins and themes can check sol_is_preload_request(). Post Views Counter and WP Statistics already ignore preloads, so warming never inflates your view counts.

Running a preload from the dashboard

Open the Local Queue

Go to SOL → Cache → Local Queue. It checks that the Speed of Light drop-in is installed. If another caching plugin owns it, disable that plugin first.

Start the preload

Click Start Preload, or Preload Cache under Local Cache → Actions. You can leave the page and it keeps running.

Watch or adjust

Progress shows cached, pending and expired pages. Switch on Turbo Mode for a faster crawl, or click Stop Preloading to clear the queue. Under Preload Settings you can change URLs per batch (default 50, maximum 500) and Delay between batches.

Preloading from WP-CLI

# Queue the priority URLs and warm them in the background
wp sol preload

# Faster crawl on a well-resourced server
wp sol preload --turbo

# Warm in this process and wait for the result (good for deploy scripts)
wp sol preload --run

# Stop after 5 minutes, or pause 2 seconds between batch windows
wp sol preload --run --max-seconds=300
wp sol preload --run --sleep=2

Sizing flags apply to one run only:

  • --batch sets URLs per batch.
  • --concurrency is the most parallel requests allowed. Standard mode still starts at 2 and backs off.
  • --chunk sets URLs per worker window, and --runtime sets seconds per window.
  • --delay sets the pause between batches. Standard mode never pauses less than 10 seconds.

Turbo Mode uses its own sizing, so --batch and --delay have no effect together with --turbo. A --run ends with a Cached / Pending / Failed summary. "Queued N URLs" counts the first priority set; the rest are added in the background.

wp sol clear clears the cache, optionally for specific --ids, --urls (wildcards allowed) or --sites. Cleared pages are re-warmed automatically.

Run wp from the correct WordPress path and as the right user. If Redis gets in the way of CLI runs, define WP_REDIS_DISABLED as true in wp-config.php for those runs. It is a PHP constant, so setting it as an environment variable does nothing.

Reading the results

Pages the cache deliberately declines, for example because the response sets a cookie (X-SOL-Cache: BYPASS), are skipped, not counted as failures, and not retried. Health explains why they aren't cached. A real failure is usually a firewall or CDN blocking the crawl, which you can fix by allowing it through as described above. If you're stuck, email help@speedoflight.pro with the failure details and we'll help.

NextLarge sites

Caching

Large sites

Speed of Light works the same on a 20-page brochure site and on a store or publication with hundreds of thousands of URLs. On large sites, a few parts of the plugin change how they behave so your server stays comfortable and your most important pages are fast first.

A preload queue built for big sites

The preloader keeps its work list in its own database table, not in a WordPress option. It fills the queue in small steps from your XML sitemaps (custom sitemap, Yoast, Rank Math, WordPress core, or the one listed in robots.txt). Sites without a sitemap fall back to your posts. Because the list never has to fit in memory at once, very large sites don't run into PHP memory or database packet limits.

A custom sitemap URL must be on your own domain. Sitemaps on other domains are ignored.

Smart warm: the most important 50,000 URLs first

On a big site, warming every URL would take a long time and keep your server busy. By default the preloader warms the 50,000 most important URLs in this order:

  1. Your home page.
  2. Recently changed content.
  3. Your main archives.
  4. Everything else, newest first.

Pages beyond that are still cached. They are cached the first time someone visits them, and stay fast for everyone after that. The preloader shows this as "Warming the top N URLs… Other pages are cached automatically on their first visit."

To warm more (or fewer) URLs, use the sol_preload_max_urls filter. Values are kept between 100 and 1,000,000.

// Warm up to 100,000 URLs per crawl (PHP 7.4+).
add_filter( 'sol_preload_max_urls', fn() => 100000 );

Raising the limit doesn't make a crawl any more aggressive. It just takes longer to finish. Check that your server copes comfortably at the default before you raise it.

Gentle on your server

The preloader watches how your server responds and adjusts to it:

  • It starts with 2 parallel requests and pauses between batches.
  • It slows down when your server returns errors (for example 429, 503 or mostly 5xx responses), times out or answers slowly, and speeds up again once things look healthy.
  • After repeated overload it pauses for 10 minutes. The Alerts centre tells you "Cache warm-up paused to protect your server".
  • Requests that time out are retried later, never immediately in the same batch.

Turbo Mode starts at full speed for a faster rebuild, but it still backs off under load. Use it on servers with headroom. For all preloader settings and WP-CLI options, see Preloader.

Cloud plans for pages that haven't been scanned yet

A large site has far more pages than the cloud can render every day, so Speed of Light uses template-based plans. It learns which template each page uses: a single post, a product, a page template, a category archive and so on. When a page has no cloud plan of its own yet, it can borrow a recent plan from a page with the same template. Borrowed plans cover critical CSS, safe used CSS, layout-shift reservations and the role of the main image. The CSS parts only apply if you've turned those tools on.

  • A page's own plan always wins. A borrowed plan is a stopgap, replaced as soon as that page's own plan arrives.
  • Borrowed plans never drive Autopilot or Insights. Decisions and findings are based only on pages the cloud actually measured.
  • Archive pages can get cloud plans too, not just posts and pages.
  • The preloader requests plans for priority pages (home, recently changed content and main archives) within a daily budget, so the pages that matter most are measured first.

Plans you already have keep being used when comments, posts, terms or users change, and while new cloud requests are paused.

  • Use a persistent object cache. Pages that are always built fresh (logged-in users, carts, search, the first visit to a long-tail page) make many database queries. Redis lets WordPress reuse their results. See Object cache (Redis).
  • Keep the cache lifetime sensible. The default 10 hours works well. Content changes clear the right pages anyway.
  • Use Cloudflare edge caching if your audience is spread around the world. See Cloudflare edge.
  • Watch the Alerts centre for preloader slow-downs, low disk space or cookies that stop pages from being cached. See Alerts centre.

NextCloudflare edge

Caching

Cloudflare edge

Edge Cache connects Speed of Light to your Cloudflare account, so your ready-made HTML pages are cached across Cloudflare's global network, not only on your own server. A visitor in another country gets the page from the data centre nearest to them, without the request reaching your server at all.

It works on the free Cloudflare plan. Speed of Light uses Cloudflare's modern Cache Rules and creates no Page Rules. You don't need paid add-ons such as APO or Argo.

What it caches

Only public HTML for logged-out visitors. These are always passed straight through to your server:

  • Logged-in users, shoppers with a cart, commenters and password-protected pages.
  • Visitors with a WPML or Polylang language cookie, or a Wordfence login cookie.
  • URLs with a query string, including campaign links.
  • Responses marked private or no-store, and error pages. These are never stored at the edge.

Edge caching is Cloudflare-only. To serve images, CSS and JavaScript from a different CDN, use Cache → CDN, which rewrites asset URLs for any CDN.

Connecting Cloudflare

Open SOL → Cache → Edge Cache and follow the three steps:

1. Account

Create an API token in Cloudflare with these permissions:

  • Zone → Zone → Read
  • Zone → Cache Purge → Purge
  • Zone → Cache Rules → Edit

Add Zone → Firewall Services → Edit only if you want the optional scanner allowlist described below. Paste the token into Cloudflare API Token and click Connect Cloudflare.

2. Site

Choose your domain under Select Site and click Use This Site. There is no Zone ID to look up.

3. Deploy

Click Deploy Rules. Speed of Light creates its cache rule and purges the edge once, so caching starts clean.

New connections use scoped API tokens. Cloudflare's Global API Key is no longer accepted, because it can do anything on your account. An older connection made with a Global API Key keeps working, with a prompt to switch. Saving a token deletes the stored key.

Your credentials stay on your server

Your token is stored on your WordPress site and used only for server-to-server calls to Cloudflare. It is never sent back to your browser (the screen only shows whether one is set), and it is removed from settings exports.

How the managed rules work

The HTML rule is named Speed of Light: Edge Manager (Full Page HTML) [SOL_MANAGED]. The [SOL_MANAGED] marker is how the plugin recognizes its own rules:

  • Redeploying replaces the previous HTML rule, so duplicates never pile up.
  • Rules you or other tools created are never touched.
  • Switching Edge Cache off removes the HTML rule and purges the edge once.
  • Rules re-deploy themselves after a plugin update.

The separate Asset Versioning card adds version stamps to your local CSS and JavaScript URLs and edge-caches them for one year, with its own rule (Speed of Light: Asset Manager (versioned CSS/JS) [SOL_MANAGED]). Use Deploy / Update Asset Rule and Remove Asset Rule. It is independent of the HTML rule.

Lifetime and exclusions

Edge Cache TTL sets how long Cloudflare keeps a page: 30 minutes, 1 hour, 2 hours, 4 hours (default), 12 hours, 24 hours, 7 days or 30 days. You rarely need a short lifetime, because Speed of Light purges the edge whenever content changes.

Edge Cache Exclusions lists paths that are never edge-cached. It starts with /wp-admin/, /wp-login.php, /xmlrpc.php, /wp-json/, /cart/, /checkout/ and /my-account/. Your page paths, query strings and cookies under Cache → Exclusions are added to the edge rule automatically, and the rule re-deploys when you change them.

Cloudflare limits a rule to 4,096 characters. Speed of Light removes duplicate patterns, and if a heavily customized site would still go over, it drops the lowest-value exclusions first and logs what it dropped. Those are feeds, sitemaps, robots.txt, XML-RPC and store API paths. Logged-in users, carts, password-protected pages, wp-admin, login, the REST API, cart, checkout and my-account are always kept.

Tiered Cache (free) is an optional switch, off by default, that turns on Cloudflare's tiered caching for your zone.

Staging copies can't touch your live zone

Speed of Light remembers the site address Cloudflare was connected on. If the site address changes, as it does on a staging copy or a clone, it pauses every Cloudflare change from that copy: purges, rule deploys, scanner rules and deactivation clean-up. The Alerts centre shows "Cloudflare changes are paused on this copy of the site" with a button to confirm the new address. Connecting new credentials or choosing a site again also confirms it.

Allowing the Speed of Light scanner

If Cloudflare's security settings block the cloud scanner, Insights scans fail. Allow the Speed of Light scanner through Cloudflare is optional and off by default for new connections. When you turn it on, Speed of Light adds Cloudflare IP Access "Allow" rules for the scanner's addresses only. Those rules are removed when you turn the option off or deactivate the plugin. The status line offers Add rules now, Try again and Copy IPs.

The edge stays fresh automatically

Speed of Light purges the affected URLs at the edge when something changes:

  • A post or page is published or updated: that URL and its related archives (home, category and tag pages, author, feed, shop pages).
  • A page is unpublished, trashed or deleted: its URL, so a removed page never keeps being served.
  • An approved comment or a WooCommerce stock change: the affected post or product.
  • A category, tag or term is created, edited or deleted: its archive and the home page.
  • A theme switch, Customizer save, menu or widget edit, or key site settings change: a full purge, because these can affect every page.

Purges are combined into one call per request and throttled, so a burst of edits never floods Cloudflare. If Cloudflare keeps refusing purges, the Alerts centre says so.

Purging manually

  • Purge Edge on the Edge Cache screen clears the whole zone immediately.
  • The admin bar's SOL menu has Purge Edge Cache.
  • wp sol clear clears the local cache and queues one combined edge purge.

103 Early Hints

103 Early Hints let the browser start connecting and downloading key files while your server is still preparing the page. Turn on Enable Early Hints (103) under Optimize → JavaScript. It is on by default and only takes effect when Cloudflare is in front of the site. Also turn on Early Hints in your Cloudflare dashboard. Hints are only sent on safe, cacheable pages that return 200, never to logged-in users or on admin, API, feed or error responses.

For pages served from the cache, hints come from the page's own preload and preconnect tags, up to six per page. Developers can adjust them with sol_early_hints_cached_links (arguments: the links and the cache file). For pages WordPress builds, use sol_early_hints_links (arguments: the links and the settings):

add_filter( 'sol_early_hints_links', function ( $links, $settings ) {
    $links[] = '<https://example.com/fonts/brand.woff2>; rel=preload; as=font; crossorigin';
    return $links;
}, 10, 2 );

Deactivating

Deactivating the plugin removes the rules it created (HTML, asset and scanner rules) and purges the edge once. This clean-up is skipped on a staging copy. Settings → Reset deletes the Cloudflare connection and removes the scanner rules.

Edge caching only starts once Cloudflare is connected with a token, a site is selected and the rules are deployed. If Edge Cache is switched off or Cloudflare can't be reached, pages are still served from your local cache. Nothing breaks: you just lose the edge layer until it is reconnected.

NextCSS optimization

Optimization

CSS optimization

Stylesheets are render-blocking: the browser won't draw anything until it has downloaded and read every stylesheet a page links to. Speed of Light has four tools to fix this, all under SOL → Optimize → CSS: Minify CSS, Combine & Defer CSS, Remove Unused CSS and Critical CSS.

All four are off by default. No CSS is minified, combined or removed until you turn a feature on. Autopilot never turns on Critical CSS or Remove Unused CSS. Turn features on one at a time and check your key pages after each.

Choose one delivery method

Combine, Remove Unused CSS and Critical CSS each rewrite how stylesheets are delivered, so only one of the three can be on at a time. Turning one on switches the others off. Minify works with any of them.

  • Remove Unused CSS: the biggest cut in CSS size, page by page.
  • Critical CSS: the fastest first paint. The top of the page is styled immediately and the rest loads afterwards.
  • Combine: fewer requests, for sites with many small local stylesheets.

Minify CSS

Minify rewrites your local static .css files without comments and extra whitespace, stores them under wp-content/cache/sol/assets and serves them in place of the originals. It is careful where simple minifiers go wrong:

  • It keeps the meaningful space in selectors such as .parent :is(...).
  • It leaves + inside calc() and the >= / <= media-query range syntax alone.
  • It doesn't drop rules after comments that contain apostrophes.

Relative URLs inside your CSS are rewritten so nothing breaks when the file is served from the cache. @import "file.css" is rewritten too, while url(#id) references stay untouched. Stylesheets generated by PHP are never copied into the cache.

Very small minified files (up to 4 KB each, 16 KB per page) are inlined into the page to save a request. Developers can tune this with the sol_css_inline_small_minified_enabled, sol_css_inline_small_file_threshold and sol_css_inline_small_page_budget filters.

Combine & Defer CSS

Combine merges neighbouring local stylesheets that share the same media type into bundles, which are then minified. A small bundle (30 KB or less) is inlined into the page. A larger one is saved as a cached file and loaded normally. Despite the name, Combine doesn't defer CSS, because deferring everything without above-the-fold styles would cause a flash of unstyled content.

The bundle rebuilds itself when any source file changes, and stylesheets keep their place relative to inline <style> blocks, so the order your styles apply in doesn't change. These are left out:

  • Sheets with @import, sheets from other domains, and anything in the exclude list.
  • Print stylesheets, and links with integrity, disabled, title, event or data- attributes. These are left completely untouched.
  • Pages the preloader warms: these get Minify but not Combine.

Remove Unused CSS

For each URL, Remove Unused CSS compares every stylesheet rule with the page's HTML and writes a lean used CSS file containing only the rules that page needs. Your home page, a blog post and a product page each get their own trimmed CSS. On licensed and trial sites, used CSS generated by the cloud, from a real browser render of the page, replaces the locally generated file when it is available.

Built to keep what you need

A large built-in safelist

Class prefixes for WordPress core and blocks, the admin bar, WooCommerce, the major page builders, common sliders, lightboxes, animation libraries, form plugins, cookie banners, ad containers, and states like active and open are always kept.

Builder-aware detection

Speed of Light detects Elementor, GreenShift, Divi, Beaver Builder, Bricks, Breakdance, Oxygen, block themes and WooCommerce. It adds their class patterns, and leaves stylesheets that are too dynamic to trim alone (see Compatibility).

Cautious matching

Any rule with a pseudo-class or pseudo-element (:hover, ::before, :has() and so on), a * or an attribute selector is always kept.

The safety fallback

With Keep original CSS as a safety fallback (on by default), the original stylesheets still load after the used CSS, without blocking the first paint, and with a <noscript> copy. Anything the matcher missed is restored a moment later. Cloud-generated used CSS always keeps this fallback.

Remove Unused CSS also:

  • Keeps the original order of your stylesheets.
  • Leaves inline <style> blocks where they are, such as the layout CSS block themes print.
  • Leaves sheets alone that use native CSS nesting, @layer statements or empty custom properties.
  • Serves the original CSS when a large stylesheet would shrink to something implausibly small, or when generation takes too long.
  • Pulls @import rules into the used-CSS file.
  • Skips search pages, form submissions, excluded URLs and AMP pages.

Generated CSS files that are no longer used are removed after 30 days.

Your own exclusions

Under Advanced CSS options:

  • CSS selectors to safelist from RUCSS takes one class or ID prefix per line. Enter it without the leading dot, for example my-plugin-.
  • Exclude stylesheets from RUCSS matches part of a stylesheet's URL. It starts with fonts.googleapis.com, font-awesome and dashicons.
  • Add data-sol-no-rucss to a stylesheet's tag in your theme to keep that sheet out.
  • To switch Remove Unused CSS off for a single post or page, open it in the editor and tick Disable Remove Unused CSS in the SOL Optimization box.

Critical CSS

Critical CSS works out the styles needed to paint the top of the page and inlines them in the HTML. The rest of your CSS then loads without blocking the first paint. Critical CSS is generated and cached for each URL, keyed by a cleaned-up form of the address, so clearing one page regenerates only that page. On licensed and trial sites, critical CSS from the cloud's real browser render replaces the local version when it is available.

  • Stylesheets are only deferred when there is enough critical CSS to trust (more than 500 bytes).
  • Deferred stylesheets keep their original media query and have a <noscript> fallback.
  • Rules for :root, html, body and * are always included.
  • @supports, @layer and @container are handled, and relative URLs are resolved correctly.
  • Any @font-face rule in the inlined CSS gets font-display: swap if it has no display setting, so headings never stay invisible while a font loads.

Deferred sheets load with the proven media="print" / onload technique. An alternative data-href method is available for themes where that misbehaves.

Themes with their own critical CSS. Several themes and builders already generate above-the-fold CSS. Speed of Light recognizes them and doesn't defer their stylesheets, which would only push your first paint later. Developers can change this with the sol_critical_css_theme_skip filter.

Things every CSS feature respects

  • Logged-in users always get your full, unmodified CSS, so editing never breaks.
  • AMP pages are skipped by every CSS optimizer.
  • If an optimization step fails, the original page is served and the problem is logged.
  • The cloud scanner skips Critical CSS deferral and CSS trimming when it loads a page, so it measures your real layout.

Fonts

The Font Optimization card on the same screen holds Self-host Google Fonts and Preload fonts, both off by default. See Fonts & Gravatars.

A sensible order

  1. Turn on Minify CSS. It is the safest win.
  2. Choose Remove Unused CSS or Critical CSS, keeping the safety fallback on while you check pages.
  3. Use Combine instead only when you have many small local stylesheets and don't use the other two.

After each change, clear the cache and load your key pages in a private window. If one page misbehaves, switch the feature off for that page, or add a safelist prefix, before turning the whole feature off. Stuck? Email help@speedoflight.pro with the page URL and the CSS features you have on.

NextJavaScript optimization

Optimization

JavaScript optimization

JavaScript has the biggest effect on how responsive a page feels. Analytics tags, chat widgets, sliders and social embeds keep the browser busy, and a visitor's first tap has to wait for them. The tools on SOL → Optimize → JavaScript deal with this: Delay JavaScript Execution, Minify JavaScript and Defer JavaScript. The same screen also has Instant page loads, which makes clicks from one page to the next feel instant. Speed of Light never combines JavaScript files into bundles.

Delay, Minify and Defer are all off by default. They are opt-in tools, and Autopilot never turns on JavaScript delay. When you turn delay on, it starts in Safe mode. Test your interactive elements (menus, forms, sliders, cart) after enabling it.

Delay JavaScript Execution

With delay on, eligible scripts don't run while the page loads. A tiny runner at the top of the page waits for the visitor's first mouse movement, touch, scroll, key press or click, and then runs the delayed scripts in their original order. The click that woke the page is replayed, so it isn't lost (links and form fields are left to the browser). If nobody interacts, the scripts load anyway after the Delay Timeout (ms), which defaults to 3500 ms and can be set from 0 to 30000. A value of 0 means no wait, so scripts load straight away.

Delayed scripts keep every attribute they had, and any data WordPress prints for a script (localized settings, translations, inline before/after snippets) stays with that script and runs at the right moment. This mostly improves INP (responsiveness) and Total Blocking Time.

Delay Mode

  • Safe (default): delays theme and plugin scripts that nothing else depends on. jQuery and WordPress core, forms, sliders, payments, ads, analytics and consent tools keep running immediately.
  • Aggressive: delays all non-critical scripts. The always-protected list below still applies. Test interactive features carefully.

Never delayed, in any mode

  • Ad loaders: Google AdSense, Google Publisher Tag (GPT), DoubleClick, Raptive (AdThrive), Mediavine, Ezoic, Prebid, Amazon (apstag), Monumetric, Freestar and others. Delaying these would stop ads rendering for visitors who don't interact.
  • Consent tools: Cookiebot, OneTrust, Complianz and similar, the IAB TCF / GPP / USP APIs, Google Consent Mode, Funding Choices and Sourcepoint.
  • CAPTCHAs: Cloudflare Turnstile, reCAPTCHA and hCaptcha.
  • Payments: Stripe, PayPal, Square, Braintree and WooCommerce's cart and checkout scripts.
  • Core: jQuery, jQuery Migrate and WordPress core dependencies.
  • Scripts you mark with data-no-optimize, data-noptimize, data-cfasync="false" or data-sol-no-delay.
  • Scripts that can't be replayed safely: ES modules, and inline scripts that use document.write().

Analytics

Google Analytics, Tag Manager, the Meta Pixel and similar trackers run immediately by default. Also delay analytics & tracking pixels is a separate opt-in. With it on, they load after the first interaction, so pages are faster, but visitors who leave without interacting may not be counted. Anything Tag Manager loads also waits. Ads, consent and payment scripts are never delayed either way.

Pages and visitors that are skipped

  • WooCommerce cart, checkout and My Account pages are never delayed, so payment fields and cart updates work straight away.
  • Logged-in users always get pages without optimizations. There is also a Skip JS delay for logged-in users toggle, off by default.
  • wp-admin, AJAX, cron, REST API requests and the Customizer are never touched.

Excluding a script

If one widget misbehaves, add it to Exclude scripts from delay, one per line. A line can be part of the script's URL or ID, part of an inline script's content, a * wildcard pattern (for example *chat*), or an exact script handle (with or without the trailing -js). The box starts with the Google ad patterns.

To check whether delay is causing a problem, add ?soldelay=0 to the page URL. That turns delay off for that one page load and leaves your settings unchanged. To turn every optimization off for one page permanently, add it to Cache → Exclusions.

Developers can extend the Safe-mode protection list with the sol_js_delay_plugin_exclusions filter, and the always-protected list with sol_js_delay_builtin_critical:

add_filter( 'sol_js_delay_plugin_exclusions', function ( $patterns ) {
    $patterns[] = 'my-booking-widget'; // matched against src, id or inline content
    return $patterns;
} );

Minify JavaScript

Minify strips comments and whitespace from your local JavaScript files.

  • Scripts from other domains are never touched.
  • .min.js files are skipped, and so is any file that doesn't actually get smaller.
  • ES modules, data URIs, JSON-LD and scripts with nested template literals are skipped.
  • Larger inline scripts are minified when that makes them smaller.
  • Ad scripts are always skipped.
  • Add data-sol-no-minify to a script, or add it to Exclude scripts from minification. That box matches the script URL and starts with jQuery, wp-polyfill and Google ad patterns.

Minified files are keyed by the original URL and its modification time, so updating a plugin or theme produces a fresh copy automatically. They are written safely through a temporary file. Clearing the page cache doesn't remove them. Changing a JavaScript setting, or running wp sol js-minify clear, switches pages to freshly named files. To switch minify off for one post or page, tick Disable JS Minify in the editor's SOL Optimization box.

Defer JavaScript

Defer JavaScript (off by default) adds defer to eligible scripts so they no longer block rendering, with its own Exclude scripts from defer list. Delay and Defer are alternatives: turning delay on switches Defer off.

Instant page loads

Instant page loads starts loading the next page when a visitor hovers over a link, so it opens almost instantly. It has three settings:

  • Prefetch (the default): downloads the next page's HTML only.
  • Prerender: fully loads the next page in the background. This is opt-in, because it can count analytics or ad views for pages the visitor never opens.
  • Off.

It never runs for logged-in users or on cart, checkout and account pages. It never prefetches links whose query strings change something, such as add-to-cart or remove-item links. The built-in exclusion list covers wp-admin, login, cart, checkout, my-account, previews and Customizer links.

More tools on this screen

  • Enable Early Hints (103) (on, needs Cloudflare): see Cloudflare edge.
  • Rendering & navigation hints (on): includes reduced-motion handling for visitors who ask their device for less animation.
  • CLS Optimizer (on): reserves space for images, videos and embeds using cloud measurements.
  • Use lightweight YouTube and Vimeo facades (off): see Images.
  • Self-host common analytics scripts (off): serves Google Analytics, gtag, Tag Manager and Meta Pixel scripts from your own domain. Add data-sol-no-local to a script to opt it out.
  • Cache Gravatar avatars locally: see Fonts & Gravatars.

Stuck? Email help@speedoflight.pro with the page URL and the JavaScript features you have on.

NextImages

Optimization

Images

Images are usually the heaviest thing a browser downloads. Unsized or eagerly loaded images are also a leading cause of poor Core Web Vitals. The image tools live under SOL → Optimize → Images and Optimize → Bulk Compression. They make lighter WebP or AVIF copies of your images, give the browser the right loading hints, and load your main (LCP) image first.

Keep two things apart. Conversion creates WebP or AVIF files in your media library and keeps your originals, so you can restore them. Front-end hints (lazy loading, dimensions, LCP handling, video facades) only change the HTML sent to visitors and never touch your files.

Converting images to WebP and AVIF

Enable image optimization is on by default. Here is what happens to a new image:

  1. You upload a JPEG or PNG as usual. The original is stored untouched, with its color profile and camera data.
  2. About a minute later, in the background, your server creates a WebP (the default) or AVIF version. WordPress makes its thumbnails first.
  3. The attachment is pointed at the new file, and links to it in your content are updated. The original stays on disk, so the conversion can be undone.

GIFs are never converted automatically, because conversion would keep only the first frame of an animation. Conversion uses Imagick or GD, falling back to the cwebp tool if needed. If your server can encode neither WebP nor AVIF, conversion can't be turned on, and the Output Format list marks unsupported formats.

Safe by default

  • Quality (1-100) defaults to 82.
  • A converted file that would be bigger than the original is thrown away, and the original is kept.
  • Images are never enlarged.
  • If you choose AVIF and your server can't produce it, WebP is used instead.
  • WordPress's own scaling of very large uploads (above 2560 px) stays on, unless you tick Disable WordPress big image auto-scaling.

Options you have to opt in to

  • Replace originals in the browser on upload (off): re-encodes each image in your browser before upload. Uploads are smaller, but the original file, its color profile and camera data are never stored and can't be restored.
  • Delete originals after conversion (off): removes the original JPEG or PNG once the WebP or AVIF version exists. This saves disk space, but those conversions can no longer be undone.
  • Max Image Dimension in px (0 = original): when set, Bulk Compression and browser-side replacement shrink larger images to this size. Automatic conversion after upload never resizes.

The Preset menu offers Custom (the default), Recommended (quality 82, WebP) and Smaller files (quality 70, WebP, 1920 px maximum).

Converting the images you already have

Your existing library is only converted when you start it yourself. Autopilot never converts or resizes media library files.

Bulk Compression

Open Optimize → Bulk Compression and click Start Compression. JPEG, PNG and WebP images are processed in the background in small batches, with live progress and a Stop button. On licensed and trial sites, the Speed of Light cloud does the encoding, with conversion on your own server as the fallback. The results are always stored on and served from your site.

Or a Fix it button in Insights

If Insights finds oversized images, its Fix it button starts the same background conversion, with originals kept. It only runs when you click it.

Or WP-CLI

The CLI converts on your server only, without resizing. Unlike the automatic path, it includes GIFs.

# Convert every convertible image
wp sol convert

# Preview what would be converted, without changing anything
wp sol convert --dry-run

# Convert the first 100, or specific attachment IDs
wp sol convert --limit=100
wp sol convert --ids=123,456

# Convert one attachment and show before/after sizes
wp sol convert-one 123

# Reset saved progress and start a fresh run
wp sol convert-reset

Restoring originals

As long as the original file was kept, a conversion can be reversed. Restoring points the attachment back at the original, rewrites the links in your content back, and deletes the generated WebP or AVIF files.

  • One image: use the Restore original link on the image in the Media Library list view.
  • Everything: go to Optimize → Bulk Compression → Restore Original Images and click Restore all originals.

Restoring isn't possible when there is no separate original. That happens if you turned on Delete originals after conversion or Replace originals in the browser on upload. It also happens when Bulk Compression only shrank an image within its existing format, for example a WebP image with WebP output, because then the file is compressed in place. Take a normal backup of wp-content/uploads before large bulk runs.

Serving WebP to visitors

Serve WebP images when available is on by default. For browsers that accept WebP, image URLs are pointed at an existing .webp copy on disk, and those browsers get their own cached version of each page. Browsers without WebP support get the original. On licensed sites, the cloud's measurements also size the responsive sizes attribute of your theme's existing srcset. Speed of Light doesn't add <picture> wrappers or blur-up placeholders.

Loading hints

These only change the HTML and are on by default:

  • Lazy load images: adds loading="lazy" to images WordPress outputs and to iframes, so off-screen media loads as the visitor scrolls. Your main image is always kept eager. Lazy load all page images (off) extends this to headers, footers and page-builder markup, keeping the first images eager (Keep first N images eager, default 3). Lazy load background images (off) delays inline CSS backgrounds until they are near the screen.
  • Add decoding=async to images: image decoding no longer holds up the page.
  • Add missing width/height attributes: lets the browser reserve space so content doesn't jump (CLS). It is only added to content images, never to logos, header, footer or navigation images. When a page has <main> or <article>, only images inside it are changed.

To keep a single image or iframe out, add data-sol-no-lazy, data-no-lazy or the skip-lazy class, or use data-sol-no-dimensions.

LCP: loading your main image first

Largest Contentful Paint (LCP) measures how quickly the biggest element at the top of the page appears, usually the hero image. Auto-detect and optimize LCP image is on by default.

  • Finding the real hero. Speed of Light doesn't just take the first image, which is often a logo. It scores candidates by size, position and hero-like class names. It understands heroes hidden behind lazy-load data-src attributes, and CSS background heroes from page builders.
  • What it does. The hero gets loading="eager", fetchpriority="high" and a preload hint in the page head. Competing high-priority hints are removed, so only the hero is first in line.
  • Cloud accuracy. On licensed and trial sites, the cloud measures the real LCP element in a browser at both phone and desktop widths. When the two differ, each gets its own preload. If the cloud found that the largest element is text or a video, no image is promoted. Art-directed <picture> images aren't preloaded, so the wrong version is never fetched.
  • Manual control.Manual LCP image URLs accepts full URLs, filenames or * wildcards (for example */hero-*.webp), and always wins. You can also mark an image with data-sol-lcp.

Prioritize the first in-content image (off) is a simpler alternative for post content only. It is unavailable while the LCP optimizer is on.

Layout-shift fixes from the cloud

On licensed and trial sites, the cloud measures which elements actually move while a page loads. The CLS Optimizer then applies a precise fix to each one: real dimensions for an unsized image, iframe or video, or a reserved height for a container that grows. Desktop measurements apply only at desktop widths, and phones get their own. Without a cloud plan, this feature does nothing, so it can't break a layout on its own.

Video embeds and iframes

Known video embeds (YouTube, Vimeo, Dailymotion, Wistia, Loom and others) that have no size get a 16:9 aspect ratio, so they don't shift the layout. This is never applied to maps, ads or chat widgets.

Use lightweight YouTube and Vimeo facades is off by default, under Optimize → JavaScript → Advanced JS options. It replaces each player with a thumbnail and a play button, and the real player loads only when someone clicks. Facades fit WordPress's responsive embed wrappers, and they skip autoplaying, background and API-controlled players. They work with the keyboard (Enter or Space) and have screen-reader labels.

The thumbnail still loads from YouTube or Vimeo. Before the real player loads, a cancelable sol:facade:beforeload event fires, so a consent tool can hold the player back. If that event can't run, the player doesn't load.

<!-- Keep this embed as a normal iframe -->
<iframe src="https://www.youtube.com/embed/VIDEO_ID" data-sol-no-facade></iframe>

<!-- Don't lazy-load it, or don't add an aspect ratio -->
<iframe src="…" data-sol-no-lazy></iframe>
<iframe src="…" data-sol-no-aspect></iframe>

SVG uploads

WordPress blocks SVG uploads because an SVG can contain code. Allow SVG uploads is off by default. When you turn it on, only users with the unfiltered_html capability can upload SVGs (super admins on multisite). Every file is sanitized before it is saved, and a file that fails is rejected. SVGs are never converted and are left out of dimension and LCP handling.

A sensible setup: leave conversion on (WebP, quality 82), keep lazy loading, async decoding, dimensions and the LCP optimizer on, and run Bulk Compression once, after a backup, for your existing library. Still stuck? Email help@speedoflight.pro.

NextFonts & Gravatars

Optimization

Fonts & Gravatars

Google Fonts and commenter avatars both reach out to a third-party host (Google, Gravatar) from your visitor's browser, and both can delay when your text and images appear. Speed of Light can serve them from your own domain instead. Font settings live in the Font Optimization card under SOL → Optimize → CSS.

Why third-party fonts slow you down

A page that uses Google Fonts makes the browser connect to fonts.googleapis.com for a stylesheet, then to fonts.gstatic.com for the font files. Each new host costs a DNS lookup, a secure connection and a download before your text can appear in its real typeface. On slow connections, visitors see blank space where words should be, or a visible jump when the font swaps in.

Self-host Google Fonts

Self-host Google Fonts is off by default. It shows up in your Recommendations, and on licensed and trial sites, Autopilot can turn it on as part of font optimization. When it is on, Speed of Light finds Google Fonts stylesheets on your pages, both <link> tags and @import rules, and:

  • Fetches the CSS the way a modern browser would, so it gets compact woff2 files.
  • Downloads the font files to wp-content/cache/sol/fonts in the background, never while a visitor's page is loading.
  • Switches the page to the local stylesheet once every file it needs is on disk. Until then, Google's stylesheet is served as before.

Latin and Latin Extended subsets are self-hosted, plus any subset the stylesheet explicitly asks for. Other subsets keep loading from Google. Developers can change this with the sol_fonts_self_host_subsets filter. Only Google Fonts are handled, and separate stylesheets aren't merged.

Readable text from the first paint

The self-hosted stylesheet adds font-display: swap to fonts that don't set a display strategy. Text appears right away in a fallback font and switches to your web font when it arrives. Icon fonts are different: they get font-display: block, so icons never briefly show as random letters.

Never in the way

  • Background work only. Font files are downloaded by a background task, not during a visitor's page load.
  • Short timeouts. Google's stylesheet is cached for a day after it is fetched. If Google is slow or unreachable, the request gives up quickly, the page keeps its Google stylesheet, and a failed fetch isn't retried on every page.
  • Dynamic pages are skipped. WooCommerce cart, checkout and account pages, Easy Digital Downloads checkout, and pages marked DONOTCACHEPAGE are left alone.
  • Fails safe. If a file can't be downloaded or the cache folder can't be written, that font keeps its Google URL. Self-hosting can't break the page.

Preload fonts

Preload fonts is also off by default and shows up in your Recommendations. It tells the browser to fetch your most important fonts straight away, instead of discovering them later in the CSS. It adds at most two preload hints per stylesheet, just before </head>, with the correct type and crossorigin attributes. It preloads the URLs the page will actually use: your local copies when self-hosting is active, otherwise Google's.

On licensed and trial sites with Preload fonts on, the cloud's real browser render tells Speed of Light which fonts actually paint at the top of the page. That list replaces the local guess (still at most two fonts), and preconnect hints are added for the hosts that matter.

A good pairing

  • Self-host + swap removes the third-party connections and keeps text readable from the first paint.
  • Preload then shortens the time until your headline and body text appear in their real font. Turn it on once self-hosting is working.

Gravatar caching

Cache Gravatar avatars locally (under Optimize → JavaScript → Advanced JS options) serves commenter avatars from your own domain instead of gravatar.com. Its stored default is off, but it is one of the recommendations applied once on a fresh install when comments are open on new posts (see Autopilot & Recommendations).

Catch the avatar URL

Only gravatar.com and secure.gravatar.com avatar URLs are handled. Everything else is left alone.

Serve the local copy

If a fresh local copy exists, matched by the Gravatar hash, size and options, the page uses it and the browser never contacts Gravatar.

Download in the background

If there is no copy yet, the original URL is used for now and the download runs in the background a few seconds later. No visitor waits for it.

Local avatars are refreshed after 7 days, so changes on Gravatar still come through. Downloads aren't repeated while one is pending, sizes are kept between 1 and 512 pixels, and only real image responses are stored.

What you'll notice

  • Fewer third-party requests. Once the local copies are ready, requests to fonts.googleapis.com, fonts.gstatic.com and gravatar.com disappear from your browser's network panel, apart from non-Latin font subsets.
  • No invisible text. Text shows immediately and swaps to the web font.
  • A short warm-up. Right after you turn self-hosting on, pages keep using Google until the background download finishes.

Fonts added by JavaScript after the page loads, instead of a normal <link> or @import, can't be detected. They keep loading from Google as before. To check a specific font, clear the cache and look for gstatic.com requests in your browser's network panel, or email help@speedoflight.pro.

NextDatabase clean-up

Optimization

Database clean-up

Over time, every WordPress database collects rows nobody needs: old revisions, auto-drafts, trashed items, spam and expired temporary data. SOL → Clean shows how much of that you have and removes it when you ask. Two optional daily jobs under Settings → Debloater can keep things tidy automatically.

The Clean screen

The Database Health card shows a running total, for example "1,240 items can be safely removed". Click Run Safe Cleanup to clean everything at once. Below it, the Cleanup Items card lists each type with its own count and a Clean button. A toast confirms when a cleanup has finished, and the counts update to show what is left.

Cleanups run as soon as you click, and deletions are permanent. Trashed posts and comments are deleted for good, not moved anywhere. If there is anything you might still want, restore it from the Trash first, and keep a recent backup as you would for any database work.

What each item removes

  • Post Revisions: old revisions of posts and pages. The newest 3 revisions of each post are always kept, and so are autosaves and posts open in the editor. The count only includes revisions beyond those 3.
  • Auto Drafts: the empty placeholders WordPress creates when you open the editor and never save. Only those older than seven days are removed, for posts and pages, and active editing sessions are preserved.
  • Trashed Posts: posts and pages already in the Trash. Products and other custom post types aren't included, and posts being edited are skipped.
  • Spam Comments and Trashed Comments: comments marked as spam or already in the Trash.
  • Expired Transients: temporary cached values whose expiry time has passed, both the value and its timeout row, for site and network transients. Unexpired transients are left alone. When a persistent object cache such as Redis is active, transients live there instead, so this shows 0.
  • Orphaned Postmeta and Orphaned Commentmeta: metadata for posts or comments that no longer exist. Rows that belong to no post or comment on purpose (ID 0) are kept. Large backlogs are worked through in batches, so you may need to click more than once.

Posts and comments are deleted through WordPress's own functions, so related data is cleaned up properly. Your published content, approved comments and settings are never touched.

Automatic daily jobs

Under Settings → Debloater → WordPress Internals, two jobs run daily at 2 AM site time:

  • Daily clean expired transients is on by default. It removes expired transients in small daily batches, and skips everything when Redis holds your transients.
  • Daily optimize WordPress tables is off by default. It runs OPTIMIZE TABLE on this site's core WordPress tables, but only on tables with reclaimable space, or tables using the older MyISAM engine.

While either job is on, Disable WP-Cron is unavailable, because the jobs need it. See Kill Bloat.

Autoloaded options

Autoloaded options are settings WordPress loads into memory on every request, whether a page needs them or not. A bloated set adds time and memory to every page that isn't served from the cache. You can see the total under Insights → Server in the Database card (Autoload Size), next to your database version, table count and total size.

The autoload figure counts options marked autoload = 'yes'. WordPress 6.6 and later also use other autoload values, so on newer sites the real total can be somewhat higher. If it looks large, find the plugin that created the biggest options and change its settings, or remove the plugin. Don't delete option rows by hand unless you're sure what they belong to.

Plugin database health

Speed of Light keeps a few tables of its own: the activity log, performance measurements, Used CSS, and the preload queue. SOL → Health checks the first three under Plugin database. If the preload queue table can't be created, for example because your host doesn't allow it, the Preloader explains this in plain English and asks you to have your host allow table creation.

Multisite

Database cleanup is switched off on multisite networks, to avoid cross-site risk. The server refuses cleanup requests there, so on a network Clean shows nothing to remove.

Who can use it

The whole SOL menu requires the manage_options capability (normally administrators). Each cleanup request is checked again on the server before anything is deleted. Developers can adjust this with the sol_enable_db_cleaner, sol_db_cleanup_capability and sol_db_allowed_cleanup_items filters. There is no WP-CLI command for database cleanup.

Not sure about a cleanup or a large option? Email help@speedoflight.pro before deleting.

NextTweaks & debloat

Optimization

Tweaks & debloat

WordPress loads features many sites never use, and each one can cost visitors a request, a few kilobytes of markup, or a background task. Speed of Light's clean-up switches live under SOL → Settings, in the Tweaks, Debloater and Admin tabs. None of them rewrite your content or theme. Each one simply stops WordPress loading something you didn't ask for.

Almost everything here is off by default. A new install changes nothing on your login page or in wp-admin: branding, admin bar, admin columns, the Custom Fields box and the other admin tweaks are all off. Three exceptions are on: Remove SEO plugin HTML comments, Daily clean expired transients and Show SOL cache status column, which adds a small cache-status column to your post and page lists. Turn other options on one at a time and check your site after each.

Changes apply to pages as they are rebuilt. Clear the page cache to see them everywhere straight away.

Tweaks → Frontend Tweaks

These remove tags and links WordPress prints into every page's <head>:

  • Remove WordPress version from head and Remove generator meta tag: stop advertising your WordPress version.
  • Remove RSD and WLW manifest links: links used only by old desktop blogging apps.
  • Remove shortlink: the rel="shortlink" tag.
  • Remove oEmbed links: the oEmbed discovery links.
  • Remove rel prev/next links: the previous/next-post links WordPress adds on single posts.
  • Remove REST/oEmbed link headers: removes the REST API link tag, the REST Link: header and oEmbed discovery. The REST API itself keeps working.
  • Remove SEO plugin HTML comments (on by default): removes the credit comments Rank Math, Yoast, All in One SEO and SEOPress add to pages. It also turns off those plugins' own sitemap caching.

These only change what WordPress itself outputs. Headers your server adds, such as PHP's X-Powered-By, aren't removed.

Tweaks → Admin Tweaks and Security Tweaks

All of these are off by default. They change what you and your editors see in wp-admin:

  • Remove WordPress logo from admin bar, Remove Howdy greeting, Remove Help tab on admin screens, Remove WP footer text in admin and Disable admin color scheme picker.
  • Hide admin bar for non-admin users: hides the front-end toolbar for everyone without the manage_options capability, including editors, authors and shop managers. Nobody is ever blocked from wp-admin.
  • Hide admin notices: hides routine notices. If an error, warning or update notice is present, all notices are shown, so you never miss a problem.
  • Disable file editing in admin and Hide login errors.

Debloater

Scripts & Styles

  • Disable emojis: removes WordPress's emoji detection script and stylesheet, plus the feed, email and editor emoji filters. Modern devices show emoji natively.
  • Disable Dashicons on frontend: removes the Dashicons icon font for logged-out visitors only, so the admin bar keeps working for you. If icons disappear for visitors, your theme needs it, so turn it back off.

Pingbacks & Comments

  • Prevent WP from pinging itself: no more pingbacks when you link between your own posts.
  • Globally disable pingbacks & trackbacks: closes pings site-wide, and includes the self-ping setting.
  • Disable comments and Return 404 for author archives are here too.

WordPress Internals

  • Cap post revisions to 3: keeps at most three revisions per post. WordPress trims a post's older revisions the next time you save it.
  • Increase autosave interval to 120s: the editor autosaves half as often. This is skipped if AUTOSAVE_INTERVAL is already defined.
  • Daily clean expired transients (on by default) and Daily optimize WordPress tables (off): see Database.
  • Disable WP-Cron: defines DISABLE_WP_CRON without editing wp-config.php. Only use it if a real server cron runs wp-cron.php. It is greyed out while either daily job is on, because they rely on cron. Turn the jobs off first.
  • Disable automatic updates and Force auto-updates: each is greyed out while the other is on, so they can't fight.
  • Enable maintenance mode (503): shows visitors a temporary maintenance response.

APIs & Feeds

  • Disable XML-RPC: turns off the legacy remote API and removes the X-Pingback header.
  • Disable RSS feeds: feed URLs return 403.
  • Remove jQuery Migrate: on the front end only. Leave it off if older scripts on your site need it.

Safe Debloat

  • Throttle Heartbeat API to 60s: wp-admin's background check-ins (autosave polling, post locks) run once a minute instead of more often. They aren't disabled.

WooCommerce

This card is only available when WooCommerce is active.

  • Disable WooCommerce cart fragments: removes the wc-cart-fragments script on every front-end page. Leave it off if your header shows a live mini-cart count.
  • Remove WC CSS/JS on non-shop pages: removes WooCommerce styles and scripts on pages that aren't shop, product, cart, checkout or account pages. If you show products or add-to-cart buttons on other pages, leave this off.
  • Dequeue WooCommerce block styles: removes the WooCommerce block stylesheets on every front-end page. Leave it off if you use WooCommerce blocks.

Admin tab

Admin Columns adds or removes list-table columns: featured image, excerpt, last modified, ID, media file size, and the SOL cache status column (on by default). Admin Features offers extras such as a Duplicate post action, media-library user avatars, removing the Custom Fields box, and Enable custom login branding. All of these are off by default, apart from the cache status column.

Self-hosting third-party scripts

Self-host common analytics scripts (off by default) is under Optimize → JavaScript → Advanced JS options. It copies a fixed list of scripts to your server and points your pages at the local copy, saving a connection to another domain:

  • Google Analytics: gtag/js, analytics.js and ga.js.
  • Google Tag Manager: gtm.js. Preview and environment containers are never self-hosted.
  • Meta Pixel: fbevents.js.

Each ?id= gets its own local file. Downloads happen in the background, never during a visitor's page load. Until a copy exists, the page keeps the original URL, and pages switch to the local copy as they are rebuilt. Copies are refreshed in the background after a day. A download only replaces the old copy if it is a real 200 response containing JavaScript. To keep a script on its original URL, add data-sol-no-local:

<script data-sol-no-local src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXX"></script>

This only changes where the scripts are served from. It isn't a consent tool: the same trackers run, and your consent setup stays your responsibility.

A low-risk starting point

  • Disable emojis.
  • Remove the generator, version, shortlink, RSD/WLW and rel prev/next links.
  • Throttle the Heartbeat API and increase the autosave interval.
  • Cap post revisions to 3.
  • Keep Daily clean expired transients on.

Add the WooCommerce options if your store sits inside a mostly-content site. Leave Disable WP-Cron and the update options for last, and only change them if you understand your hosting. Every option can be switched back off at any time. If one causes something unexpected, turn it off, clear the cache, and email help@speedoflight.pro with the option name and what you saw.

NextInsights & Health

Monitoring

Insights & Health

Two screens tell you how your site is doing. Insights explains how fast your pages are and what is slowing them down. Health checks that Speed of Light itself is working. Find both in the SOL menu in wp-admin.

Insights

Insights has three tabs: Autopilot, Core Web Vitals and Server. Cloud scans need an active license or trial. Without one, Insights asks you to activate your license.

Checking your pages

Click Check my site on the Autopilot tab. The cloud loads your pages in a real browser, at desktop and phone widths, and measures them the way a visitor would experience them. A check takes about half a minute. The page cache preloader also asks the cloud to check your most important pages in the background, within a daily allowance.

The default view stays simple: whether Autopilot is on and what it changed. Click Show technical details for the full findings, page by page. You can filter by Home, Pages, Posts, Products and Archives, and phone results are labelled mobile. Each finding shows:

  • How serious it is: Critical, High, Medium or Low.
  • What it affects, such as the main image (LCP), responsiveness (INP), layout shifts (CLS), CSS, JavaScript, images, third-party scripts or navigation.
  • The culprit: the file or element responsible, and the estimated savings where they can be measured.
  • A next step.Fix it when Speed of Light can change the setting for you, or How to fix with plain steps when the fix belongs in your theme or content.

The metrics in plain English

MetricWhat it meansGood
LCP (Largest Contentful Paint)How long until the biggest thing on screen, usually the hero image or headline, has appeared.2.5 s or less
INP (Interaction to Next Paint)How quickly the page reacts when someone taps, clicks or types.200 ms or less
CLS (Cumulative Layout Shift)How much the page jumps around while it loads.0.1 or less
TTFB (Time to First Byte)How long your server takes to start answering. Page caching is the big fix here.800 ms or less

Image, font and asset findings point at the files behind these numbers: images that are too big or load too late, fonts that delay text, and stylesheets or scripts that block the first paint.

Core Web Vitals and Server tabs

Core Web Vitals shows field data from your real visitors when real-user monitoring is on (see Real-User Monitoring). This is what Google uses, as opposed to a one-off lab test. Server lists your PHP environment and extensions, database (including autoload size), WordPress configuration and web server.

When a scan fails

If scans can't complete, a banner at the top of Insights explains what went wrong, how many scans failed in the last 24 hours, which pages were affected, and what to do next. The most common cause is a firewall, security plugin or CDN blocking the scanner. When that happens, click Copy allowlist details and paste them into your firewall's allowlist, or send them to your host. If you reach the daily scan limit, Speed of Light tells you when scans resume. Saved cloud plans keep working in the meantime.

Health

SOL → Health starts with the Alerts panel. Below it, Run health check runs a quick self-check. It doesn't render pages and is safe to run any time. Results are grouped like this:

  • Plugin database: the activity log, performance measurements and Used CSS storage are ready.
  • Plugin core: page-cache drop-in, WP_CACHE, writable cache folder, a live check that the homepage is served from cache, Pages can be stored in the cache, object cache, background tasks and license.
  • Cloud API: reachability, renderer, license, authentication and optimization jobs.
  • Optimization: Critical CSS, Remove Unused CSS, LCP optimizer, image optimization and real-user monitoring. Features you haven't turned on show as "off (optional)", not as errors.
  • Conflicts: other page-cache plugins.
  • Edge: the Cloudflare connection and whether cache rules are deployed.

Every check shows its current state in plain English and, when something is wrong, a Fix line. Only a broken page cache (missing drop-in, WP_CACHE off or an unwritable cache folder) turns the overall result red. Everything else is at most a warning. A site on the free trial shows its license as active, with full cloud features.

"Pages can be stored in the cache" is the check to read when caching seems to do nothing. If a plugin or your theme sets a cookie on every visit, or marks pages private or no-store, this check names the cookie or header, the page where it was seen and how to fix it. See Page cache.

When the result isn't fully healthy, Contact Support and Copy diagnostics appear. The diagnostics text lists every check and its fix, so paste it into your message to help@speedoflight.pro.

NextAlerts centre

Monitoring

Alerts centre

The Alerts centre tells you, in plain English, when something needs your attention. Each alert says what is happening, what your visitors notice and the exact next step, usually with a button that takes you there. When the problem is fixed, the alert clears itself.

Where alerts appear

  • One compact notice, "Speed of Light needs attention", on the WordPress Dashboard, the Plugins screen and the SOL screens. It shows the most important alert, its action button and View alerts. Alerts never stack up into a wall of notices.
  • An admin-bar badge, for example "2 alerts need attention".
  • The Speed of Light dashboard widget on the WordPress Dashboard.
  • The Alerts panel at the top of SOL → Health, with the full list and the email settings.

The notice and the badge only count critical problems and warnings. Information alerts appear in the Alerts panel and the dashboard widget. Only administrators see alerts.

How alerts behave

  • They wait for real problems. A condition that can be a short blip, such as a brief network hiccup, only becomes an alert once it persists. Setup problems show straight away.
  • They clear themselves. Once the cause goes away, the alert is marked Resolved and stays visible for 24 hours so you can see what happened.
  • You stay in control.Dismiss until it changes hides an alert until its situation changes. Snooze 24h hides it for a day. Show again brings back a hidden alert, and Check again re-evaluates everything now.
  • They are ranked. Critical first, then warnings, then information, newest first within each.

Alerts are checked in the background every 15 minutes and when an administrator opens wp-admin. They never run on visitor page loads.

What is covered

  • Page caching not active, with the reason (for example another plugin controls advanced-cache.php, or WP_CACHE is off), and a note when the drop-in was repaired or the WP_CACHE line was put back automatically.
  • Cookies or headers that stop pages from being cached, naming the cookie.
  • The preloader slowing down or pausing to protect your server, or a cache warm-up that has stopped making progress, with the reason (for example blocked loopback requests, or WP-Cron switched off without a server cron job) and the fix.
  • Cloud problems: the daily scan limit (with the time scans resume), license status, failed scans, and the cloud service being unreachable.
  • Real-user speed data not reaching the cloud.
  • Redis not answering, so the object cache is running in fallback mode.
  • Cloudflare: changes paused on a staging copy, purges being refused, and the page scanner possibly being blocked.
  • Autopilot turning optimizations on, or undoing a change to keep your site safe.
  • Conflicting cache, optimization or image plugins, and host page caches.
  • Plugin updates, WordPress version support, low disk space and error spikes.

Alert emails

Speed of Light can email you about problems that affect visitors. Email me about problems is on by default and sends critical alerts to the site's Administration Email Address.

  • An email is sent only once a problem has lasted 30 minutes.
  • You get at most one email per problem per day and three per day in total, plus a short note when the problem is resolved.
  • Send to takes up to five addresses, separated by commas. Leave it empty to use the site's Administration Email Address.
  • Which alerts is either Critical only (the default) or Critical and warnings.
  • Send test email checks that your site can actually send mail.

If the test email never arrives, your site probably can't send mail reliably. An SMTP plugin connected to your mail provider usually fixes this, and it helps every other email your site sends too.

For developers

Add your own alerts with the sol_alerts filter. Each alert needs an id and a title. severity (critical, warning or info, default warning), message and action (label + url) are optional. Return the condition only while the problem exists, and it will resolve itself when you stop returning it.

add_filter( 'sol_alerts', function ( $alerts ) {
    if ( get_option( 'my_feed_import_failed' ) ) {
        $alerts[] = array(
            'id'       => 'my_feed_import',
            'severity' => 'warning',
            'title'    => 'The product feed import failed',
            'message'  => 'New products are not appearing. Re-run the import.',
        );
    }
    return $alerts;
} );

To forward alerts somewhere else, such as Slack, hook the sol_alert_raised and sol_alert_resolved actions. Each receives the alert record (id, severity, title, message, action and timestamps). sol_alerts_email_recipients lets you change who receives alert emails. See WP-CLI, REST API & hooks for the full hook list.

NextReal-user monitoring

Monitoring

Real-user monitoring

Real-User Monitoring (RUM) measures how fast your site feels to the people actually visiting it. Instead of a single lab test from one machine, it collects Core Web Vitals from your visitors' own browsers, on every device and connection, and reports them the way Google does. This is called field data. It is what Google uses to judge your site in Search.

Where to find it

Open SOL → Insights → Core Web Vitals. The Core Web Vitals Monitoring card has the on/off switch and shows Monitoring Active or Monitoring Disabled. RUM only collects while that switch is on. If you switch it off, it stays off. Updates and Autopilot never switch it back on, though a full Settings → Reset returns it to its default.

What it measures

The collector uses the browser's built-in PerformanceObserver API:

  • LCP (Largest Contentful Paint): how long until the biggest visible element has appeared. Good is 2.5 s or less.
  • INP (Interaction to Next Paint): how quickly the page reacts to taps, clicks and key presses during the whole visit. Good is 200 ms or less.
  • CLS (Cumulative Layout Shift): how much the page jumps around. Good is 0.1 or less.
  • TTFB (Time to First Byte): how long the server takes to start answering. Good is 800 ms or less.
  • FCP (First Contentful Paint) is collected too, but not shown on the dashboard.

INP and CLS keep changing for as long as someone uses the page, so final values are sent when the visitor leaves it. Each figure is reported at the 75th percentile (p75), the same statistic Google uses, so you can compare it directly with PageSpeed Insights. INP uses the same near-worst-interaction method as Google's web-vitals library.

Reading the dashboard

Four cards show your site-wide p75 for LCP, INP, CLS and TTFB over the last 7 days, each colored Good, Needs improvement or Poor, with its target. When the cloud has analyzed your data, a Field breakdown adds:

  • Phone and desktop figures.
  • Most measured pages.
  • Slow LCP elements: the actual images or headings visitors' browsers reported as the largest element.
  • Slow interaction targets: the buttons or links that respond slowly.

An empty dashboard just means not enough logged-out visitors have arrived yet. That's normal on a new or quiet site.

Privacy

RUM is designed to collect as little as possible:

  • No IP addresses are stored. They are used only briefly, in hashed form, to limit how often one source can send data.
  • No cookies are set or stored, and no visitor identifier is recorded, so individual visitors can't be told apart or tracked.
  • No query strings. Everything after ? or # is removed from page addresses before they are stored or sent, so campaign tags never reach the data.
  • Coarse device type only: mobile or desktop. Each sample also notes the navigation type, a short description of the largest element (its tag, classes, and an image URL without its query string) and the element the visitor interacted with.
  • Logged-in users are never measured, and nor are bots, Lighthouse, headless browsers or Speed of Light's own scanner and preloader.
  • Strict limits per site keep the amount of stored data small.

Where the data goes

Measurements are sent with the browser's sendBeacon to your own site's REST route (/wp-json/sol/v1/rum) and stored on your site. On licensed and trial sites, Speed of Light forwards these privacy-bounded summaries to the Speed of Light cloud for analysis. The cloud uses each page's field data to plan fixes and to build the field breakdown. If the data can't reach the cloud, the Alerts centre tells you why.

Data stored on your site is deleted automatically after 30 days. Clear Data removes everything collected so far and asks the cloud to delete its copy. Reset does the same and switches monitoring off.

WordPress's privacy tool (Settings → Privacy → Policy Guide) includes suggested text from Speed of Light about the anonymous performance data. Review it before adding it to your policy page, and mention that the summaries are processed by the Speed of Light cloud. Speed of Light doesn't check Do Not Track or consent signals before collecting, so decide with your own privacy setup in mind.

For developers

// Keep local RUM data for 14 days instead of 30.
add_filter( 'sol_rum_retention_days', function () {
    return 14;
} );

sol_rum_retention_days only controls the copy stored on your site. sol_rum_sample_rate controls how much of your traffic is measured (default: every page view). The sol_rum_enabled filter can force collection on, but it can't switch it off.

To check that collection works, open your site in a private window (so you are logged out), visit a few pages, then return to the dashboard. Data arrives as you leave each page.

NextCompatibility

Reference

Compatibility

The quickest way to break a site is to strip or delay the CSS and JavaScript that your theme or page builder generates on the fly. Speed of Light avoids this. It recognizes what you're running, protects that output automatically, and keeps the riskier tools off until you choose to turn them on. This page covers what is detected, what is protected, and the one rule to follow: run only one caching plugin.

Theme and builder detection

Speed of Light detects your active theme and any page builder automatically, with nothing to configure. Builders are recognized by their own code: Elementor by ELEMENTOR_VERSION, Bricks by BRICKS_VERSION, GreenShift by GREENSHIFT_DIR, and so on. What you get depends on what is detected.

Protected CSS for Remove Unused CSS

When you turn on Remove Unused CSS, built-in safelists keep the class names your builder adds at render time. This applies to:

  • Elementor, GreenShift, Divi, Beaver Builder, Bricks, Breakdance and Oxygen.
  • WooCommerce: notices, cart, checkout, account, variations, prices and forms.
  • Any block theme: navigation, query pagination, search, comments and post blocks.

Some builder stylesheets are left out of processing entirely, such as Elementor's common and Pro CSS and Oxygen's unified CSS.

Advice where a theme or builder overlaps

Some themes and builders already do part of the job. Speed of Light shows a plain-English warning next to the matching toggle:

  • Blocksy, Kadence, Neve, GreenShift: they generate their own critical CSS or conditional CSS. If you use Critical CSS or Remove Unused CSS, turn it on last and preview your key templates.
  • Divi, Avada, Flatsome, Elementor: they generate CSS per page. Avoid Combine CSS and Remove Unused CSS. On Divi, Avada and Elementor, also be careful with JavaScript delay, because their front-end scripts are needed for interactions.
  • Oxygen, Bricks: combining CSS is unnecessary because they already optimize their own CSS.

Page caching, minification, fonts and images are complementary on all of these.

JavaScript that is never delayed

JavaScript delay is off by default. When you turn it on, these always run immediately:

  • jQuery and WordPress core scripts, and scripts that others depend on.
  • Payment gateways (Stripe, PayPal, Square, Braintree), CAPTCHAs, consent tools and ad loaders.
  • Scripts marked data-no-optimize or data-cfasync="false".
  • Everything on WooCommerce cart, checkout and account pages, where payment fields and cart updates must work straight away.
  • Pages viewed by logged-in users, which skip optimization entirely.

In Safe mode, form plugins (Gravity Forms, Contact Form 7, WPForms), cookie banners and sliders are kept too. Analytics run immediately unless you opt in to delaying them. See JavaScript optimization.

WooCommerce and Easy Digital Downloads

The storefront is cached. Anything tied to a shopper's session is not. When a request carries a WooCommerce or EDD cart or session cookie, the page is built fresh, so a customer never sees someone else's cart or a stale checkout. More than 20 cookie patterns are built in, and cookies you add under Cache → Exclusions are added to the list, never replacing it. Stock changes and new orders clear the affected product pages. See Page cache.

Multilingual, AMP, multisite and view counters

  • WPML and Polylang: each language gets its own cached copy, and their language cookies don't stop pages from being cached. TranslatePress is detected too.
  • AMP: AMP pages are skipped by CSS minify, Combine, Critical CSS, Remove Unused CSS and image rewriting.
  • Multisite: deactivating Speed of Light on one site doesn't switch off caching or the object cache for the rest of the network.
  • Post Views Counter and WP Statistics: preloader visits aren't counted as views. Other plugins can check sol_is_preload_request().

Run only ONE caching plugin

Two page-cache or optimization plugins working on the same page cause doubled minification, broken layouts and behavior that's hard to diagnose. Speed of Light covers page cache, asset optimization, fonts, images, object cache and CDN integration, so it should be your only caching plugin.

Speed of Light checks your active plugins against a list of known tools:

  • Critical (deactivate it): WP Rocket, LiteSpeed Cache, W3 Total Cache, WP Super Cache, WP Fastest Cache, FlyingPress, NitroPack, Swift Performance, Cache Enabler and Breeze. While one of these is active, Speed of Light pauses its own page caching instead of fighting over advanced-cache.php.
  • Warning (choose who does what): Autoptimize, Perfmatters, SG Optimizer and WP Optimize overlap on CSS, JavaScript or images.
  • Info (usually fine): the Cloudflare plugin, Redis Object Cache, Object Cache Pro, Query Monitor, and image optimizers such as EWWW, ShortPixel and Imagify. For images, pick one optimizer, not both.

Conflicts show up in four places:

  • A banner on the Dashboard.
  • The Conflicts group in SOL → Health.
  • The Alerts centre, for example "WP Rocket is also caching your pages".
  • Next to any toggle that overlaps.

Deactivate the other cache plugin

For a critical match, deactivate the competing plugin under Plugins. Speed of Light's page-cache setup then retries automatically.

Clear caches and re-check

Purge Speed of Light's cache (and Cloudflare's, if connected), then run Run health check in Health to confirm the conflict is gone.

Choose one image optimizer

If you keep a dedicated image optimizer, turn off Speed of Light's image conversion, or the other way round, so the two don't both rewrite the same files.

Host page caches

Speed of Light recognizes managed hosts that run their own page cache: Kinsta, WP Engine, SiteGround, SpinupWP, Pantheon, WordPress.com / WP Cloud, GridPane, RunCloud and Cloudways. It shows an information alert that your host also caches pages. When Speed of Light clears its whole cache, it also asks SiteGround, SpinupWP, WP Engine, Pantheon and Breeze (Cloudways) to clear theirs, so visitors don't get an old copy from further down the line.

The safest order on any site: page caching, images and fonts first (most are on already), then minify, then JavaScript delay. Turn on Critical CSS and Remove Unused CSS last, previewing your key templates as you go. Unsure about a setup? Email help@speedoflight.pro with your theme and builder.

NextWP-CLI, REST API & hooks

Reference

WP-CLI, REST API & hooks

Most of what Speed of Light does from its admin screens can also be scripted, in four ways:

  • A wp sol WP-CLI command family for shell and deployment scripts.
  • A REST API under /wp-json/sol/v1/.
  • WordPress actions and filters.
  • A few wp-config.php constants.

There is also a per-post box for turning two optimizations off on a single post. You don't need any of this. The plugin works the same without it.

WP-CLI: wp sol

# ---- Page cache ----
wp sol clear                           # clear the whole site (or network) cache
wp sol clear --ids=1,2,3               # only these post IDs
wp sol clear --urls=example.com/about/ # a specific URL
wp sol clear --urls=example.com/blog/* # a page and everything below it
wp sol clear --sites=1,2,3             # multisite: specific blog IDs

# ---- Preload (cache warming) ----
wp sol preload                         # queue the priority URLs, warm in the background
wp sol preload --turbo                 # faster crawl
wp sol preload --run                   # warm in this process until done
wp sol preload --run --max-seconds=120 --sleep=2

# ---- Remove Unused CSS / JavaScript minify ----
wp sol rucss stats                     # entries, completed, failed, total size
wp sol rucss clear                     # reset used-CSS records so CSS is regenerated
wp sol js-minify clear                 # switch pages to freshly minified files

# ---- Object cache (Redis) ----
wp sol object-cache status             # also: enable, disable, update-dropin,
wp sol object-cache diagnostics        #       flush, diagnostics, groups

# ---- Images ----
wp sol convert --dry-run               # also: --ids=, --limit=
wp sol convert-one 123
wp sol convert-reset

Command notes

  • wp sol clear with no options clears the whole page cache, and the Cloudflare edge when connected. --ids and --urls take comma-separated lists and can be combined. A URL may leave out the scheme and may end in * to match a path prefix.
  • wp sol preload queues the most important URLs (50,000 by default, see sol_preload_max_urls) and returns. Add --run to work through the queue in the current process. It finishes with a Cached / Pending / Failed summary. Sizing flags are --batch, --delay, --concurrency, --chunk and --runtime. See Preloader for how they interact with Turbo Mode and the built-in back-off.
  • wp sol rucss clear empties the database records, so used CSS is regenerated on the next visit. Existing files are kept, so pages that are already cached keep working.
  • wp sol js-minify clear moves pages to new minified file names. Old files aren't deleted.
  • wp sol object-cache <action> needs an action. status, diagnostics and groups print tables. flush removes only this site's keys.
  • wp sol convert converts on your server only, without resizing, and keeps originals unless you chose to delete them.

WP-CLI runs without a WordPress capability check, so anyone with shell access can run these commands. Protect shell access accordingly.

REST API: /wp-json/sol/v1/

Almost every route requires the manage_options capability, so you authenticate as an administrator, for example with an application password over HTTPS. On multisite, changing the object cache also requires a Network Super Admin. A few routes are public by design:

  • POST /rum: the visitor speed beacon, registered only while real-user monitoring is on.
  • The routes the Speed of Light cloud uses to deliver results. These are signature-checked.
# Read live stats with an application password
curl https://example.com/wp-json/sol/v1/stats \
  --user "admin:xxxx xxxx xxxx xxxx xxxx xxxx"
  • Settings: GET/POST /settings, GET /settings/export, POST /settings/import, POST /settings/reset.
  • Cache and preload: GET /stats, POST /cache/purge, POST /preload, POST /preload/stop, GET /cached-urls, GET /critical-css/stats, POST /critical-css/purge.
  • Cloudflare: POST /edge/purge, /edge/deploy, /edge/zones, /edge/asset-rule/deploy, /edge/asset-rule/remove, and /edge/scanner-allowlist (GET/POST).
  • Images: POST /images/bulk-compress, GET /images/compress-status, GET /images/stats, POST /images/compress-stop, /images/compress-rescan, /images/repair, /images/restore-all, /images/lcp-auto-clear.
  • Insights and Autopilot: GET/DELETE /insights, POST /insights/scan, /insights/fix, /insights/fix-all, /insights/autopilot, /insights/undo, POST /cloud/test.
  • Health and alerts: GET /health, GET /health/check, GET/DELETE /logs, GET/POST /alerts (dismiss, snooze, restore), GET/POST /alerts/settings, POST /alerts/test-email.
  • Object cache: GET /object-cache, POST /object-cache/enable, /disable, /flush, /config, GET /object-cache/test, GET /object-cache/metrics.
  • Other: DELETE /rum clears stored real-user data. POST /db-clean runs database cleanup (disabled on multisite). POST /score/boost applies a set of conservative speed settings in one step, skipping any setting you have changed yourself.

Treat an application password like the admin password it stands in for. Never put it in browser code or commit it to a repository.

Hooks

Caching

  • sol_bypass_cache (bool $bypass): return true to stop the current page from being stored. DONOTCACHEPAGE is always honored as well.
  • sol_cache_allowed_set_cookies (string[] $names): cookies that may be set without stopping caching. The default list holds WPML and Polylang language cookies, and a trailing * matches a prefix.
  • sol_cacheable_query_params: extra query parameters that should still get the cached page, like the built-in tracking parameters.
  • sol_exclude_search, sol_cache_allowed_hosts, sol_user_can_clear_cache and sol_site_wide_post_types (post types whose saves clear the whole cache).
  • Actions fired: sol_page_cache_created (url, post ID, index), sol_page_cache_cleared (url, post ID, index, trigger), sol_site_cache_cleared (url, blog ID, index, trigger), sol_complete_cache_cleared (trigger) and sol_preload_url_warmed (url).
  • Actions you can call: do_action( 'sol_clear_complete_cache' ), 'sol_clear_site_cache', 'sol_clear_page_cache_by_post' (post) and 'sol_clear_page_cache_by_url' (url).

Preloading

  • sol_preload_max_urls (int $max, default 50,000): how many URLs one crawl warms, kept between 100 and 1,000,000.
  • sol_preload_request_args, sol_preload_user_agent, sol_preload_sslverify, sol_preload_concurrency, sol_preload_chunk_size and sol_preload_runtime.
  • sol_is_preload_request() returns true during a preload request, detected by the X-SOL-Preload: 1 header or the SpeedOfLightPreloader/ user agent. The sol_is_preload_request filter can adjust it.
// Don't count preloader visits in your own analytics code.
if ( function_exists( 'sol_is_preload_request' ) && sol_is_preload_request() ) {
    return;
}

Alerts

  • sol_alerts (array $alerts): add or remove alerts. Each needs an id and a title, and can have severity, message and action. See Alerts centre for an example.
  • sol_alert_raised and sol_alert_resolved (array $alert): fired when an alert appears or clears. Use them to forward alerts to Slack or similar.
  • sol_alerts_email_recipients: change who gets alert emails.

Optimization

  • JavaScript: sol_js_delay_plugin_exclusions, sol_js_delay_builtin_critical, sol_assets_should_defer_script and sol_assets_should_delay_script. JavaScript is delayed, deferred and minified, never combined.
  • CSS and fonts: sol_critical_css_theme_skip, sol_css_inline_small_minified_enabled and sol_fonts_self_host_subsets.
  • Hints: sol_preconnect_hosts, sol_early_hints_links (links, settings) and sol_early_hints_cached_links (links, cache file).
  • Real-user monitoring: sol_rum_enabled (can force collection on, not off), sol_rum_sample_rate and sol_rum_retention_days.
  • Database cleanup: sol_enable_db_cleaner, sol_db_cleanup_capability and sol_db_allowed_cleanup_items. The action sol_db_after_cleanup fires after a cleanup.

Constants

Define these in wp-config.php, above the "That's all, stop editing" line.

  • SOL_DEBUG: set it to true to write detailed [SOL] trace lines to the PHP error log. WP_DEBUG alone no longer turns them on. Remove it again when you're done.
  • SOL_REDIS_*, such as SOL_REDIS_HOST, SOL_REDIS_PORT, SOL_REDIS_PATH, SOL_REDIS_SCHEME, SOL_REDIS_DATABASE, SOL_REDIS_PREFIX and SOL_REDIS_MAXTTL: configure the object cache. Settings saved in the plugin come first, then these, then your host's WP_REDIS_* constants. A value equal to the built-in default never overrides a host setting.
  • SOL_REDIS_DISABLED or WP_REDIS_DISABLED: keep the drop-in installed but don't connect to Redis.
  • SOL_CACHE_ALLOWED_HOSTS: adds hostnames the page cache may serve, as a comma-separated string or an array, for example an alias domain. Your home host and its www/non-www twin are always allowed.
  • SOL_CACHE_DIR: moves the cache directory. Keep it inside your web root, because generated CSS and JavaScript URLs are built from it.
  • SOL_DISABLE_ASSETS: switches off the script defer/delay asset module only. To stop a specific optimization, turn off its toggle instead.
// In wp-config.php
define( 'SOL_DEBUG', true );          // temporary troubleshooting
define( 'SOL_REDIS_PATH', '/var/run/redis/redis.sock' ); // connect over a Unix socket

Per-post box: opt a single post out

When you edit any public post type, the editor sidebar has a SOL Optimization box with two checkboxes:

  • Disable Remove Unused CSS keeps the full stylesheets for that post.
  • Disable JS Minify serves that post's JavaScript unminified.

Update the post, and the exception applies the next time the page is built. Every other optimization keeps working on that page. To exclude a page from everything, use Cache → Exclusions.

Need something these don't cover? Email help@speedoflight.pro.

NextTroubleshooting

Reference

Troubleshooting

Most Speed of Light problems fall into a few familiar categories, and nearly all have a one- or two-step fix. Find the section that matches what you're seeing. Two built-in tools usually point straight at the answer: the Alerts centre and SOL → Health → Run health check.

Always test in a private / incognito window. Logged-in sessions are never served from the cache, so a page that "looks the same" while you are logged in tells you nothing. A private window shows what a logged-out visitor sees.

Pages are not being cached

Open the page in a private window, load it twice, and look at the X-SOL-Cache response header in your browser's developer tools:

  • HIT: it's working.
  • MISS on every load: the page is built each time but never stored. Work through the checks below.
  • BYPASS: the page was deliberately not cached. Health and the Alerts centre tell you why.

Don't rely on X-Cache-Plugin: SpeedOfLight.Pro. It is sent on every response, cached or not.

1. A cookie or header is blocking the cache

If a theme or plugin sets a cookie on every visit, or marks pages private, no-store or no-cache, Speed of Light won't store those pages. That is deliberate, because they might be personal. The Health check Pages can be stored in the cache names the cookie or header and the page it was seen on. Ask the plugin's developer to set the cookie only when it's needed. If the cookie never changes what a page shows, allow it with the sol_cache_allowed_set_cookies filter (see Page cache).

2. The drop-in or WP_CACHE is missing

Page caching needs wp-content/advanced-cache.php and define( 'WP_CACHE', true ) in wp-config.php. Speed of Light sets both up and puts a missing drop-in or WP_CACHE line back automatically. You'll see "Page caching was repaired automatically" or "Page caching was switched back on automatically" when it does. If another caching plugin owns advanced-cache.php, Speed of Light won't overwrite it. Deactivate the other plugin and setup retries by itself. If wp-config.php can't be edited, Cache → Local Cache explains what to add.

3. The cache folder isn't writable

The web server must be able to write to wp-content/cache/sol. Fix the folder permissions (usually 755) or ask your host.

4. A session cookie or query string

A leftover login, cart or comment cookie makes every request bypass the cache, by design. URLs with query strings are only cached when every parameter is a known tracking parameter, such as utm_source or gclid. Test in a fresh private window, without browser extensions, and with a clean URL.

5. The page is excluded

Check Cache → Exclusions. Remember that paths match whole segments: /shop also covers /shop/…. Pages that define DONOTCACHEPAGE are never cached. WooCommerce and many plugins do this on carts and checkouts, which is correct.

Running two page-cache or all-in-one optimization plugins at once is the most common cause of both "pages won't cache" and "pages look broken". Keep one. Health's Conflicts group and the Alerts centre name well-known offenders.

The preloader reports 403 errors or warms slowly

The preloader requests each page from your own server. If a firewall, security plugin or CDN answers with 403 Forbidden, the error names what blocked it: Cloudflare (with a Ray ID), ModSecurity, Wordfence, or your web server itself. To let it through:

  • Firewall or security plugin: allowlist your own server's IP address. Preloader requests also carry an X-SOL-Preload: 1 header and a SpeedOfLightPreloader/ user agent that you can recognize. Headers can be copied by anyone, so allowlisting by IP is safer.
  • Cloudflare or another edge: make sure your server's own requests aren't being challenged as bots.

Slow warming is usually the preloader protecting your server. It starts with 2 parallel requests, backs off when responses slow down or fail, and pauses for 10 minutes after repeated overload. The Alerts centre says so when this happens. If your host rate-limits requests, lower URLs per batch or raise Delay between batches under Cache → Local Queue → Preload Settings. See Preloader.

Insights scans fail

The banner at the top of Insights explains the cause and which pages were affected. When a firewall or CDN blocks the scanner, click Copy allowlist details and add them to your firewall's allowlist, or send them to your host. On Cloudflare, you can turn on Allow the Speed of Light scanner through Cloudflare under Cache → Edge Cache. If you've reached the daily scan limit, Insights shows when scans resume.

A page looks unstyled after turning on Remove Unused CSS

Remove Unused CSS keeps only the rules a page appears to use. Styles that appear only after an interaction, such as a class added by JavaScript, an accordion, a mega-menu or a third-party widget, can occasionally be missed.

Keep the safety fallback on

Keep original CSS as a safety fallback (on by default) loads the original stylesheets after the first paint, which restores anything that was missed.

Safelist the class

Under Optimize → CSS → Advanced CSS options, add the class prefix to CSS selectors to safelist from RUCSS, one per line, without the leading dot. Or exclude the whole stylesheet with Exclude stylesheets from RUCSS.

Or turn it off for one page

In the editor's SOL Optimization box, tick Disable Remove Unused CSS.

Regenerate

Run wp sol rucss clear, then clear the page cache so the page is rebuilt with the new rules.

A menu, form or slider stopped working after turning on JavaScript delay

Add ?soldelay=0 to the page URL. If the problem disappears, delay is the cause. Add the script to Exclude scripts from delay, or switch Delay Mode from Aggressive to Safe. See JavaScript optimization.

An optimization seems to break a page

If an optimization step fails, returns nothing or would cut the page short, Speed of Light serves the original page and logs the event. To isolate the cause, turn the opt-in tools off one at a time (Critical CSS, Remove Unused CSS, Combine, JavaScript delay, HTML minify), clear the cache and reload. To take one page out of every optimization, add it to Cache → Exclusions.

Enabling the object cache made a plugin look deactivated

WordPress keeps its list of active plugins in its options cache. When a persistent object cache first comes online, WordPress could briefly read an old copy of that list. Speed of Light's drop-in prevents this by flushing those entries on its first load. If you ever see it, deactivate and reactivate Speed of Light, or switch the object cache off and on once under Object Cache. Nothing was actually deactivated, and your settings and license are untouched.

Redis won't connect

Speed of Light tests the connection before enabling and explains any failure. If Redis becomes unreachable later, your site keeps working: transients fall back to the database, and the panel shows Enabled — running in memory with the reason. The Alerts centre also says "Redis isn't answering". Check:

  • Redis is running (redis-cli ping should answer PONG).
  • The host, port, socket path, password and TLS settings are correct, and you clicked Save connection before Test connection.
  • The web server can open the socket file, if you use one.
  • Your host's own WP_REDIS_* settings in wp-config.php are what you expect.

To stop CLI runs from touching Redis, define WP_REDIS_DISABLED as true in wp-config.php. It is a PHP constant, not an environment variable. You can also simply turn the object cache off. Everything else keeps working. See Object cache (Redis).

Cloudflare isn't serving pages from the edge

  • Rules not deployed. Connecting isn't enough: click Deploy Rules under Cache → Edge Cache. Health flags "connected but rules not deployed".
  • A cookie or query string. Logged-in, cart, session and language cookies always skip the edge, and so do URLs with query strings. Test logged out, with a clean URL.
  • A staging copy. Cloudflare changes are paused on a copy of the site until you confirm its address (see the Alerts centre).
  • The first visit. A new page can be served once before its cloud optimization is ready. Speed of Light keeps that version's edge lifetime short and purges it when the optimized page is warmed.

Look at Cloudflare's own cf-cache-status header to see edge hits, and X-SOL-Cache to see the local cache.

The admin screen looks broken after an update

Hard-refresh the page (Cmd/Ctrl + Shift + R). Your browser may be holding an old copy of the admin app. If a CDN or another optimizer caches wp-admin files, purge it. This only affects the admin screens, never the pages visitors see. If it persists, re-upload the latest plugin zip.

Logs, debug output and starting over

  • Settings → Logs shows the Activity Log of recent operations, kept for 14 days. You can copy, export or clear it.
  • For deeper tracing, define SOL_DEBUG as true in wp-config.php. Debug lines then go to your PHP error log. WP_DEBUG alone doesn't turn them on.
  • Settings → Export / Import saves or restores your configuration. Credentials such as your Cloudflare token are never included.
  • Settings → Reset → Reset All Settings restores factory defaults and clears all caches. It also removes your Cloudflare connection. It can't be undone.

Still stuck?

Run Run health check in Health. If anything isn't green, click Copy diagnostics and email the result to help@speedoflight.pro with your site URL and what you're seeing. We'll point you to the fix. For what each Health check means, see Insights & Health.

NextFAQ

Reference

Frequently asked questions

What exactly does Speed of Light (Pro) do?

It makes WordPress fast in three layers. The first is a full-page cache, served by an advanced-cache.php drop-in before WordPress loads, with ready-made gzip/Brotli copies. The second is optional Cloudflare edge caching. The third optimizes the pages WordPress still has to build.

On licensed and trial sites, a cloud engine renders your pages in headless Chrome at desktop and phone widths. From that it produces critical and used CSS, LCP fixes for each viewport, layout-shift fixes, and image and font plans, with template-based plans for large sites.

You also get a built-in Redis object cache, WebP/AVIF images (originals kept), real-user monitoring, an Alerts centre, a Recommendations list and Autopilot, which applies cloud-verified, publisher-safe changes. Critical CSS, Remove Unused CSS, JavaScript delay and HTML minify are opt-in tools.

Do I need Redis to use it?

No. Redis only powers the optional object cache, which caches WordPress's internal database lookups. The page cache, edge cache and every optimization work without it.

If you do have Redis, Speed of Light includes its own object-cache drop-in with live diagnostics and value compression. It tests the connection before enabling, explains any failure, and respects your host's WP_REDIS_* settings. If Redis later becomes unreachable, your site keeps working: WordPress falls back to database transients, so nothing is lost, and the Alerts centre tells you what happened.

Does it work without Cloudflare?

Yes. The page cache works on any host with no CDN at all. Cloudflare is an optional edge layer that caches pages across its global network for visitors far from your server. Everything else (page caching, minification, Remove Unused CSS, Critical CSS, image conversion, object cache, real-user monitoring) works without it.

Is the Cloudflare edge caching really free?

Yes. It uses Cloudflare's Cache Rules, which are available on the free plan. It creates no Page Rules and needs no paid add-ons such as APO or Argo. An optional, free Tiered Cache switch is available too.

Setup takes three steps: connect a scoped API token, choose your site, and click Deploy Rules. Staging copies can't change your live zone: Cloudflare changes are paused on a copy until you confirm its address.

Is my Cloudflare token safe? What permissions does it need?

Speed of Light uses a scoped API token with Zone → Zone → Read, Zone → Cache Purge → Purge and Zone → Cache Rules → Edit. Add Zone → Firewall Services → Edit only if you want the optional scanner allowlist. New connections don't accept the Global API Key, which can do anything on your account.

The token is stored in your own WordPress database, is never sent back to your browser, and is removed from settings exports. It isn't encrypted at rest, so protect admin and database access as usual, and revoke the token in Cloudflare if you stop using it.

Will it break my theme, WooCommerce, Elementor or other page builders?

It's built not to. The tools that can change how a page looks or behaves (Critical CSS, Remove Unused CSS, JavaScript delay and HTML minify) are off until you turn them on. Speed of Light detects popular themes, page builders and conflicting plugins, and warns you where they overlap.

For WooCommerce, cart, checkout and account pages are never cached, and payment scripts (Stripe, PayPal, Square, Braintree) are never delayed. If any optimization step fails, the original page is served instead. You can exclude a single page, or switch a feature off for one post, at any time.

Does it cache pages for logged-in users?

No, and that's deliberate. The cache is for logged-out visitors only. Logged-in users, commenters and anyone with a session or cart cookie always get a fresh page from WordPress, even when your site uses a custom login cookie name. There is no per-user cache, so one person never sees another person's page.

Optimizations are skipped for logged-in users too, so the admin bar and editing tools are never touched.

What about my ads and analytics: will delaying JavaScript break them?

JavaScript delay is off by default. When you turn it on, ad loaders are never delayed in any mode. That covers AdSense, Google Publisher Tag, Raptive, Mediavine, Ezoic, Prebid and Amazon. Consent tools (including IAB TCF), CAPTCHAs, payment scripts and scripts marked data-no-optimize or data-cfasync="false" are never delayed either.

Analytics and tag managers run immediately unless you also turn on the separate Also delay analytics & tracking pixels option.

Can I run it alongside another caching plugin (WP Rocket, W3 Total Cache, LiteSpeed, WP Super Cache)?

No. Two full-page cache plugins cause doubled optimization and broken pages. Speed of Light detects WP Rocket, W3 Total Cache, LiteSpeed Cache, WP Super Cache, FlyingPress, NitroPack and others, and tells you to deactivate them.

It never overwrites another plugin's advanced-cache.php. It pauses its own page caching until the conflict is gone. Its Recommendations never suggest something that clashes with a plugin you run, such as minify while Autoptimize is minifying. If you keep a separate image optimizer, choose one tool for images, not both.

Is multisite supported?

Yes. Caching and optimization run per site across a network. Deactivating Speed of Light on one site doesn't switch caching or the object cache off for the others. The Redis object-cache drop-in and its connection are managed once for the whole network. Database cleanup is disabled on multisite by design, to avoid cross-site risk.

Will it slow down my admin (wp-admin)?

No. Caching and optimization only run on logged-out, front-end page views. wp-admin, AJAX, cron, the REST API and the Customizer are left alone. A fresh install also makes no changes to your login page or the admin. Admin tweaks are all opt-in.

Which image formats does it produce, and does it use an image CDN?

It makes WebP (the default) or AVIF copies of your images. New uploads keep the original file, and the WebP/AVIF copy is made on your server shortly afterwards. Originals can be restored per image (Restore original in the Media Library) or all at once. Replacing originals in the browser before upload is an explicit opt-in.

Your existing library is converted only when you click Start Compression. Autopilot never converts or resizes media library files. On licensed sites the cloud does the encoding, with your server as the fallback. Images are always stored on, and served from, your own domain. There is no image CDN.

Speed of Light keeps your theme's srcset, sizing it from cloud measurements. It adds lazy loading, width and height (only to content images), and fetchpriority on the hero image.

Does it send data anywhere? Is real-user monitoring private?

Real-user monitoring stores privacy-bounded summaries on your site: no IP addresses, no query strings and no cookies, just the page path and whether the visitor was on mobile or desktop. When it is enabled on a licensed or trial site, those summaries are also forwarded to the Speed of Light cloud for analysis.

Strict per-site limits apply, and data on your site is deleted after 30 days. You can switch monitoring off, or clear its data (which also asks the cloud to delete its copy), under Insights → Core Web Vitals.

Cloud scans load your public pages the way a visitor would. Your license and updates go through Freemius.

How do I stop a specific page from being cached or optimized?

Add it under Cache → Exclusions. Excluded pages skip everything: caching, preloading and optimization. Page paths match whole segments from the start of the path: /cart matches /cart/… but not /cartoons. A trailing * is a prefix, and lines starting with ^ or wrapped in #…# are regular expressions. The defaults are /wp-admin, /wp-login.php, /xmlrpc.php, /wp-json, /cart, /checkout and /my-account. Feeds and search are always bypassed anyway.

To turn off just one feature for a post, use the editor's SOL Optimization box: Disable Remove Unused CSS or Disable JS Minify. Developers can also define DONOTCACHEPAGE.

Is there WP-CLI support?

Yes, under wp sol. The commands are:

  • wp sol clear (with --ids, --urls or --sites)
  • wp sol preload (with --run, --turbo and sizing flags)
  • wp sol rucss clear and wp sol rucss stats
  • wp sol js-minify clear
  • wp sol object-cache status|enable|disable|update-dropin|flush|diagnostics|groups
  • wp sol convert, convert-one and convert-reset for images

See WP-CLI, REST API & hooks.

What PHP and WordPress versions are required?

WordPress 6.0+ (tested up to 7.1) and PHP 7.4+. On older PHP, the plugin shows a notice and doesn't load. It also needs write access to wp-content/ and wp-config.php to install its cache drop-in and turn on WP_CACHE. If it can't, it explains the problem in plain English.

How does the Cloudflare integration keep the edge cache fresh?

When you publish or edit content, Speed of Light purges the affected URLs through Cloudflare's purge API. Site-wide changes, such as a new theme or an edited menu, purge everything. Purges are combined into one call per request and throttled, so a burst of edits never floods Cloudflare. Purges from a staging copy are blocked until you confirm its address. Cache Rules decide what is cached, and purges keep it fresh. No cache tags are used.

Does the cache expire on its own and leave visitors on stale pages?

New installs use a 10-hour cache lifetime. You can choose anything from 1 hour to 30 days, or Never, under Cache → Local Cache → Cache Expiry. Content changes clear exactly the affected pages straight away, and the preloader re-warms them in the background.

Pages that contain a WordPress security token (nonce) for logged-out visitors are always rebuilt within 10 hours, whatever the lifetime setting, so forms and buttons keep working. Extreme Cache Mode, which never clears automatically, is an advanced option and off by default.

What is Autopilot, and can I turn it off?

Autopilot runs on licensed and trial sites, under Insights → Autopilot. It applies only publisher-safe changes: page cache, static asset cache, LCP preload and fetchpriority, image dimensions, responsive image serving, font optimization and instant navigation.

It verifies each change with a rescan and rolls back anything that causes problems, blocking that change for 14 days. It makes at most one change set per day. If the cloud is unreachable during the check, it retries later instead of rolling back.

It never touches JavaScript delay, Critical CSS, Remove Unused CSS, video embeds or your media library files, and never changes a setting you set yourself. Undo last changes restores your previous settings. Switch Autopilot off and it stays off.

Are there one-click, aggressive or developer modes to choose from?

There is no global performance level. Instead, the Dashboard's Recommendations list explains each suggested change and offers Apply all, and Autopilot handles the publisher-safe changes on licensed and trial sites.

Where a feature needs more control, it has its own. JavaScript delay has a Delay Mode of Safe (the default) or Aggressive. For CSS, you choose one delivery method: Remove Unused CSS, Critical CSS or Combine. Any setting you change yourself is kept.

How does its object cache differ from a page cache and the edge cache?

They cache different things and work together:

  • The page cache stores the finished HTML of a page, served before WordPress loads.
  • The edge cache (Cloudflare) stores that same HTML across Cloudflare's network, near your visitors.
  • The object cache (Redis) stores WordPress's internal pieces (database results, options, transients), so pages that can't be page-cached, such as wp-admin, logged-in views and WooCommerce, run with fewer database queries.
Does the Redis object cache use persistent or pooled connections?

It is a persistent object cache in the WordPress sense: data lives in Redis between requests. It opens a fresh connection on each request, using phpredis or the bundled Predis library, and doesn't use connection pooling. Keys are unique per site, even on a shared Redis server, and expire after 30 days by default. Flushing only removes this site's keys.

What is Remove Unused CSS (RUCSS), and is it risky?

Remove Unused CSS strips the rules a page doesn't use, which shrinks render-blocking CSS. It is off by default, and Autopilot never turns it on. On licensed and trial sites, used CSS generated by the cloud from a real browser render replaces the local version.

It ships with broad safelists for builders, WooCommerce and common plugins. Keep original CSS as a safety fallback (on by default) loads the full stylesheets after the first paint. You can turn it off for one post in the SOL Optimization box. Only one CSS delivery method can be on at a time: Remove Unused CSS, Critical CSS or Combine.

How does font optimization work? Does it combine my Google Fonts?

Self-host Google Fonts and Preload fonts are off by default and appear in your Recommendations. Autopilot may turn them on as part of font optimization on licensed and trial sites.

Self-hosting downloads the font files (Latin subsets) to your server in the background, never during a visitor's request, then switches pages to the local copy. Text uses font-display: swap, and icon fonts use font-display: block. Separate font stylesheets are not merged. The gain comes from self-hosting and preloading.

Does it combine or concatenate my JavaScript?

No. It can minify, defer and delay scripts until the first interaction, all opt-in and off by default, but it never bundles them into one file. With delay on, ads, consent tools, CAPTCHAs, payment scripts and jQuery/WordPress core are never delayed. Analytics are only delayed if you opt in.

What does the database cleanup feature do?

SOL → Clean shows how many old revisions, auto-drafts, trashed posts and comments, spam, expired transients and orphaned metadata you have. You can clean each type, or click Run Safe Cleanup for all of them. Cleanups run as soon as you click and delete permanently, so keep a backup and restore anything you need from the Trash first. Your published content and settings are never touched.

Under Settings → Debloater, Daily clean expired transients is on by default, and Daily optimize WordPress tables is an opt-in. Cleanup is disabled on multisite.

Which cookies stop a page from being cached?

More than 20 built-in patterns: WordPress login (wordpress_logged_in, wordpress_sec), password-protected posts (wp-postpass), commenters (comment_author), WooCommerce, Easy Digital Downloads, YITH, Jetpack, Ecwid, Bookly and more. Cookies you add under Cache → Exclusions are added to the list.

Separately, a page isn't stored if the response sets a cookie (WPML and Polylang language cookies excepted) or is marked private or no-store. Health names the cookie or header that is responsible.

How do I uninstall cleanly, and what does it leave behind?

Deleting the plugin removes its options, its own database tables (used CSS, real-user metrics, the activity log and the preload queue), its cache files and its post metadata. It also removes the drop-ins it installed (advanced-cache.php, the Redis object-cache.php and its config file), but only after confirming they are its own. Cleanup also runs when the licensing SDK skips its uninstall event, for example on staging clones or via WP-CLI. Your site then runs on standard WordPress behavior.

How is it licensed, and what are the plans?

One plan, and every feature on every tier. Tiers differ only by the number of sites:

  • 1 site: $20/year.
  • 50 sites: $99/year.
  • Unlimited sites: $179/year.

Prices are in USD. Checkout is through Freemius (cards and PayPal). Every tier starts with a 7-day free trial with full cloud features. A card is required, and the trial converts unless you cancel. We can't offer refunds after a trial converts.

There's no API key to paste: cloud features authenticate with your license automatically. See Licensing & free trial.

What is Insights?

Insights is the cloud-backed check of your pages. It loads them in headless Chrome at desktop and phone widths and explains, in plain English, what slows each page down: the main image (LCP), responsiveness (INP), layout shifts (CLS), server response (TTFB), and image, font and asset problems. Each finding comes with an estimated saving and either a Fix it button or clear steps.

If scans fail, Insights explains why. If a firewall is blocking the scanner, it offers Copy allowlist details. It needs an active license or trial. See Insights & Health.

How can I check that a page is being cached?

Open the page in a private window, load it twice and look at the X-SOL-Cache response header:

  • HIT: served from the cache.
  • MISS: it was just built.
  • BYPASS: it was deliberately not cached, and SOL → Health tells you why.

The X-Cache-Plugin header appears on every response, so it doesn't tell you whether a page was cached.

What are alerts, and will they email me?

The Alerts centre explains problems in plain English: what's happening, what visitors notice and the next step. Examples include caching not running, cookies blocking the cache, Redis or Cloudflare issues, license or scan problems, and Autopilot changes. Alerts appear as one compact notice in wp-admin, an admin-bar badge, the dashboard widget and the Alerts panel in Health. They wait until a problem persists and clear themselves when it's fixed.

Email for critical problems is on by default and goes to the site admin email. It is sent only after a problem has lasted 30 minutes, at most once per alert per day and three times a day in total, with a follow-up when the problem is resolved.

How does the free trial work?

Every tier has a 7-day free trial with the full product, including cloud optimization, Insights and Autopilot. A card is required at checkout. The trial converts to a paid yearly subscription unless you cancel before it ends. Cancel from your account page or the Freemius customer portal. We can't offer refunds after a trial converts, so the trial is the time to decide.

What happens if my license expires?

Your site stays fast. Page caching and the local optimizations you've turned on keep working. Cloud optimization, Autopilot, Insights scans, plugin updates and support stop until you renew. Speed of Light shows an alert explaining this, with a link to your account.

Does it handle very large sites?

Yes. The preloader keeps its queue in its own database table and warms the 50,000 most important URLs first: home page, recently changed content, main archives, then newest first. The rest are cached on their first visit. You can change the limit with the sol_preload_max_urls filter.

It slows down automatically when your server is busy. The cloud uses template-based plans, so pages it hasn't scanned yet can borrow a plan from pages of the same type. See Large sites.

Can I move my license to another site?

Yes. Deactivate the license on the old site from the Account page in the SOL menu, then activate it on the new site. If the old site is already gone, email help@speedoflight.pro and we'll help.

Still stuck?

Ask the people who wrote it.

Send us the page and the setting involved. We reply within 24–48 hours.