Surge is a very simple and fast page caching plugin for WordPress.

Overview
=== Surge ===
Contributors: kovshenin
Donate link: https://github.com/kovshenin/surge
Tags: cache, performance, caching
Requires at least: 5.7
Tested up to: 5.8.2
Requires PHP: 7.3
Stable tag: 1.0.1
License: GPLv3 or later
License URI: https://www.gnu.org/licenses/gpl-3.0.en.html

Surge is a very simple and fast page caching plugin for WordPress.

== Description ==

Surge generates and serves static HTML files for your WordPress site, causing quicker requests, faster load times and a shorter time to first byte (TTFB).

Surge does not require configuration, and has no options. It works out of the box on any well-configured hosting platform. Cached files are stored on disk, and automatically invalidated when your site is updated.

In various load tests, Surge has shown to easily handle 1000-2500 requests per second at 100 concurrent, on a small single-core server with only 1 GB of RAM. That's over 70 times faster than a stock WordPress install.

== Installation ==

Via the WordPress Dashboard: navigate to Plugins - Add New. In the search bar type "surge" and hit Enter. Find the Surge plugin in the search results, hit Install, then Activate.

Manually: download the Surge plugin .zip file from WordPress.org. In your WordPress admin navigate to Plugins - Add New - Upload. Select the .zip file and hit Upload. Activate the plugin after upload is successful.

Manually via FTP: download the Surge plugin .zip file from WordPress.org, extract the archive, make sure the directory is called "surge". Use your FTP/SFTP client to upload the "surge" directory to wp-content/plugins. Then activate the plugin in your WordPress admin from the Plugins section.

Using WP-CLI: wp plugin install surge --activate

== Frequently Asked Questions ==

= Where is the plugin configuration screen? =

There isn't one.

= Is my cache working? =

Visit the Site Health screen under Tools in your WordPress dashboard. Common caching errors, like installation problems, etc. will appear there. Otherwise, open your site in an Incognito window to see the cached version. You could also look for the "X-Cache" header in the server response.

= Why am I getting cache misses? =

Below are a few common reasons:

* You are logged into your WordPress site
* You have a unique cookie set in your browser
* A unique query parameter will also cause a cache miss, except common marketing parameters, such as utm_campaign, etc.
* Request methods outside of GET and HEAD are not cached

= Can I exclude page X from being cached? =

Of course. If you pass a "Cache-Control: no-cache" header (or max-age=0) the request will automatically be excluded from cache. Note that most WordPress plugins will already do this where necessary.

= fpassthru() has been disabled for security reasons =

It seems like your hosting provider disabled the fpassthru() function, likely by mistake. This is a requirement for Surge. Please get in touch with them and kindly ask them to enable it.

= How can I support Surge? =

