Cyclone Static

Description

Cyclone Static generates fully-rendered static HTML files for every page on your WordPress site and instructs Apache to serve them directly — bypassing PHP, WordPress, and the database for anonymous visitors.

When a static file exists for a requested URL, Apache reads it from disk and sends it without starting PHP or querying the database. The visitor receives a complete HTML page. Their browser runs your JavaScript, plays your audio, renders your animations — everything works as it did before, because the static file contains the same HTML WordPress would have generated.

Logged-in users, POST requests, query strings, and administrative paths bypass the static cache and receive live WordPress as normal.

Key features

  • Static file serving — Apache serves files directly from disk. PHP and the database are not involved in serving anonymous page requests.
  • Automatic regeneration — When you publish or update a post or page, it is automatically queued for regeneration. You do not need to do anything.
  • Reduced attack surface — Static HTML files do not execute PHP or query a database. Common WordPress-targeted attack vectors that require a live PHP process — such as SQL injection via PHP, PHP code execution, and xmlrpc.php abuse — do not apply to anonymous page requests served as static files.
  • CDN integration — Works alongside W3 Total Cache. Direct integration with Bunny.net, Cloudflare, KeyCDN, and Amazon CloudFront is available in Cyclone Static Pro.
  • W3 Total Cache compatible — Installs its .htaccess rules before W3TC rules. Works alongside or without W3TC.
  • Non-destructive — Deactivating the plugin removes the .htaccess rules and WordPress resumes normal operation. Your cached files are not deleted without your explicit consent — a prompt appears when you deactivate, asking whether to keep or delete them.
  • Free and open — No license required. Support via the WordPress.org community forums.

System requirements

  • WordPress 6.0 or later
  • PHP 8.0 or later
  • Apache web server with mod_rewrite enabled
  • .htaccess support enabled (AllowOverride All or equivalent)
  • WordPress Multisite is not supported in this version — Multisite support is available in Cyclone Static Pro

Nginx users: Cyclone Static manages .htaccess automatically on Apache. If your server runs Nginx, the Settings page includes a ready-to-paste Nginx server block under Settings Nginx Configuration.

CDN support

The free version works automatically alongside W3 Total Cache — CDN purges are routed through W3TC when it is active.

Direct API integration with Bunny.net, Cloudflare, KeyCDN, and Amazon CloudFront is available in Cyclone Static Pro.

Privacy

Cyclone Static does not collect, transmit, or store any personal data. The queue table stores only URLs. No external service is contacted except the CDN purge APIs you explicitly configure.

Support

Support is provided via the WordPress.org community forums. Post your question there — answers are public, so search first as your question may already be answered. For private inquiries, you can reach us at support@kryptonmediagroup.com. Confirmed bugs are addressed through plugin updates. Private one-on-one support is not offered via the forums.

External Services

Cyclone Static can optionally connect to the following third-party services to purge cached content from your CDN. These connections are only made when you configure a CDN provider under Settings CDN Integration and a purge is triggered. No data is sent to these services unless you explicitly configure them.

Bunny.net

Used for CDN cache purging. Your Bunny.net API key and Pull Zone ID are sent to the Bunny.net API.
* Service: https://bunny.net/
* API documentation: https://docs.bunny.net/reference/purgepublicpullzone
* Privacy policy: https://bunny.net/privacy/

Cloudflare

Used for CDN cache purging. Your Cloudflare API token and Zone ID are sent to the Cloudflare API.
* Service: https://www.cloudflare.com/
* API documentation: https://developers.cloudflare.com/api/resources/cache/methods/purge/
* Privacy policy: https://www.cloudflare.com/privacypolicy/

KeyCDN

Used for CDN cache purging. Your KeyCDN API key and Zone ID are sent to the KeyCDN API.
* Service: https://www.keycdn.com/
* API documentation: https://www.keycdn.com/api
* Privacy policy: https://www.keycdn.com/privacy

Amazon CloudFront

Used for CDN cache invalidation. Your AWS Access Key, Secret Key, and CloudFront Distribution ID are sent to the Amazon CloudFront API.
* Service: https://aws.amazon.com/cloudfront/
* API documentation: https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_CreateInvalidation.html
* Privacy policy: https://aws.amazon.com/privacy/

