Proxy Client Setup

This library ships with clients for the Varnish and NGINX caching servers and the Symfony built-in HTTP cache.

A Multiplexer client that forwards calls to multiple proxy clients is available, mainly for transition scenarios of your applications. A Noop client that implements the interfaces but does nothing at all is provided for local development and testing purposes.

The recommended usage is to have your application interact with the cache invalidator which you set up with the proxy client suitable for the proxy server you use.

Supported invalidation methods

Not all clients support all invalidation methods. This table provides of methods supported by each proxy client:

Client Purge Refresh Ban Tagging
Symfony Cache    

Of course, you can also implement your own client for other needs. Have a look at the interfaces in namespace FOS\HttpCache\ProxyClient\Invalidation.


Most proxy clients use the HttpDispatcher to send requests to the proxy server. The HttpDispatcher is built on top of the HTTPlug abstraction to be independent of specific HTTP client implementations.

Basic HTTP setup with HttpDispatcher

The dispatcher needs to know the IP addresses or hostnames of your proxy servers. If your proxy servers do not run on the default port (80 for HTTP, 443 for HTTPS), you need to specify the port with the server name. Make sure to provide the direct access to the web server without any other proxies that might block invalidation requests.

The server IPs are sufficient for invalidating absolute URLs. If you want to use relative paths in invalidation requests, supply the hostname and possibly a base path to your website with the $baseUri parameter:

use FOS\HttpCache\ProxyClient\HttpDispatcher;

$servers = ['', '']; // Port 80 assumed for
$baseUri = '';
$httpDispatcher = new HttpDispatcher($servers, $baseUri);

If your web application is accessed on a port other than the default port, make sure to include that port in the base URL:

$baseUri = '';

You can additionally specify the HTTP client and URI factory that should be used. If you specify a custom HTTP client, you need to configure the client to convert HTTP error status into exceptions. This can either be done in a client specific way or with the HTTPlug PluginClient and the ErrorPlugin. If client and/or URI factory are not specified, the dispatcher uses HTTPlug discovery to find available implementations.

Learn more about available HTTP clients in the HTTPlug documentation. To customize the behavior of the HTTP client, you can use HTTPlug plugins.

Varnish Client

The Varnish client sends HTTP requests with the HttpDispatcher. Create the dispatcher as explained above and pass it to the Varnish client:

use FOS\HttpCache\ProxyClient\Varnish;

$varnish = new Varnish($httpDispatcher);


To make invalidation work, you need to configure Varnish accordingly.

You can also pass some options to the Varnish client:

  • tags_header (default: X-Cache-Tags): The HTTP header used to specify which tags to invalidate when sending invalidation requests to the caching proxy. Make sure that your Varnish configuration corresponds to the header used here;
  • header_length (default: 7500): Control the maximum header length when invalidating tags. If there are more tags to invalidate than fit into the header, the invalidation request is split into several requests;
  • default_ban_headers (default: []): Map of headers that are set on each ban request, merged with the built-in headers.

Additionally, you can specify the request factory used to build the invalidation HTTP requests. If not specified, auto discovery is used – which usually is fine.

A full example could look like this:

$options = [
    'tags_header' => 'X-Custom-Tags-Header',
    'header_length' => 4000,
    'default_ban_headers' => [
        'EXTRA-HEADER' => 'header-value',
$requestFactory = new MyRequestFactory();

$varnish = new Varnish($httpDispatcher, $options, $requestFactory);

NGINX Client

The NGINX client sends HTTP requests with the HttpDispatcher. Create the dispatcher as explained above and pass it to the NGINX client:

use FOS\HttpCache\ProxyClient\Nginx;

$nginx = new Nginx($httpDispatcher);

If you have configured NGINX to support purge requests at a separate location, call setPurgeLocation():

use FOS\HttpCache\ProxyClient\Nginx;

$nginx = new Nginx($servers, $baseUri);


To use the client, you need to configure NGINX accordingly.

Symfony Client

The Symfony client sends HTTP requests with the HttpDispatcher. Create the dispatcher as explained above and pass it to the Symfony client:

use FOS\HttpCache\ProxyClient\Symfony;

$symfony = new Symfony($httpDispatcher);


To make invalidation work, you need to use the EventDispatchingHttpCache.

Noop Client

The Noop (no operation) client implements the interfaces for invalidation, but does nothing. It is useful for developing your application or on a testing environment that does not have a proxy server set up. Rather than making the cache invalidator optional in your code, you can (based on the environment) determine whether to inject the real client or the Noop client. The rest of your application then does not need to worry about the environment.

Multiplexer Client

The MultiplexerClient allows to send invalidation requests to multiple proxy clients.

It is useful when multiple caches exist in the environment and they need to be handled at the same time; the Multiplexer proxy client will forward the cache invalidation calls to all proxy clients supporting the operation in question:

use FOS\HttpCache\ProxyClient\MultiplexerClient;
use FOS\HttpCache\ProxyClient\Nginx;
use FOS\HttpCache\ProxyClient\Symfony;

$nginxClient = new Nginx($servers);
$symfonyClient = new Symfony([...]);
// Expects an array of ProxyClient in the constructor
$client = new MultiplexerClient([$nginxClient, $symfonyClient]);

Invalidation calls on MultiplexerClient will be forwarded to all proxy clients that support the invalidation method and be ignored if none do. Calling getTagsHeaderValue and getTagsHeaderName will throw an UnsupportedProxyOperationException if none of the proxy clients support tagging (i.e., implement TagCapable).


Having multiple layers of HTTP caches in place is not a good idea in general. The MultiplexerClient is provided for special situations, for example during a transition phase of an application where an old and a new system run in parallel.


When using the multiplexer, code relying on instanceof checks on the client and also the CacheInvalidator::supports method will not work, as the MultiplexerClient implements all interfaces, but the attached clients might not. Make sure that none of the code you use relies on such checks - or write your own multiplexer that only implements the interfaces supported by the clients you use.

Using the Proxy Client

The recommended usage of the proxy client is to create an instance of CacheInvalidator with the correct client for your setup. See The Cache Invalidator for more information.

Implementation Notes

Each client is an implementation of ProxyClient. All other interfaces, PurgeCapable, RefreshCapable, BanCapable and TagCapable, extend this ProxyClient. So each client implements at least one of the three invalidation methods depending on the proxy server’s abilities. To interact with a proxy client directly, refer to the doc comments on the interfaces.

The ProxyClient has one method: flush(). After collecting invalidation requests, flush() needs to be called to actually send the requests to the proxy server. This is on purpose: this way, we can send all requests together, reducing the performance impact of sending invalidation requests.