I'm researching caching layers for my application stack and seriously considering Varnish. Varnish sounds great, but most of my data is not only dynamic, it also requires authentication to access, and is unique to individual users.

Based on what I've read so far, it seems like there are two options:

  1. When receiving a POST request at the application, I could attach a custom header to the response to Varnish from the origin server, use VCL to parse it, manually expire the existing cache specified by the custom header (usually a GET response to the same resource, in my case), and then strip the header from the response in Varnish before returning it to the user. I'm pretty sure this is possible.

  2. Configure/script VCL to do everything, so when a POST request comes in and a response is returned with status 200, the GET response cache on the corresponding resource is expired. I'm not sure if this is possible.

Basically, I'm wondering:

  1. Is it possible to use VCL to directly force a cached response to expire in the event of a request to a different resource? If so snippets would be much appreciated!

  2. Is there a better way to do this? I don't think I'll have any trouble setting up Varnish to handle caching unique responses, I'll just append the API token to the name of the cache file. What I really need to make this work is a way to let my application force an expiration at Varnish when a user takes an action (POST) that updates a GET.

1 Answer 1


Normally what you return in POST request is different to output from GET request. The default Varnish behaviour is that POST requests are not cached. However, to answer your questions:

  1. It is possible. You will use bans for that: ban("obj.http.x-url ~ " + req.url); (example of a ban lurker friendly ban)

  2. Since you're able to control your application's code the best way is to setup purge handler in Varnish, then make your application issue request to that (via curl). In fact, your purge handler might use bans as above, or it might use return(purge). Bans are normally used to invalidate cache for multiple objects at once, whereas purge invalidates single page.

So once your app sees a POST request, it will (provided you code necessary logic) issue PURGE request to Varnish with the URL of the resource that need to be invalidated (doesn't have to be the same URL).

  • Thanks for your reply. In my situation, I use a GET request on a resource to return an array of objects, while a POST request to the same resource must include data and will result in the creation of a new (sub) resource. That resource will then be available as a child of the current URI. I need to use POST instead of PUT because I don't know the ID of the child until it's been committed to the data store. During the processing of the POST request I will also send the PURGE as recommended to expire the cache for the GET version, since it has now changed. So thanks, your answer helped a ton!
    – ineedhelp
    Feb 17, 2017 at 20:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.