Installation

  1. Upload cyclone-static.zip via Plugins Add New Upload Plugin
  2. Activate the plugin
  3. Go to Cyclone Static Dashboard
  4. Confirm .htaccess Rules shows ✓ Installed in the System Info panel
  5. Click Discover from Sitemap to queue all pages for initial generation
  6. Monitor the Queue Depth stat card until generation is complete

Initial generation time

At default settings (2 pages every 60 seconds), a 4,000-page site takes several hours for initial full generation. Increase Batch Size in Settings to speed this up on servers with capacity to spare.

After initial generation, the cache maintains itself automatically as you publish and update content.

FAQ

Does this work with page builders like Divi and Extra?

Yes. Cyclone Static captures the fully-rendered HTML output of each page as WordPress and your page builder produce it, including all JavaScript and CSS references. The static file closely matches what a live WordPress request would produce.

Does this break my admin or editor experience?

No. Logged-in users bypass the static cache and receive live WordPress. Divi’s visual builder, preview functions, and WordPress admin features work as before.

What happens if I deactivate the plugin?

Deactivation removes the Cyclone Static block from .htaccess — Apache falls through to WordPress for all requests. A prompt appears asking what to do with your cached files: Keep cache files (recommended if you plan to reactivate — files are served again immediately upon reactivation) or Delete cache files (removes them from disk now). If you dismiss the prompt without choosing, your files are kept.

What happens if I delete the plugin?

Deleting the plugin removes the .htaccess rules, drops the queue database table, and removes plugin settings. Your cached files are only deleted if you chose Delete cache files when you deactivated — if you chose to keep them or never saw the prompt, they remain on disk at their original location.

Does it work with W3 Total Cache?

Yes. Cyclone Static installs its .htaccess rules before W3TC rules, so static files are served by Apache before W3TC is consulted. CDN purges are routed through W3TC automatically when it is active.

Can I remove W3 Total Cache if I install Cyclone Static?

Yes, but you must follow the safe removal procedure. See the Removing W3 Total Cache guide in the collapsible section on the Cyclone Settings page. Removing W3TC without preparation can break your site’s styles and scripts.

Does it work with Cloudflare?

The free version works behind Cloudflare without any special configuration — Cloudflare will cache and serve your static files as normal, and its CDN cache will refresh as files expire or are manually purged from the Cloudflare dashboard. Direct Cloudflare cache purging via API is available in Cyclone Static Pro.

Does it work with Nginx?

Yes, with manual configuration. Cyclone Static manages .htaccess automatically on Apache but cannot write Nginx config files. The Settings page includes a ready-to-paste Nginx server block under Settings Nginx Configuration. Copy that snippet into your site’s server block before the location block that passes requests to PHP-FPM.

Does it support Brotli compression?

Yes, when the php-brotli extension is installed on your server. Cyclone Static automatically generates a pre-compressed index.html.br alongside the standard index.html.gz for every cached page. Apache serves the best variant the browser supports — Brotli first, then gzip, then uncompressed. If php-brotli is not installed, gzip and uncompressed files are generated as normal with no configuration required.

What happens to cached pages when a comment is posted?

When a new comment is posted and approved, Cyclone Static automatically re-queues the parent post for regeneration so the cached page reflects the updated comment count and list. Comments awaiting moderation do not trigger a regeneration — the page is only updated when the comment transitions to approved status.

What is the disk space requirement?

It depends on the complexity of your pages. A typical WordPress page generates a static file of 50–300 KB. A 4,000-page site would require roughly 200 MB – 1.2 GB. Cyclone Static displays your current cache size and available disk space on the Dashboard.

Does it support WooCommerce?

Cyclone Static can run on WooCommerce sites with manual configuration. Add /cart/, /checkout/, /my-account/, and /wc-api/ to the exclusions list under Settings Exclusions — this prevents session-sensitive pages from being cached. Product pages cache and serve correctly for anonymous visitors; Add to Cart functions normally via WooCommerce’s AJAX handling. Stock level display may lag until pages regenerate.

Does it support WordPress Multisite?

No. Multisite support is available in Cyclone Static Pro, distributed from kryptonmediagroup.com/cyclone-static.

