Make WordPress Core

Opened 5 years ago

Last modified 3 months ago

#25072 new defect (bug)

Send no-cache response header from wp-cron.php requests

Reported by: westonruter Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 2.1
Component: Cron API Keywords: has-patch dev-feedback needs-refresh
Focuses: Cc:


In high-scale WordPress installs, it is common to enable DISABLE_WP_CRON and then have a system cron ping wp-cron.php?doing_wp_cron every minute. When working on a site with DISABLE_WP_CRON, we recently ran into a situation where future-published posts were consistently missing their schedule for several minutes. It turns out that the network architecture routed requests through Pound and then Varnish before hitting the web server, including requests originating on the server itself.

Because of the default proxy cache configuration, the requests to wp-cron.php were getting served from the cache without hitting WordPress, so the scheduled tasks were not getting executed. A workaround was put in place to add a timestamp cache-buster (i.e. wp-cron.php?doing_wp_cron&1283712312), and then we worked out a more elegant solution with a mu-plugin which did nocache_headers() if DOING_CRON. It seems the best solution is to just always send no-cache headers from wp-cron.php itself, as I can't imagine a situation where responses should be cached (except maybe with a max-age=60).

In addition to the default no-cache headers that WordPress sends, we also included a Surrogate-Control: no-cache header for caching proxies to specifically target.

So to summarize: I propose that wp-cron.php send no-cache response headers.

Attachments (2)

wp-cron.php.diff (788 bytes) - added by westonruter 5 years ago.
Patch to wp-cron.php to do nocache_headers()
no-cache-wp-cron.php (552 bytes) - added by westonruter 5 years ago.
mu-plugin to send no-cache response headers from wp-cron.php

Download all attachments as: .zip

Change History (12)

5 years ago

Patch to wp-cron.php to do nocache_headers()

#1 @westonruter
5 years ago

Come to think of it, the DISABLE_WP_CRON may be inconsequential here: the normal asynchronous wp-cron.php loopback requests would also likely be subject to the proxy caching.

5 years ago

mu-plugin to send no-cache response headers from wp-cron.php

#2 @westonruter
5 years ago

  • Cc weston@… added

#3 @c3mdigital
5 years ago

  • Severity changed from minor to normal
  • Version changed from trunk to 2.1

#4 @tollmanz
5 years ago

  • Cc tollmanz@… added

#5 @mordauk
4 years ago

I don't know of any reason this would cause issues. Seems like a good idea to me.

#6 follow-up: @nacin
4 years ago

What if you just used a POST request instead?

#7 @chriscct7
3 years ago

  • Keywords dev-feedback added

#8 in reply to: ↑ 6 @westonruter
3 years ago

Replying to nacin:

What if you just used a POST request instead?

Note we can't just send an arbitrary POST request: it would have to explicitly be a POST request without any post data because wp-cron.php short-circuits if $_POST is not empty:

if ( !empty($_POST) || defined('DOING_AJAX') || defined('DOING_CRON') )

#9 @jrf
3 years ago

@westonruter's suggestion & patch make sense to me. What needs to be done to move this forward ?

#10 @peterwilsoncc
3 months ago

  • Keywords needs-refresh added

This seems sensible to me, the patch requires a refresh:

  • Reference to DISABLE_WP_CRON can eb removed
  • The comment needs to be converted to a docblock.
Note: See TracTickets for help on using tickets.