Showing results for 
Search instead for 
Did you mean: 

Content Caching does not respond with HTTP 304 Code?


Content Caching does not respond with HTTP 304 Code?

Hello all,

I'm using Stingray v9.4, and I'm enabling content caching on my website.  I can verify that the content is being put into the content cache via the admin panel.  However, when I'm monitoring the HTTP traffic via Fiddler, I see that the Stingray always respond with a HTTP 200 "OK" code.  This means the entire request body is sent back over the wire.

However, shouldn't it send an HTTP 304 ("Not Modified") to save on bandwidth?  If I request several large .js files, I never get the 304 that I would expect, always an HTTP 200.  This causes my bandwidth usage to go up and the caching benefits are not really visible, as it takes longer to send the data over the wire than to send a body-less response of 304. 

If I turn off content caching at the load balancer, my web servers will appropriately respond with a 304.  Using Apache Benchmark, I actually get much more requests per second directly calling my web servers than using content caching from the load balancer.  I turned on webcache!verbose, and the response I get in the X-Cache-Info field says "not cacheable; response code not cacheable"

My end goals is to have much of the static files served by the load balancer, leaving dynamic requests for the web servers.

Is there a way to correct this, either with an out-of-the-box setting or with a TrafficScript rule?


Re: Content Caching does not respond with HTTP 304 Code?

Hi tpoise,

Stingray will only return a "304 not modified" if you include a "If-Modified-Since" header with your request.

mark@goldfish:~$ curl -i -H "If-Modified-Since: Mon, 18 Mar 2013 10:51:38 GMT" http://stingray1/

HTTP/1.1 304 Not Modified

Date: Tue, 05 Nov 2013 00:12:14 GMT

X-Cache-Info: cached

However if you include the header, but the item is not already in Stingrays cache, then Stingray will need to forward the request to a node in the pool. The node may then respond with a 304 of its own. As the 304 does not include the actual content body, it is not cachable.

How were you requesting the files when you saw only 200 responses? Try again and be sure to include an If-Modified-Since header. You will need to send at least one request through without the header to populate the cache first.

In any case the 304 responses aren't really desirable either. What you actually want is for the browser not to request the content at all, and that can be achieved by setting a correct "Expires" header in the response. A browser will not re-request content while the content has a proper future expiry date. The below TrafficScript sets a Cache-Control and Expires header based on the Content-Type of the response, and will stop the browser making requests for that content until after it has expired.

$ct = http.getResponseHeader("Content-Type");

if ( string.startswith($ct, "text/html") ) {

   $age = 10;

} else if ( string.startswith($ct, "text/css") ) {

   $age = 172800;

} else if ( string.startswith($ct, "text/javascript" ) {

   $age = 172800;

} else if ( string.startswith($ct, "image") ) {

   $age = 172800;

} else {

   $age = 60;


$expire = sys.time() + $age;

http.setResponseHeader("Cache-Control", "max-age=" . $age );

http.setResponseHeader("Expires", sys.gmtime.format( "%a, %d %b %Y %T GMT", $expire));

In this example: html pages are cached for 10 seconds, images, javascript and CSS are cached for two days, and all other content is cached for 60 seconds.