Reviews

There are no reviews for this plugin.

Contributors & Developers

“Cyclone Static” is open source software. The following people have contributed to this plugin.

Contributors

Translate “Cyclone Static” into your language.

Interested in development?

Browse the code, check out the SVN repository, or subscribe to the development log by RSS.

Changelog

1.1.38

  • Fixed: Regenerating an already-cached page was a silent no-op — the generator’s loopback HTTP request was served the existing static file by Apache instead of fresh PHP output, so the cache was overwritten with its own stale content. The .htaccess rules now pass generator requests (identified by the X-Cyclone-Internal header) through to PHP.
  • Fixed: When a loopback URL is configured, the Host header is now included in the fetch request so Apache can route to the correct virtual host on multi-site servers.

1.1.37

  • Fixed: Changing Settings Reading (front page type, front page, or posts page assignments) no longer requires a manual full-site regeneration — those option changes now trigger automatic full regeneration the same way widget and menu changes do.

1.1.36

  • Fixed: On sites with a static front page and a separate Posts Page (Settings Reading “A static page”), publishing, unpublishing, or deleting a post did not queue the Posts Page for regeneration. Only the home page (/) was re-queued, leaving the Posts Page with stale content until the next full-site regeneration. The posts page is now detected automatically and queued alongside the home page whenever post content changes.

1.1.35

  • Fixed: All cache-serving RewriteRules and the anti-recursion guard now use the [END] flag instead of [L]. The [L] flag ends the current rewrite pass but restarts the engine with the new URL, allowing the WordPress block to match the internal cache-file path and enter a redirect loop. [END] terminates all rewrite processing unconditionally, preventing the loop entirely. Sites with high traffic could accumulate tens of thousands of AH00124 errors per day in the Apache error log.

1.1.34

  • Fixed: mod_rewrite recursion loop on hosting configurations where the cache directory path does not fall under wp-content — root .htaccess now adds an explicit early pass-through rule for the cache path as a belt-and-suspenders guard against any recursion scenario.
  • Fixed: No Cache-Control headers were emitted for cached pages, leaving CDN cache TTLs undefined. Compressed variants (Brotli/gzip) now receive public, max-age=31536000, immutable; the plain-HTML fallback receives public, max-age=3600. Existing users: purge your CDN cache after upgrading.

1.1.33

  • Fixed: On hosts with mod_brotli enabled globally, pre-compressed cached pages were re-compressed on top of the existing gzip encoding when the client sent Accept-Encoding: br, producing a corrupted body that browsers reject with ERR_CONTENT_DECODING_FAILED (blank pages or raw compressed bytes rendered as text). The cache directory’s .htaccess now declares Content-Encoding via AddEncoding in mod_mime’s type_checker phase, which runs before the output filter chain so mod_brotli correctly detects the encoding and skips re-compression. Upgrading installs are migrated automatically on the next request. Remember to purge any CDN cache in front of the site after the upgrade — edge caches may have pinned the bad responses.

1.1.32

  • Fixed: Mobile browsers (notably Chrome on Android) served cached pages as a “download.tgz” archive instead of rendering them as HTML. Root cause was mod_mime’s type_checker overriding the RewriteRule’s T=text/html based on the .gz / .br file extension; the cache directory’s .htaccess now uses ForceType and per-file Content-Encoding headers scoped by FilesMatch, which survive internal subrequests reliably. Upgrading installs are migrated automatically on the next request.

1.1.31

  • Fixed: Pre-compressed .gz and .br cache files failed to serve on Apache configurations whose default authz policy denies access under wp-content — the cache directory’s .htaccess now grants access explicitly instead of relying on a blanket “Require all denied” that also blocked internal rewrite subrequests. Upgrading installs are migrated automatically on the next request.

1.1.30

  • Added: Admin notice for users upgrading from v1.1.28 or earlier — detects the old cache directory (wp-content/cyclone-static) left behind by the cache location change and offers a one-click delete or dismiss

