vADC Docs

Feature Brief: Stingray Content Caching

by on ‎02-26-2013 06:26 AM (7,833 Views)

Stingray’s Content Caching capability allows Stingray Traffic Manager to identify web page responses that are the same for each request and to remember (‘cache’) the content. The content may be ‘static’, such as a file on disk on the web server, or it may have been generated by an application running on the web server.

Why use Content Caching?

When another client asks for content that Stingray has cached in its internal web cache, Stingray can return the content directly to the client without having to forward the request to a back-end web server.

This has the effect of reducing the load on the back-end web servers, particularly if Stingray has detected that it can cache content generated by complex applications which consume resources on the web server machine.

What are the pitfalls?

A content cache may store a document that should not be cached.

Stingray conforms to the caching recommendations of RFC 2616, which describe how web browsers and server can specify cache behaviour. However, if a web server is misconfigured, and does not provide the correct cache control information, then a TrafficScript or RuleBuilder rule can be used to override Stingray's default caching logic.

A content cache may need a very large amount of memory to be effective

Depending on the spread of content for your service, and the proportion that is cacheable and frequently used compared to the long tail of less-used content, you may need a very large content cache to get the best possible hit rates.

Stingray Traffic Manager allows you to specify precisely how much memory you wish to use for your cache, and to impose fine limits on the sizes of files to be cached and the duration that they should be cached for. Stingray's 64-bit software overcomes the 2-4Gb limit of older solutions, and Stingray can operate with a two-tier (in-memory and on-SSD) cache in situations where you need a very large cache and the cost of server memory is prohibitive.

How does it work?

Not all web content can be cached. Information in the HTTP request and the HTTP response drives Stingray's decisions as to whether or not a request should be served from the web cache, and whether or not a response should be cached.


  • Only HTTP GET and HEAD requests are cacheable. All other methods are not cachable.
  • The Cache-Control header in an HTTP request can force Stingray to ignore the web cache and to contact a back-end node instead.
  • Requests that use HTTP basic-auth are uncacheable.


  • The Cache-Control header in an HTTP response can indicate that an HTTP response should never be placed in the web cache.  The header can also use the max-age value to specify how long the cached object can be cached for. This may cause a response to be cached for less than the configured webcache!time parameter.
  • HTTP responses can use the Expires header to control how long to cache the response for. Note that using the Expires header is less efficient than using the max-age value in the Cache-Control response header.
  • The Vary HTTP response header controls how variants of a resource are cached, and which variant is served from the cache in response to a new request.

If a web application wishes to prevent Stingray from caching a response, it should add a ‘Cache-Control: no-cache’ header to the response.

Debugging Stingray's Cache Behaviour

You can use the global setting webcache!verbose if you wish to debug your cache behaviour. This setting is found in the Cache Settings section of the System, Global Settings page. If you enable this setting, Stingray will add a header named ‘X-Cache-Info’ to the HTTP response to indicate how the cache policy has taken effect. You can inspect this header using Stingray's access logging, or using the developer extensions in your web browser.

X-Cache-Info values

X-Cache-Info: cached

X-Cache-Info: caching

X-Cache-Info: not cacheable; request had a content length

X-Cache-Info: not cacheable; request wasn't a GET or HEAD

X-Cache-Info: not cacheable; request specified "Cache-Control: no-store"

X-Cache-Info: not cacheable; request contained Authorization header

X-Cache-Info: not cacheable; response had too large vary data

X-Cache-Info: not cacheable; response file size too large

X-Cache-Info: not cacheable; response code not cacheable

X-Cache-Info: not cacheable; response contains "Vary: *"

X-Cache-Info: not cacheable; response specified "Cache-Control: no-store"

X-Cache-Info: not cacheable; response specified "Cache-Control: private"

X-Cache-Info: not cacheable; response specified "Cache-Control: no-cache"

X-Cache-Info: not cacheable; response specified max-age <= 0

X-Cache-Info: not cacheable; response specified "Cache-Control: no-cache=..."

X-Cache-Info: not cacheable; response has already expired

X-Cache-Info: not cacheable; response is 302 without expiry time

Overriding Stingray's default cache behaviour

