Speed up your site by compressing and caching your content with .htaccess

Please read Improving web site performance with Apache .htaccess for an updated version of this article.

.htaccess – gzip and cache your site for faster loading and bandwidth saving is one of the most popular posts on samaxes.
It’s basically on how to compress and cache your site content with Apache and .htaccess file.

It works like a charm, but it’s not yet the perfect configuration for me.
I wanted something that I can use out-of-the-box without having to rely on external extension modules or tools.

If you are lucky enough to have Apache 2 with your hosting provider you can use the mod_deflate module that comes bundled with it.

In order to compress your text files with this Apache’s module you just have to add the following lines to your .htaccess file:

<ifModule mod_deflate.c>
  <filesMatch ".(css|js|x?html?|php)$">
    SetOutputFilter DEFLATE

This will gzip all your .css, .js, .html, .html, .xhtml, and .php files.

A great .htaccess file example that will gzip your text files and cache all your static files, may look like:

# BEGIN Compress text files
<ifModule mod_deflate.c>
  <filesMatch ".(css|js|x?html?|php)$">
    SetOutputFilter DEFLATE
# END Compress text files

# BEGIN Expire headers
<ifModule mod_expires.c>
  ExpiresActive On
  ExpiresDefault "access plus 1 seconds"
  ExpiresByType image/x-icon "access plus 2592000 seconds"
  ExpiresByType image/jpeg "access plus 2592000 seconds"
  ExpiresByType image/png "access plus 2592000 seconds"
  ExpiresByType image/gif "access plus 2592000 seconds"
  ExpiresByType application/x-shockwave-flash "access plus 2592000 seconds"
  ExpiresByType text/css "access plus 604800 seconds"
  ExpiresByType text/javascript "access plus 216000 seconds"
  ExpiresByType application/javascript "access plus 216000 seconds"
  ExpiresByType application/x-javascript "access plus 216000 seconds"
  ExpiresByType text/html "access plus 600 seconds"
  ExpiresByType application/xhtml+xml "access plus 600 seconds"
# END Expire headers

# BEGIN Cache-Control Headers
<ifModule mod_headers.c>
  <filesMatch ".(ico|jpe?g|png|gif|swf)$">
    Header set Cache-Control "max-age=2592000, public"
  <filesMatch ".(css)$">
    Header set Cache-Control "max-age=604800, public"
  <filesMatch ".(js)$">
    Header set Cache-Control "max-age=216000, private"
  <filesMatch ".(x?html?|php)$">
    Header set Cache-Control "max-age=600, private, must-revalidate"
# END Cache-Control Headers

# BEGIN Turn ETags Off
<ifModule mod_headers.c>
  Header unset ETag
FileETag None
# END Turn ETags Off

# BEGIN Remove Last-Modified Header
<ifModule mod_headers.c>
  Header unset Last-Modified
# END Remove Last-Modified Header

This will surely improve your site performance by one order of magnitude. Try it!

Published by

Samuel Santos