1.1.29

  • Fixed: Inline <script> in deactivation modal moved to wp_add_inline_script() per WP.org coding standards
  • Fixed: .htaccess path now uses get_home_path() instead of ABSPATH constant directly
  • Changed: Default cache directory moved to uploads folder (wp-content/uploads/cyclone-static) per WP.org guidelines
  • Changed: Custom cache directory setting now restricted to the uploads directory instead of all of wp-content
  • Changed: Removed dead code — unused License methods (is_pro, supports_multisite, get_item_limit, get_key, upgrade_url), unused utility methods (file_exists_for_url, get_cached_count), and write-only CDN credential option keys

1.1.28

  • Added: Deactivation modal — when deactivating the plugin, a prompt now asks whether to keep or delete cached files; dismissing without choosing defaults to keep
  • Changed: Uninstall no longer silently deletes the cache directory; files are only removed if the user explicitly chose “Delete cache files” at deactivation
  • Fixed: Settings page fatal error caused by missing PHP closing tag after template variable assignment

1.1.27

  • Changed: Removed all trialware and upgrade-prompt UI; plugin is now fully functional with no feature gates
  • Changed: Freemius SDK config updated to reflect free-only distribution on WordPress.org
  • Fixed: Inline <script> blocks in settings view moved to wp_add_inline_script() per WP.org coding standards
  • Fixed: Removed load_plugin_textdomain() call (not needed since WordPress 4.6 for WP.org-hosted plugins)
  • Added: External Services disclosure in readme.txt for Bunny.net, Cloudflare, KeyCDN, and CloudFront

1.1.26

  • Security: Added missing output escaping on several admin dashboard and pages-list elements (esc_attr on CSS class/style values; esc_html on human_time_diff output)
  • Security: Added missing wp_unslash() before sanitize_text_field() on bulk-action POST field

1.1.20

  • Added: Amazon CloudFront CDN support (Pro); WordPress Multisite support (Pro)
  • Added: Compression status rows in System Info — shows gzip and Brotli availability and whether cached files are present; includes install instructions if php-brotli is missing
  • Added: Throttle Delay setting — configurable pause between page fetches in a batch to prevent cache generation from affecting live visitors
  • Changed: Default batch size reduced from 20 to 2 for safer out-of-box behaviour on shared/VPS hosting
  • Fixed: Plugin update no longer disrupts .htaccess — hooks into upgrader_process_complete to rewrite rules cleanly after each update
  • Fixed: First-activation redirect now lands on the correct dashboard page

1.1.6

  • Added: Brotli pre-compression — generates index.html.br alongside index.html.gz when php-brotli extension is available; Apache serves the best variant the browser supports
  • Added: Comment invalidation — posting or approving a comment now re-queues the parent post for regeneration
  • Added: Nginx configuration snippet in Settings — collapsible panel with a ready-to-paste server block for Nginx users
  • Fixed: .htaccess header block now correctly sets Content-Encoding and Vary for both Brotli and gzip responses

1.1.5

  • Fixed: W3 Total Cache removal guide moved from broken Help tab to a collapsible section on the Settings page
  • Fixed: Removed dead add_help_tab() calls that were registered too late in the WordPress lifecycle to appear

1.1.4

  • Fixed: Widget, sidebar, nav menu, and Customizer changes now trigger a full site regeneration — previously cached pages retained stale widget output after any widget edit

1.1.3

  • Fixed: Dynamic shortcodes settings UI now correctly reflects configuration state

1.1.2

  • Fixed: .htaccess block now auto-restores if deleted externally (e.g. via Permalinks save)
  • Fixed: Version stamp check now also verifies block presence, not just version match

1.1.1

  • Added: Pre-compressed gzip delivery — static pages served as .gz files with reduced server CPU overhead
  • Fixed: E=no-gzip:1 flag prevents mod_deflate double-compressing pre-compressed files
  • Fixed: RemoveEncoding .gz prevents Apache adding duplicate Content-Encoding from file extension

1.1.0

  • Fixed: .htaccess restructure — replaced pass-through RewriteRule [L] patterns with negative RewriteCond conditions, resolving REST API 404 errors that broke post saving, YouTube embeds, and AVIF previews
  • Fixed: Plugin now auto-rewrites .htaccess rules after in-place upgrades (no deactivate/reactivate required)
  • Added: MIME type declarations for AVIF, WebP, and WOFF2

1.0.0

  • Initial release