Several TrafficScript and RuleBuilder cache contrl functions are available to facilitate the control of Stingray Traffic Manager’s caching behaviour. In most cases, these functions eliminate the need to manipulate headers in the HTTP requests and responses.


Invoking http.cache.disable() in a response rule prevents Stingray from caching the response. The RuleBuilder 'Make response uncacheable' action has the same effect.


Invoking http.cache.enable() in a response rule reverts the effect of a previous call to http.cache.disable(). It causes Stingray’s default caching logic to take effect. Note that it possible to force Stingray to cache a response that would normally be uncachable by rewriting the headers of that response using TrafficScript or RuleBuilder (response rewriting occurs before cachability testing).


The http.cache.setkey() function is used to differentiate between different versions of the same request, in much the same way that the Vary response header functions. It is used in request rules, but may also be used in response rules.

It is more flexible than the RFC2616 vary support, because it lets you partition requests on any calculated value – for example, different content based on whether the source address is internal or external, or whether the client’s User-Agent header indicates an IE or Gecko-based browser.

This capability is not available via RuleBuilder.

Simple control

http.cache.disable and http.cache.disable allow you to easily implement either 'default on', or 'default off' policies, where you either wish to cache everything cacheable unless you explicity disallow it, or you wish to only let Stingray cache things you explictly allow. For example, you have identified a particular set of transactions out of a large working set that each 90% of your web server usage, and you wish to just cache those requests, and not lets less painful transactions knock these out of the cache. Alternatively, you may be trying to cache a web-based application which is not HTTP compliant in that it does not properly mark up pages which are not cacheable and caching them would break the application. In this scenario, you wish to only enable caching for particular code paths which you have tested to not break the application. An example TrafficScript rule implementing a 'default off' policy might be:

# Only cache what we explicitly allow


if( string.regexmatch( http.geturl(), "^/sales/(order|view).asp" )) {

  # these are our most painful pages for the DB, and are cacheable



RuleBuilder offers only the simple 'default on' policy, overridden either by the response headers or the 'Make response uncacheable' action.

Caching multiple resource versions for the same URL

Suppose that your web service returns different versions of your home page, depending on whether the client is coming from an internal network ( or an external network. If you were to put a content cache in front of your web service, you would need to arrange that your web server sent a Cache-Control: no-cache header with each response so that the page were not cached.

Use the following request rule to manipulate the request and set a 'cache key' so that Stingray caches the two different versions of your page:

# We're only concerned about the home page...

if( http.getPath() != "/" ) break;

# Set the cache key depending on where the client is located

$client = request.getRemoteIP();

if( string.ipmaskmatch( $ip, "" ) ) {

   http.cache.setkey( "internal" );

} else {

   http.cache.setkey( "external" );


# Remove the Cache-Control response header - it's no longer needed!

http.removeResponseHeader( "Cache-Control" );

Forcing pages to be cached

You may have an application, say a JSP page, that says it is not cacheable, but actually you know under certain circumstances that it is and you want to force Stingray to cache this page because it is a heavy use of resource on the webserver.

You can force Stingray to cache such pages by rewriting its response headers; any TrafficScript rewrites happen before the content caching logic is invoked, so you can perform extremely fine-grained caching control by manipulating the HTTP response headers of pages you wish to cache.

In this example, as have a JSP page that sets a 'Cache-Control: no-cache' header, which prevents Stingray by caching the page. We can make this response cacheable by removing the Cache-Control header (and potentially the Expires header as well), for example:

if( http.getpath() == "/testpage.jsp" ) {

  # We know this request is cacheable; remove the 'Cache-Control: no-cache'

  http.removeResponseHeader( "Cache-Control" );


Granular cache timeouts

For extra control, you may wish instead to use the http.setResponseHeader() function to set a Cache-Control with a max-age= paramter to specify exactly how long this particular piece of content should be cached or; or add a Vary header to specify which parts of the input request this response depends on (e.g. user language, or cookie). You can use these methods to set cache parameters on entire sets of URLs (e.g. all *.jsp) or individual requests for maximum flexibility.

The RuleBuilder 'Set Response Cache Time' action has the same effect.

Read more