Make WordPress Core

Opened 7 years ago

Last modified 11 months ago

#39861 accepted defect (bug)

WP REST API and Caching Issue

Reported by: sckmkny's profile sckmkny Owned by: johnbillion's profile johnbillion
Milestone: Future Release Priority: normal
Severity: normal Version: 4.7.2
Component: REST API Keywords:
Focuses: Cc:


It appears that the current implementation of the WP REST API uses the following cache control header:

cache-control:no-cache, must-revalidate, max-age=0

The problem is that some providers, e.g., SiteGround, also tack on a bogus last modified header:

last-modified:Thu, 01 Jan 1970 00:00:00 GMT

This combination causes the browser to add a "if-modified-since" header to subsequent API call and resulting with a 304 response (in this case NGINX at SiteGround). At the point, you continually get stale results from the API.

The fix is to also add a "no-store" to the API response.

Cache-Control: no-cache, no-store, must-revalidate

For reference:

Change History (8)

#2 @joehoyle
7 years ago

  • Milestone Awaiting Review deleted
  • Resolution set to invalid
  • Status changed from new to closed

@sckmkny is this for an authenticated request? We don't send no-cache headers on anonymous requests, for example:

> http
HTTP/1.1 200 OK
Access-Control-Allow-Headers: Authorization, Content-Type
Access-Control-Expose-Headers: X-WP-Total, X-WP-TotalPages
Allow: GET
Cache-Control: max-age=300, must-revalidate
Connection: keep-alive
Content-Encoding: gzip
Content-Type: application/json; charset=UTF-8
Date: Sun, 26 Mar 2017 01:56:55 GMT
Last-Modified: Sun, 26 Mar 2017 01:56:55 GMT
Link: <>; rel="next"
Server: nginx/1.4.6 (Ubuntu)

As for siteground returning the bogus last-modified, I don't know why they would be doing that but I think that might be an issue on their end.

cache-control:no-cache, must-revalidate, max-age=0 should absolutely not cause a last modified to be that, so it might be better to reach out to their support. We already send a last modified of the current date.

Going to close out, but re-open if it seems I missed something!

#3 @TimothyBlynJacobs
4 years ago

#51831 was marked as a duplicate.

#4 @mguenter
4 years ago

  • Resolution invalid deleted
  • Status changed from closed to reopened

Hey @joehoyle and @lukecavanagh,

I just came across this ticket because I have a similar issue. We have implemented a dashboard in a WordPress submenu page. Imagine the following scenario:

  1. Open the dashboard
  2. JavaScript is fetching data via GET from a WP REST API endpoint
  3. Click on another submenu, e.g. media library
  4. Use the back button from the browser

Check the network log and you will see, that the WP REST API request got cached (200 OK (from disk cache))

Tested on Chrome, but I think this happens on all browsers.

How can this be fixed? Using the following header disallows the browsers to cache the response:

Cache-Control: no-cache, no-store, must-revalidate, max-age=0

Add no-store directive, see also and

The solution? Add the no-store cache directive. It tells the browser to really not store anything at > all. So this works, and clicking the back button in Chrome will never serve up cached content: [...]

If you fix this, you need to be careful, because the directive should probably only be added on WP REST API calls.

#5 @SergeyBiryukov
2 years ago

  • Milestone set to Awaiting Review

#6 @johnbillion
15 months ago

  • Milestone changed from Awaiting Review to 6.3
  • Owner set to johnbillion
  • Status changed from reopened to accepted

Let's see if we can tackle this along with #21938 and #57627

This ticket was mentioned in Slack in #core by oglekler. View the logs.

12 months ago

#8 @johnbillion
11 months ago

  • Milestone changed from 6.3 to Future Release

I didn't have a chance to work on this for 6.3.

Note: See TracTickets for help on using tickets.