Java developer, Open Source hacker, Web technologist, JUG Leader.

  • Pingback: More on compressing and caching your site with .htaccess | PHP-Blog.com()

  • http://www.askapache.com/ AskApache

    Excellent! Very nice FilesMatch regex, great cache-time rules, nice IfModule usage…. this is just great Samuel!

  • http://www.samaxes.com/ Samuel Santos

    Thanks for your support!

  • methode

    This is an excellent tip for your users, honest.
    It can speed up a WordPress installation by 50% without any caching plugin.

    Excellent post

  • Hamachi

    Using your 5-row mod_deflate snippet to pack my files, but unfortunately php files aren’t packed.

    What could the problem be?

  • http://www.samaxes.com/ Samuel Santos

    Does your Apache server have mod_deflate enabled?
    Are your PHP files using .php extension?

  • Hamachi

    Apache is v2. JS, CSS and HTML files are compressed (only compressing PHP doesn’t work), so I guess it’s enabled.

    PHP files have .php extensions.

  • http://www.samaxes.com/ Samuel Santos

    I can’t see any reason for it to not work.
    Try asking you hosting provider for support.

  • Pingback: » WordPress Speed and Performance » Prodyut Bora()

  • Jack

    Samuel -THANK YOU. I am pursuing an entirely different strategy for speeding services and this seems to fit quite nicely within that paradigm without sacrificing dynamic content.

  • http://www.usefulstrategy.com Angelina

    Thank you for your wonderful article. I implemented this in my site and the downloading speed has increased greatly. YSlow grade has improved from C to B. Some more things need to be done to get a grade of A!

  • http://www.dkdecorators.com Paul

    Thank you so much for this information; it has solved my yslow problems making it Grade A.

    Highly recommended.

    Thanks again.

  • Pingback: Blogger World()

  • Pingback: Caching und Compressing Optimierung in der .htaccess | Webmaster, Security und Technik Blog()

  • Pingback: Website Leistung: Von 4,7 auf 1,9 Sekunden > Apache, Geschwindigkeit, Leistung, MySQL, Tool > splash ;)()

  • http://ajaydsouza.com/ Ajay D’Souza

    Are you using this on your site? I’ve added this to my blogs, but ySlow firefox addon doesn’t seem to say that the expire headers are set, these are for both my blogs as well as your site

    • http://www.samaxes.com/ Samuel Santos

      I’m using a script very similar to this one except for mod_deflate module.
      Unfortunately my hosting provider is still using Apache 1.3.x; only Apache 2 or greater comes bundled with it.

  • Pingback: Speed Up Pligg Loading Times By Using htaccess Rules | Pligg Template()

  • Pingback: Some WordPress Stuff « i can haz .NET()

  • http://www.launchbutton.net/ Scott

    Just wanted to say thanks for this post, I added this to my .htaccess file and knocked off 2+ seconds on my page load times, and bumped up a letter grade in YSlow! I’m putting it on all my sites.

  • Pingback: Site compressing and caching with Apache .htaccess | WithExample()

  • Paul

    Hi Santos

    Just wanna drop by to say Hello and Thanks.
    I used the second htaccess code above and everything went perfect.

    I’m amazed by the instant faster pageload time of my WP site.
    Thanks again for this valuable post.

    BTW, what is Etag ? and why do we unset it ?

    • http://www.samaxes.com/ Samuel Santos

      Entity tags (ETags) are a mechanism to check for a newer version of a cached file.
      By removing the ETag header, you disable caches and browsers from being able to validate files, so they are forced to rely on your Cache-Control and Expires header.

  • Paul

    Hi again Santos

    Thanks for the information.


  • http://neotropicsolutions.net Shawn Rebelo

    Simply great! Thank you for this as it is perfect!

  • http://www.techmafia.org Techmafia

    Well this is great

    lets see if it works well or not !!!:P

  • http://icanhazdot.net/2010/03/23/some-wordpress-stuff/ Ewen

    This is a great resource. I have linked to it in a post I wrote about my meddlings, er optimizations, in WordPress at http://icanhazdot.net/2010/03/23/some-wordpress-stuff/.

    I added the following about your code to bypass the compression process for files that already have compressed versions that could be sent with a simple rewrite.

    RewriteEngine on
    #Check to see if browser can accept gzip files. If so and we have it - serve it!
    ReWriteCond %{HTTP:accept-encoding} gzip
    RewriteCond %{HTTP_USER_AGENT} !Safari
    #make sure there's no trailing .gz on the url
    ReWriteCond %{REQUEST_FILENAME} !^.+.gz$
    #check to see if a .gz version of the file exists.
    RewriteCond %{REQUEST_FILENAME}.gz -f
    #All conditions met so add .gz to URL filename (invisibly)
    RewriteRule ^(.+) $1.gz [QSA,L]

    Thanks for the post – it helped me out a lot.

    • http://www.samaxes.com/ Samuel Santos

      Great code snippet Ewen. Thanks for sharing!

  • http://www.drleyes.com Rafael

    Fantastic!! My site is faster, so faster…Thanks…

  • Pingback: Gzip it for speed | HOSTERWARE UK.()

  • Pingback: how to use .htaccess file to improve your wordpress blog | .htaccess guide()

  • Pingback: Links for 2010-01-10 [del.icio.us] | Just free for all()

  • Ben

    Heej Santos, Thanks for the great tips. It greatly improves the pageload speed. Just have one question, I’m getting this from Google PageSpeed: “Specify a cache validator”:

    The following resources are missing a cache validator. Resources that do not specify a cache validator cannot be refreshed efficiently. Specify a Last-Modified or ETag header to enable cache validation for the following resources.

    I know it’s turned off in your snippet, is there anyway to fix this error?

    • http://www.samaxes.com/ Samuel Santos

      Hi Ben,

      As you may find in a previous post – .htaccess – gzip and cache your site for faster loading and bandwidth saving, removing Last-Modified and ETag headers can indeed reduce your HTTP requests and improve your pages speed.

      However I’m not familiar with Google PageSpeed and I’m still using YSlow.
      You may try to comment the line Header unset Last-Modified to get a better score on Google tool and do some testing to check if you notice any degradation at all on your pages speed.

  • Pingback: WordPress MultiSite Performance Optimization()

  • Pingback: Caching a Dynamic Website. Does it Make a Difference for Loading Speed? « Boutros AbiChedid()

  • Ashok


    great cheers for your performance tips…it really worked great…


  • Shane

    Thanks for this.
    I have been messing/reading/testing/ around all day on optimizing a site and your article has helped me more than all the rest combined…Cheers

  • http://www.sogarab.com sogarab

    This is an excellent tip
    Thank you so much..

  • wojj76

    Thanks mate. You just made my site useable :)

  • Sam

    Great example, thanks! I have one question: as I understand, this htaccess file removes the ETag and Last Modified.
    Google here: http://code.google.com/speed/page-speed/docs/caching.html
    recommends that quote:
    “It is important to specify one of Expires or Cache-Control max-age, and one of Last-Modified or ETag, for all cacheable resources”
    Do you think it’s better to keep the ETag on?

    • http://www.samaxes.com/ Samuel Santos

      Hi Sam,
      This htaccess is wrong; you should keep the Last-Modified header.
      I’m writing a new article about this subject, hopefully it will be clearer.

  • Pingback: 终于修改了 browser caching 过期的时间 « 没见过御姐的御姐控()

  • Pingback: 30+ Popular .htaccess code snippets()

  • http://jamesriter.com James Riter

    Thanks! For me working with .htaccess is something better off left to the pros. lol

  • Pingback: The Need for Speed | Merge()

  • http://www.xumaa.com Rahman

    Thank you so much, This worked great on our company OS Commerce site. it had resolved allot of the issue we were facing due to gzip for js.

    Again Thanks for your help

  • Pingback: WordPress Arena: A Blog for WordPress Developers, Designers and Blogger()

  • http://blogdum.com Shasha

    What is the difference between using mod_deflate codes and W3total cache plugin to optimize wordpress blog?

  • balu

    Thanks dude :) very helpful.

  • Pingback: 30 Popular .htaccess code snippets | Magento Host Solution()

  • Pingback: WordPress haute performance avec le htacces()

  • http://www.siterevista.com Rinto George

    Nice article, by the way I had used this in my website.

  • http://www.klamonfra.de/ Klaus

    Thank you for the overview