Home  »  Htaccess  »  Speed Tips: Remove Last-Modified Header

by 18 comments

If you remove the Last-ModifiedandETag header, you will totally eliminate If-Modified-Since and If-None-Match requests and their 304 Not Modified Responses, so a file will stay cached without checking for updates until the Expires header indicates new content is available!

Remove Last-Modified Header

Please don't turn off ETags and Last-Modified headers for your .html files, leave one of them ON. (I use Last-Modified for .html).

This goes in your root .htaccess file but if you have access to httpd.conf that is better.

This code uses the FilesMatch directive and the Header directive to remove all Last-Modified Headers from being sent.

Header unset Last-Modified

How it Works

By removing both the ETag header and the Last-Modified headers from your static files (images, javascript, css) browsers and caches will not be able to validate the cached version of the file vs. the real version. By also including a Cache-Control header and Expires header, you can specify that certain files be cached for a certain period of time, and you magically (this is a really unique trick I promise) eliminate any validation requests!!


September 10th, 2007

Comments Welcome

  • Robot Terror

    Yes, this will speed individual requests, but for those sites with actual traffic they may crawl to a halt due to re-requested content from frequent visitors (think RSS feeds) and spiderbots (Google, etc.). It's a trade-off that massive scalable systems must consider: slow each request a little to be able to serve all requests reasonably fast.

  • Spencer

    This is what I currently have in my .htaccess file at the root. Do you see any problems with what I have here? Would you organize it differently? I don't know much about .htaccess files, but would love to see if this is ok for my server. Here it is below...

    FileETag None
    Header unset ETag
    Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
    Header set Pragma "no-cache"
    Header set Expires "Wed, 11 Jan 1984 05:00:00 GMT"
    Header unset ETag
    FileETag None
    SetOutputFilter DEFLATE
    Header set Expires "Thu, 15 Apr 2010 20:00:00 GMT"
    Header unset Last-Modified

    Thanks for your help!

  • Robot Terror

    This is what I currently have in my .htaccess file at the root. Do you see any problems with what I have here?

    First off, once your rules are correct be sure to move the rules out of .htaccess and into the httpd.conf file for the Directory section of your DocumentRoot. Why? .htaccess is inherently slow as it must be read for each and every request that starts in or goes deeper than the directory in which it resides (and for which AllowOverride is enabled).

    See the Apache documentation for .htaccess files for more information

  • Matt

    I love this tip. I've done a lot of optimization research and actually nobody ever suggested to remove the Last-Modified header and it's interesting to know that the browser will not pass in those "If-" requests which is once again less bytes that have to travel across the web.

    My only question is why are you suggesting NOT to remove the Last-Modified header for .html files?

  • sunnybear

    Information isn't valid. Existence of Last-Modified / ETag doesn't influence rate of cache integtiry checks in browsers

  • uggs

    Thanks. RTT time is a big part of little page loading time. i never thought about remove these two headers, but it really works, at least one round request and response saved.

  • richard

    Having some issues with pagespeed (aka google's analysis tool). It's saying I need to specify a last-modified header, but the htaccess file has the following:

    ErrorDocument 401
    ErrorDocument 404
    ErrorDocument 500
    RewriteEngine On
    RewriteCond %{HTTP_HOST} ^ [nc]
    RewriteRule (.*)$1 [R=301,L]
    ExpiresActive On
    ExpiresByType image/ico A29030400
    ExpiresByType image/gif A2592000
    ExpiresByType image/png A2592000
    ExpiresByType image/jpg A2592000
    ExpiresByType image/jpeg A2592000
    ExpiresByType text/javascript A2592000
    ExpiresByType text/css A2592000
    ExpiresByType text/swf A29030400
    ExpiresByType text/js A29030400
    Header add X-Enabled mod_gzip
    Header add X-Enabled mod_deflate
    Header set Cache-Control "private"
    Header set Expires "Thu, 27 Jul 2011 10:00:00 GMT"
    FileETag none
    Header unset Last-Modified

    Is the file correct - are there clashes/ etc. Current pagespeed score is 91% and yslow gives it a Grade A. Before I move on to learning about CDN's, I need to make sure I'm on the right track with htaccess files!

  • Pattanaik

    Damn.... I am still undecided what to do with the last modified date and ETags.
    I have a project in hand that needs me to set last modified date and Etags. Its an average site that is a reseller webhosting company. So there would be quite a bit of return traffic. What do you suggest in this case? keep it or remove it? I am seriously not able to decide....HELP!!!!

  • Klaubert

    I found this tip valuable until today... when I realize that it is not complete.

    Removing the ETag header is ok (each server generate a different ETag, in a cluster/farm this will be a problem, not a solution). But by removing the last-modified header you will make the browser use the "Expires" only, when the content Expires on browser cache it (the browser) will fetch a new content, regardless if is modified or not. If you use Expires and last-modified together, the browser (firefox on my test, YMMV) use the Expires, and after that it start to use last-modified getting the 304 (not modified) as a benefit. This way you get a two layer of cache: 1- absolutely local, 2- Browser e Server if-modified-since/not-modified handshake;


  • David Merrilees

    Does this work? I've removed both the Etag and Last-Modified headers, and added an expires header, but it always revalidates with 200 response. Can someone who's got this working post a URL please?


  • Francesco

    David this is not true anymore!

    new browsere ( ie8 , firefox, chrome) ask again the resource if they do not know when was last modified!

    so this article should be changed since make damages

  • CandleForex


    While this is an old post, it is still very useful. I have a question if you dont mind:

    Is there a way to Combine external JavaScript using htaccess?

    If there is how is it done?

  • Marco Demaio

    I agree with David Merrilees's comment below.

    Removing the Last-Modified header seems totally useless. I tested on Firefox with "FireBug > Net" (Firefox versions 3.6 and 11.0)

    If you close the browsers and re-open it, and then you navigate to the page you previously viewed, you will see browser hitting the server with an HTTP request for each resource (images, etc.).

    After the HTTP request, the server replies with 200 OK and the browser decides to take the image from cache instead of downloading it from server, but the browser has still inquired the server for each image with an HTTP request, so it's NOT true when in this article they say: "...this is a really unique trick I promise) eliminate any validation requests!!"

    FYI: this issue was discussed also on stackoverflow: because the same problem arises even when using Cache-Control: max-age=31536000 header.

  • Dave Artz

    This post as it stands is an anti-pattern, yet ranks very high in Google. Please delete this post, as it is a danger to the Internet.

    There is no benefit to removing Last-Modified. As Klaubert rightly points out, doing so will eliminate the chance of a 304 on revalidation, forcing the server to resend the full payload.

    Last-Modified should always be used in conjunction with Expires. For objects that do can not support a Last Modified header, e.g. dynamic .php, .jsonp requests, use Etags.

  • Mike Winter

    Unfortunately, it's rather clear from the synopsis of this article that the author doesn't understand caching properly, nor the actual implications of disabling cache validators (that is, ETag and Last-Modified).

    As with other commentators, I strongly suggest that this article should at least be ignored, but better would be for the author to remove or rewrite it. For better information, search for Mark Nottingham's caching tutorial.

  • frank

    never unset the last-modified header as firefox and IE will ALWAYS fetch the documents/assets from the server as the returned header is 200. Only Chrome will assume a 304 if an expires Tag is set. as Dave mentioned, you outtake the whole browser cache mechanism.

  • Gadar Soe

    As many have pointed out, removing Last-Modified header is totally wrong. Please remove this post.

  • Robot Terror music is a good way to lose traffic. Is this a MySpace page?

Related Articles

My Online Tools
Popular Articles

Hacking and Hackers

The use of "hacker" to mean "security breaker" is a confusion on the part of the mass media. We hackers refuse to recognize that meaning, and continue using the word to mean someone who loves to program, someone who enjoys playful cleverness, or the combination of the two. See my article, On Hacking.
-- Richard M. Stallman


It's very simple - you read the protocol and write the code. -Bill Joy

Except where otherwise noted, content on this site is licensed under a Creative Commons Attribution 3.0 License, just credit with a link.
This site is not supported or endorsed by The Apache Software Foundation (ASF). All software and documentation produced by The ASF is licensed. "Apache" is a trademark of The ASF. NCSA HTTPd.
UNIX ® is a registered Trademark of The Open Group. POSIX ® is a registered Trademark of The IEEE.

+Askapache | askapache

Site Map | Contact Webmaster | License and Disclaimer | Terms of Service

↑ TOPMain