If you like Surge, consider giving us a [star on GitHub](https://github.com/kovshenin/surge) and a review on WordPress.org.

== Changelog ==

= 1.0.1 =
* Various invalidation enhancements and fixes
* Remove advanced-cache.php when plugin is deactivated
* Add a note about fpassthru() in FAQ
* Minor fix in Site Health screen tests

= 1.0.0 =
* Anonymize requests to favicon.ico and robots.txt
* Improve cache expiration, add cache expiration by path

= 0.1.0 =
* Initial release
Comments
  • Cache-Control: max-age not honored

    Cache-Control: max-age not honored

    I'm trying to cache a WP Rest API response that calls to a 3rd party API, the 3rd party API takes few seconds to query.

    Surge caches the response by default, everything is fine, except if I want the Rest API to hit the 3rd party API again after the max-age expires.

    Looks like Surge only checks for no-cache and max-age=0, are there any plans to support variable number of max-age like header( 'Cache-Control: max-age=60' ); ?

    opened by SilverMira 6
  • (feat): allow config values to be changed with hook 'surge/config'

    (feat): allow config values to be changed with hook 'surge/config'

    The values in the config array are hardcoded. Sometimes, it could be useful to change the values.

    The hook surge/config (but name can be changed if required), allows values to be changed.

    opened by edwinsiebel 5
  • Add a way of disabling overwriting `WP_CACHE` value in wp-config.php

    Add a way of disabling overwriting `WP_CACHE` value in wp-config.php

    Upon install, whatever the value of WP_CACHE is in wp-config.php is removed it would be good to be able to disable this behaviour, useful for cases where config is configured from env vars and plugins are installed as part of a build process for example.

    I'm happy to provide a PR, but just wanted to run it by you first. Would you be happy with wrapping in a conditional with a filter?

    opened by jenkoian 3
  • Warning when looping through metadata headers

    Warning when looping through metadata headers

    Some users reported a PHP warning in foreach() in include/serve.php on line 76, which is the loop through the headers, saved in the cache metadata. It seems like in some cases, when WordPress doesn't send any headers at all, or only ones that we choose to skip:

    https://github.com/kovshenin/surge/blob/main/include/cache.php#L39

    The $headers variable is never defined as an array, and is thus saved as null in the metadata, which then causes the warning on display.

    bug 
    opened by kovshenin 3
  • Feature: A way to modify the cache configuration

    Feature: A way to modify the cache configuration

    Following up on #1 here. Unfortunately the proposed solution in that PR doesn't quite work as part of the configuration code is executed way too early for any WordPress actions or filters to be called. In this PR users are allow dot create their own configuration file, and attach it with the WP_CACHE_CONFIG constant in wp-config.php, for example:

    define( 'WP_CACHE', true );
    define( 'WP_CACHE_CONFIG', __DIR__ . '/cache-config.php' );
    

    The file itself has access to the original Surge $config but must return a valid configuration array. You can not unset any of the configuration keys, but you can extend them or override them. For example, if you wish to add your own ignored query variable, you would have the following config:

    $config['ignore_query_vars'][] = 'custom_query_var';
    return $config;
    

    You can prevent the request from being cached by setting the TTL to zero, for example:

    if ( false !== stripos( $_SERVER['HTTP_USER_AGENT'], 'googlebot' ) ) {
        $config['ttl'] = 0;
    }
    
    return $config;
    

    If you wish to cache mobile visitors in a different cache bucket, you can use the variants array, like so:

    function is_mobile() {
        // Your mobile check implementation
        return true; // or false
    }
    
    $config['variants']['mobile'] = is_mobile();
    return $config;
    

    Looking forward to your feedback @edwinsiebel!

    enhancement 
    opened by kovshenin 1
  • Publishing a new post or untrashing a post does not invalidate cache correctly

    Publishing a new post or untrashing a post does not invalidate cache correctly

    Spotted by @roytanck. Publishing a new post does not invalidate the home page cache (or other related archives) because it's not been flagged with this new post ID. Untrashing a post has the same problem for the same reasons.

    Reproduce:

    • Make sure home is set to list latest 10 posts
    • Prime the home page cache in incognito mode
    • Publish a new post
    • Check home page, the new post will be missing until the TTL runs out

    The published post permalink will still work immediately as it's invalidated correctly by post ID, but things like "latest posts" widgets, etc. will also have a hard time picking up the new post until it expires due to TTL.

    opened by kovshenin 1
  • Allow multiple headers with the same name.

    Allow multiple headers with the same name.

    In HTTP headers it is allowed to specify the same name. In particular, it can be useful to specify links for preload:

    Link: <https://example.com/other/styles.css>; rel=preload; as=style
    Link: </theme/styles.css>; rel=preload; as=style
    

    Some info about multiple headers https://stackoverflow.com/questions/3241326/set-more-than-one-http-header-with-the-same-name

    opened by doiftrue 0
  • Redirect loop on / to %2F conversion in unknown query arguments

    Redirect loop on / to %2F conversion in unknown query arguments

    Seems like there is some code in Core that converts / to %2F in unknown query arguments performing a redirect, but the redirect is cached under the same cache key as the %2F version, resulting in a redirect loop. Ideally these requests are cached under different keys.

    bug 
    opened by kovshenin 0
  • Fix locking when writing flags.json

    Fix locking when writing flags.json

    Multiple concurrent requests could be attempting to write flags.json, and the current file_put_contents() approach will blindly overwrite whatever another request may have written at the same time.

    In this PR we move the LOCK_EX lock before we're about to read the contents of the file, and release the lock right after we've written to the file. So a concurrent request will wait for the lock to be released, before attempting to read the flags.

    opened by kovshenin 0
  • get_post_type_object() can return null, causing a PHP notice

    get_post_type_object() can return null, causing a PHP notice

    This get_post_type_object() call in some cases can return null when transitioning objects of unknown types (auto-draft if I had to guess), causing a PHP notice: Trying to get property 'public' of non-object.

    Reported on the forums here.

    Should check the $obj variable prior to accessing its properties.

    bug good first issue 
    opened by kovshenin 0
  • Invalidation enhancements

    Invalidation enhancements

    In this PR:

    • Flag requests with non-singular queries for a specific post_type
    • Flag WooCommerce products to work around various caches
    • Invalidate post_type caches on transition_post_status

    This is work in progress, some of it related to #2.

    Will also need to look at nav_menu_items, because those queries run with suppress_filters by-passing our the_posts. Also a very old but still in-use function get_pages does its own thing, but has some filters we can hook into.

    cc @soulseekah

    opened by kovshenin 0
  • PHP warnings

    PHP warnings

    PHP version 7.4.30 Surge version 1.0.4

    This combination results in the following PHP warnings

    PHP Warning: Use of undefined constant DIR - assumed 'DIR' (this will throw an Error in a future version of PHP) in /var/www/doma.in/config/application.php on line 70

    PHP Warning: include(DIR/cache-config.php): failed to open stream: No such file or directory in /var/www/doma.in/content/plugins/surge/include/common.php on line 56

    We are using bedrock based structure, hence the content/plugins.

    opened by timiwahalahti 1
  • Manipulating PHP globals

    Manipulating PHP globals

    Hi!

    While playing around with Surge, I noticed the plugin makes changes to PHP globals at various places:

    • https://github.com/kovshenin/surge/blob/e68d4be79ab7fafe54799413962d9ea9a9150768/include/common.php#L143
    • https://github.com/kovshenin/surge/blob/e68d4be79ab7fafe54799413962d9ea9a9150768/include/common.php#L115-L118
    • https://github.com/kovshenin/surge/blob/e68d4be79ab7fafe54799413962d9ea9a9150768/include/common.php#L107-L108

    Is it intended?

    Since key() is called on every request, you may end up messing with third party code that relies on those globals and not only on edge cases.

    opened by nlemoine 0
  • Enable cache for logged in users

    Enable cache for logged in users

    Hey, first of all thanks for the excellent plugin, it works incredibly well out of the box!

    I have been poking through the plugin source code and I can't seem to find the logic that disables/prevents caching for logged in users.

    What I am hoping is possible is that I can create a custom config file like this Surge Configuration Example. And setup some logic to enable caching for logged in users with a certain custom role (essentially a role that only has frontend access).

    If you could point me in the direction of how Surge currently identifies logged in users I'd really appreciate it.

    opened by roryashfordbentley 1
  • Preloading pages

    Preloading pages

    I'm trying out Surge on a low-traffic site and it doesn't seem like crawling is enough to negate the need for preloading. I visited the homepage, recent posts, and main-menu items periodically over the course of an hour, and frequently got cache-misses.

    I bumped the TTL to a week as a workaround, but I'm worried that'll still result in a lot of misses. This type of site has ~300 posts, but isn't updated frequently, and is on shared hosting. So I'm more worried about slow load times on the long tail of older posts than I am about edge cases where the cache isn't invalidated fast enough.

    opened by iandunn 1
  • Can't clean `php://input`

    Can't clean `php://input`

    Hey ๐Ÿ‘‹๐Ÿป ย  I noticed this:

    https://github.com/kovshenin/surge/blob/e68d4be79ab7fafe54799413962d9ea9a9150768/include/common.php#L239

    FYI, I dug into that recently for another project, and it seems like it's not possible โ˜น๏ธ

    I'd be happy to be wrong if you found something I missed, though!

    opened by iandunn 0
Releases(1.0.4)
Owner
Konstantin Kovshenin
WordPress Core Contributor, ex-Automattician.
Konstantin Kovshenin
A Wordpress plugin that allows you to customize a news feed on your home page

=== Plugin Name === Contributors: Noora Chahine Requires at least: 4.0.1 Tested up to: 5.4 Stable tag: 5.2 License: GPLv2 or later License URI: http:/

Noora Chahine 1 Nov 15, 2021
๐Ÿ”๏ธ A WordPress plugin to automatically send a user to the page or post if it's the only search result available.

One Search Result A WordPress plugin to automatically send a user to the page or post if it's the only search result available. When there is only one

Brad Parbs 9 Oct 6, 2021
Free WordPress plugin to generate Admin Settings Page.

ClioWP Settings Page ClioWP Setting Page is a free WordPress Plugin which creates a sample Settings Page. This โ€œtestโ€ page contains almost any type of

Christos Pontikis 5 Nov 3, 2022
A WordPress plugin to suspend WordPress sites automagically. Simple and lightweight, no annoying ads and fancy settings.

Suspend WP A WordPress plugin to suspend WordPress sites automagically. Simple and lightweight, no annoying ads and fancy settings. ?? Demo (coming so

Waren Gonzaga 3 Nov 15, 2021
Simple WordPress plugin to learn how to understand WordPress Crons and the Action Scheduler library.

Simple WordPress plugin to learn how to understand WordPress Crons and the Action Scheduler library. Import Jamendo playlists with tracks in WordPress posts.

Pierre Saikali 3 Dec 7, 2022
A one-page user-profile WordPress theme

X3P0 - Profile A one-page user-profile WordPress theme. Currently, it ships with a few patterns. More will be added. Credits patterns/artist.php - Pho

X3P0 25 Nov 4, 2022
WordPress single-page theme with profile patterns.

X3P0 - Reflections A one-page user-profile WordPress theme. Really, it's just a single page. View Demo โ†’ Recommended This theme is designed to work wi

X3P0 25 Nov 4, 2022
The Pronamic WordPress Basecone plugin allows you to connect your WordPress installation to Basecone.

Pronamic WordPress Basecone The Pronamic WordPress Basecone plugin allows you to connect your WordPress installation to Basecone. Table of contents Au

Pronamic 1 Oct 19, 2021
WordPress plugin that lets you use Discourse as the community engine for a WordPress blog

WP Discourse Note: the wp-discourse plugin requires >= PHP-5.4.0. The WP Discourse plugin acts as an interface between your WordPress site and your Di

Discourse 497 Dec 10, 2022
WordPress & TypeScript. Simple starter template for WordPress projects

WordPress & TypeScript. Simple starter template for WordPress projects that want to use TypeScript in combination with @wordpress/scripts

Make it WorkPress 11 Sep 27, 2022
Beauty and simple Wordpress video player plugin. Powerfull and lite in use.

Sonic Spectre Video Player Beauty and simple Wordpress video player plugin. Powerfull and lite in use. Quick Start: Download plugin from this repo and

Halcyon 1 Jan 4, 2022
This WordPress Plugin Boilerplate is meant for you to develop your own plugin on.

WordPress Plugin Boilerplate This plugin boilerplate is meant for you to develop your own plugin on. Support & collaboration Features OOP plugin core

richardev 2 May 10, 2022
A simple platform information plugin for WordPress. Shows you environment variables, PHP settings and more.

A simple platform information plugin for WordPress. Shows you environment variables, PHP settings and more.

New To Vaux 2 Sep 7, 2022
A curated list of Awesome WordPress Theme, Plugins and Framework development Resources and WordPress Communities.

Awesome WordPress A curated list of Awesome WordPress Theme, Plugins and Framework development Resources and WordPress Communities. Inspired by bayand

Dropndot Limited 91 Dec 26, 2022
Simple Wordpress plugin that adds social share buttons

Super Fast Social Share Simple Wordpress plugin that adds social share buttons to Wordpress posts. ?? Screenshots You can either load the default css

Matthew Kiggen 2 Nov 8, 2021
Simple WordPress plugin demonstrating how one can sort posts within a taxonomy.

Simple WordPress plugin to demonstrate how to sort posts in a taxonomy. How to test Download the project and install it as a plugin in your WordPress

David Aguilera 3 Aug 16, 2022
A simple scaffold used for what's needed to spin up a Composer-based WordPress plugin.

A simple scaffold used for what's needed to spin up a Composer-based WordPress plugin.

Tom McFarlin 29 Dec 29, 2022
Divi Migration Tools - A simple plugin to assist in the conversion of Divi to WordPress.

Divi Migration Tools Different criteria to migrate the Divi shortcodes. Migrate the following Divi shortcodes to Gutenberg blocks ?? [et_pb_video] It

Automattic 4 Dec 6, 2022
Simple WordPress plugin starter framework.

WordPress Plugin Starter This is the official WordPress plugin starter framework for Highfivery. The purpose behind it is to improve the quality of th

Highfivery LLC 5 Oct 27, 2022