ryan

ProcessWire Pro Cache - Now Available

Recommended Posts

procache_1024x1024.jpg

ProcessWire is fast. With ProCache, ProcessWire is insanely fast! ProCache provides the ultimate performance for your website by completely bypassing PHP and MySQL and enabling your web server to deliver pages of your ProcessWire site as if they were static HTML files. 

The performance benefits are major and visible. Using ApacheBench with the homepage of the Skyscrapers site profile, we completed 500 requests (10 concurrent) to the homepage. The amount of time occupied to complete each of these was as follows:

  • 29 seconds: no cache enabled
  • 6 seconds: built-in cache enabled
  • 0.017 seconds: ProCache enabled

As you can see, the performance benefits are substantial. ProCache gives you the ability to drastically reduce server resources and exponentially increase the amount of traffic your server can handle. This is especially useful for traffic spikes.

Beyond measurements, ProCache makes your website feel faster to users, respond faster to search spiders (which can help with SEO), and helps to conserve server resources for requests that actually need PHP and MySQL. 

ProcessWire is already very fast, and not everybody necessarily needs what ProCache delivers. But regardless of whether you need it or not, there is little doubt that you can benefit greatly from ProCache.

For an example of ProCache in action, visit processwire.com or the skyscrapers site. Look in the lower right corner of the page (in the footer). If it says "ProCache", it means the page was delivered via ProCache. We did this for demonstration purposes (ProCache does not put anything in your markup unless you tell it to).

More information about ProCache can be found on the ProCache documentation page

Please note

There is a known issue when using ProCache with the LanguageLocalizedURL module. I hope to have this figured out soon, but for the moment you should not use ProCache in combination with that module as it doesn't appear to work in full.

ProCache does not yet support multi-host capability (i.e. cache and delivery of different content per hostname), but it will very soon. 

How to get it

Like with Form Builder, ProCache was produced as a commercial module to support development of ProcessWire. It is now available for purchase here

ProCache is in a beta test period. As a result, it's being offered with introductory pricing that may increase once we're out of that period. During the beta test period, I just ask that you let me know if you run into any bugs or issues during your use of ProCache. I also recommend that you follow the usual best practices with regard to backing up your site and testing everything before assuming it's all working. Beyond the introductory pricing, you may also use coupon code PWPC-BETA for 10% off the listed prices at checkout. This code will expire as soon as we're out of beta. 

When you get ProCache, you'll also get 1-year of access to the ProCache-members support and upgrades board, available here in the ProcessWire forums. Upgrades to ProCache will also be posted there for download. 

Disclaimer: At the date/time that I'm writing this, I think that I am currently the only one using ProCache in production use. That's why I'm providing it with the lower costs and coupon. If you are running production sites where everything must always work perfectly, you will either want to: 1) wait to install on important sites till it's out of beta; or 2) test thoroughly on a staging server or localhost before taking it to production use. In either case, always make sure you have good backups anywhere you install new modules, and always test to double check everything works how you want it to. 

Below are a few screenshots that show the configuration screens of ProCache. 

Have questions about ProCache? Please reply to this topic. Thanks for your interest in ProcessWire ProCache!

post-2-0-11930700-1359562192_thumb.png

post-2-0-58533400-1359562198_thumb.png

post-2-0-11326500-1359562208_thumb.png

post-2-0-24117700-1359562216_thumb.png

post-2-0-14699800-1359562224_thumb.png

post-2-0-99619700-1359562230_thumb.png

  • Like 25

Share this post


Link to post
Share on other sites

Is multi-language support a possibility with this?

I suppose more specifically "domain/subdomain" based language support, or maybe an easy way to bypass procache for all but the default language...? Hmmmn.

Wait... I can use a cookie.... duh. Thanks self! (Though I'd love to hear about a better method)

Share this post


Link to post
Share on other sites

So long as you are aren't serving different languages from the same exact URL, it should be totally compatible. If you are serving different languages at the same URL, then you've got to be concerned about search engines and such. But if that's not an issue, then you are right that you could accomplish it by setting a cookie and telling ProCache which cookie should bypass the cache. 

Share this post


Link to post
Share on other sites
So long as you are aren't serving different languages from the same exact URL, it should be totally compatible. If you are serving different languages at the same URL, then you've got to be concerned about search engines and such. But if that's not an issue, then you are right that you could accomplish it by setting a cookie and telling ProCache which cookie should bypass the cache. 

When you say totally compatible, are you saying I shouldn't need to use a cookie, or that the cookie itself will work?

Share this post


Link to post
Share on other sites

This looks impressive, Ryan, thank you very much for your hard work! I have to agree with the rest, the kind of performance we'll be able to achieve with this module installed is just amazing! ProcessWire just keeps getting better and better! :wub: 

  • Like 1

Share this post


Link to post
Share on other sites

Hi Marty...

Noob question: How does one load test a site?

You can use tools like ApacheBench to do this (installation instructions here. Steps 1 & 2 are all you need). Warning; if you point this at a live production server and fire off a lot of requests at it you are effectively operating a denial of service against that site for as long as the test is running, so you'd want to keep the number of requests pretty low to limit how long the site is affected ... say a hundred requests to start with...

ab -n 100 -c 10 -r http://site.to.test/

If you are testing on localhost or a non-production server, feel free to wind the requests right up (that's the number after the '-n'.)

There are other tools that can be used for profiling and some are listed in the answer to this server fault question.

  • Like 1

Share this post


Link to post
Share on other sites

@adamspruijt: ProCache caches URLs, and doesn't care so much what page they ultimately map to. So it works with regular pages, URL segments, page numbers, etc. It will also bypass the cache if any GET vars are present, unless you configure it otherwise. So long as the same URL like domain.com/path/to/page/ is always served in the same language, then you are good. But if you are serving different languages at the same URL, then a cookie or GET var would be the only way to bypass the cache. 

  • Like 1

Share this post


Link to post
Share on other sites

Looks really great, Ryan. I'm new to caching with ProcessWire--is the mechanism pretty much the same as normal where users are concerned? For example, I had a client using a heavily-cached CMS site where they had to clear the cache manually using a menu every time they updated a field on the site.

Share this post


Link to post
Share on other sites

Hello again Marty,

Check out the fourth image in the opening post for some clues regarding cache invalidation when pages are saved. I would imagine that you might need to do some manual cache invalidation if you edited template files but you'll have to wait for a reply from Ryan for that. I'd imagine it shouldn't be too hard to add a module that simply watched for changes to template files and invalidated the ProCache cache if it found any that had changed.

Share this post


Link to post
Share on other sites

First impression looks great. 

ProCache does not yet support multi-host capability (i.e. cache and delivery of different content per hostname), but it will very soon. 

Can you explain this a little more in detail. I'm on a shared Plesk Hosting Enviroment.

Share this post


Link to post
Share on other sites
Looks really great, Ryan. I'm new to caching with ProcessWire--is the mechanism pretty much the same as normal where users are concerned? For example, I had a client using a heavily-cached CMS site where they had to clear the cache manually using a menu every time they updated a field on the site.

You can configure the behavior of when the cache is cleared. But when you save a page, the cache is always cleared for that page, regardless of any other behaviors you've set. The other built-in options are to clear all children (and everything below), clear all parents (except homepage), clear homepage, or clear site. 

Another thing is that even a short 5-10 minute cache is hugely beneficial. That means that your page will only be rendered a max of once per 5-10 minutes, even if it gets hit thousands of times in that period. And the shorter the cache time, the less chance someone will ever see stale data. While I think we all have a tendency to make the cache time as high as possible (like an hour, a day, or a week), the right balance is often a much shorter time period. This would especially be the case if your site involved lots of page-to-page relations that fall outside of the tree relationship. 

ProCache does not yet support multi-host capability (i.e. cache and delivery of different content per hostname), but it will very soon. 

Can you explain this a little more in detail. I'm on a shared Plesk Hosting Enviroment.

This is not related to the hosting environment. Instead, it means that if you have code in your template files that is performing actions based on the hostname, then ProCache doesn't yet recognize that. For instance, if you are doing anything that checks $config->httpHost in your template file, you wouldn't want to cache that page with ProCache (or the built-in page cache, for that matter). This is an example of a template file you wouldn't want to cache: 

if($config->httpHost == 'de.domain.com') {
  $user->language = $languages->get('de'); 
} else {
  // www.domain.com
  // keep default language
}

However, I will be upgrading ProCache so that it saves the hostname with its cache files so that such a template file could still be cached. 

  • Like 4

Share this post


Link to post
Share on other sites

This looks fantastic Ryan. I will be making a purchase for sure.

ProcessWire already seems incredibly scalable and ProCache looks to be the icing on the cake.

  • Like 1

Share this post


Link to post
Share on other sites

Thanks guys. I've just changed the release status to "stable", as there haven't been any real bugs to turn up, and I'm now using it on several production sites. 

If anyone is interested in seeing more details about the Apache bench test results I did, here they are. This is to the skyscrapers homepage, testing on localhost using the command "ab -n500 -c10 localhost:8888/skyscrapers/demo/". For all tests, I performed a manual pageview to the homepage before running, just to ensure the relevant cache was already active. The server is MAMP running Apache with PHP 5.4.4 on a Mac Pro (early 2008). ProcessWire is version 2.2.13. 

No caching enabled:

Concurrency Level:      10
Time taken for tests:   29.066 seconds
Complete requests:      500
Failed requests:        0
Write errors:           0
Total transferred:      11567500 bytes
HTML transferred:       11361500 bytes
Requests per second:    17.20 [#/sec] (mean)
Time per request:       581.310 [ms] (mean)
Time per request:       58.131 [ms] (mean, across all concurrent requests)
Transfer rate:          388.65 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.7      0       8
Processing:   463  578  59.5    567     810
Waiting:      455  569  59.4    558     792
Total:        463  579  59.5    568     810

Percentage of the requests served within a certain time (ms)
  50%    568
  66%    591
  75%    610
  80%    622
  90%    661
  95%    693
  98%    738
  99%    760
 100%    810 (longest request)

Built-in Page cache enabled:

Concurrency Level:      10
Time taken for tests:   6.809 seconds
Complete requests:      500
Failed requests:        0
Write errors:           0
Total transferred:      11576500 bytes
HTML transferred:       11370500 bytes
Requests per second:    73.43 [#/sec] (mean)
Time per request:       136.178 [ms] (mean)
Time per request:       13.618 [ms] (mean, across all concurrent requests)
Transfer rate:          1660.35 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.3      0       4
Processing:    93  135  17.6    132     249
Waiting:       90  130  15.7    127     236
Total:         93  135  17.7    132     249

Percentage of the requests served within a certain time (ms)
  50%    132
  66%    137
  75%    141
  80%    144
  90%    154
  95%    166
  98%    187
  99%    211
 100%    249 (longest request)

ProCache Enabled:

Concurrency Level:      10
Time taken for tests:   0.117 seconds
Complete requests:      500
Failed requests:        0
Write errors:           0
Total transferred:      11529500 bytes
HTML transferred:       11370500 bytes
Requests per second:    4260.61 [#/sec] (mean)
Time per request:       2.347 [ms] (mean)
Time per request:       0.235 [ms] (mean, across all concurrent requests)
Transfer rate:          95942.85 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.2      0       1
Processing:     1    2   0.5      2       4
Waiting:        1    2   0.5      2       4
Total:          1    2   0.6      2       5

Percentage of the requests served within a certain time (ms)
  50%      2
  66%      2
  75%      3
  80%      3
  90%      3
  95%      3
  98%      4
  99%      4
 100%      5 (longest request)

ProCache Documentation and Order/Download page. 

  • Like 6

Share this post


Link to post
Share on other sites
Very impressed. Although PW has never felt slow or close to it this Module makes pages noticeably 'pop', even on a local test env'.

A great strategy also for the robust commercial support of ProcessWire; the forms Module is excellent (bought) but of course not all sites need forms; but almost any serious site would consider this Module—Developer licence bought!

One question Ryan/clever peeps, does the cron task noted in ProCache Maintenance not only clear out stale pages but also crawl the site so each page is cached ensuring the first page impression of any page by a visitor will be from cache, rather than the second and all subsequent visits? If not, could this safely be added as part of the cron?
  • Like 1

Share this post


Link to post
Share on other sites

Thanks Alan! Glad you are liking ProCache. I'm adding you to the ProCache board as soon as I finish writing this message. 

One question Ryan/clever peeps, does the cron task noted in ProCache Maintenance not only clear out stale pages but also crawl the site so each page is cached ensuring the first page impression of any page by a visitor will be from cache, rather than the second and all subsequent visits? If not, could this safely be added as part of the cron?

It is feasible to add it, and it sounds good, but there are some problems with doing this. It moves the render from one request to another. If a lot of pages were expired in the same request, it could even become quite a bottleneck on the server. The way it's setup now, the cache generation piggybacks on a page that's already being rendered, so it's very efficient and ProCache activities aren't ever going to consume all the server resources.

Consider this scenario: a maintenance run expires 1000 cache files (a potentially common scenario on a large site)… if we have to regenerate them all right there (as opposed to when the page is next viewed) we will temporarily take over a lot of server resources… perhaps interrupting traffic to the site. Whereas, if we cache them on-demand (which is what it currently does), usage of those resources is spread out over a period of time, and generally focused on caching the most-important pages first. Even if we use cron to re-cache them incrementally, the use of resources would still be disconnected from the demand for them (i.e. caching pages that may not be needed in the short term while missing pages that are). 

But I understand where you are coming from. If you've got a page doing a lot of heavy lifting (perhaps taking several seconds to render) then you don't want any user to ever experience that. So I will put more thought into how such a situation could be handled. For now, if you want to limit the chances of users getting a non-cached page, the best strategy is to increase your expiration times and limit what gets cleared on page saves.

  • Like 2

Share this post


Link to post
Share on other sites

Thanks Ryan for the explanation and that you'll look at this (although as I suspected and as you note, this is perhaps an edge-case/not an important matter).

I wonder if perhaps the solution is not to attempt to have logic do this and/or mess with the clean processes tackled by the Module but instead to use a third-party service (this assumes there is something that needs to be done which as I noted I am not sure there is as the default operation is likely perfect in the real world).

But for the sake of argument if I was fixated on ensuring pages were in the cache perhaps the use of a service that could ping pages a service like deadmanssnitch.com would be a better solution. For example having it hourly hit the key pages of a site such as home, contact, faq.

I've not used that service and it might be wholly inappropriate for this purpose, but it just came to mind as one possible option.

Edit: I think I was mistaken using the link above there, different sort of service I think.

Edited by alanfluff

Share this post


Link to post
Share on other sites

Rather than an external service, it could probably be accomplished most easily with just a local cron job that does something like this:

curl --data "procache=force-save" http://domain.com/path/to/page/ > /dev/null

The "procache=force-save" would be some user defined variable that we update ProCache to look for and then force saving the cache when present. You'd need to do this for every page you wanted to ensure was always cached, so maybe not that practical. But might be if you just need the homepage or a small set of pages to never display non-cached versions.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


  • Recently Browsing   0 members

    No registered users viewing this page.