The Correct Way To Set Up gzip with Magento

We wrote this article in response to postings offering advice to users of Magento, an open source ecommerce system. The advice is being given with good intentions, and the intent is only to assist their fellow Magento users. But the advice being give may actually have the potential cause harm to the users site, or at the least a good deal of down time. The advice being offered is to help speed up Magento by enabling a server side caching system called gzip. What people don’t realize is that their being told to enable two separate caching systems. These two systems tend not to play well together, and could cause harm to your install. While most people see positive results, there are a rare few seeing server side errors, database errors, and are stumped as to why.

The two caching systems are gzip and zlib. Most reputable hosting companies include these options in their shared hosting packages. By default most of these options are disabled. We’re going to show you the right way to setup caching on your server, and at the same time solve the dreaded recurring memory issues that have plagued so many Magento users. Our setup is as follows. A shared hosting account on Hostmonster.com, a fresh Magento install, currently the latest version 1.3.2.4. and the gzip caching.

The majority of people reading this will be on a similar shared hosting account, so this will be our focus. If you don’t already know whether gzip is available on your server, copy the following code to an html editor, or a text editor, and save it as test.php

1
2
3
<?php
phpinfo();
?>

Upload the file to your server, and navigate to it with your web browser. If you see gzip anywhere on the info page, you’re in luck. Remember to remove this file before moving on, as it does pose a security threat if left on the server.

Next you need to log into you hosting account and access your cpanel. Keep in mind that most good hosting companies will help you with all of this, so never be ashamed to ask for help.

Before going any further, you should also be absolutely positive that all your sites can run on PHP5. If not you’ll want to upgrade any scripts utilizing an older version of php. Now we need to install a single default ini, php.ini.default, via your cpanel. Navigate to the the php admin area. Choose to install a (Single php.ini) Choose save, then scroll down to the checkboxes for IonCube and SourceGuardin, and click “Install php.ini Master File”. This manually directs system resources to the new location of your single php.ini file. Call your host if you need help. Now download the file that was just created from the root directory of your server ( php.ini.default ) Rename this file to php.ini and open it.

First locate the memory settings, currently located on line 225, and duplicate the setting bellow. Your location may vary. Note, the character # before a statement means that won’t be read by the server, and has been “commented out”.

225
226
227
228
229
230
231
;;;;;;;;;;;;;;;;;;;
; Resource Limits ;
;;;;;;;;;;;;;;;;;;;
 
max_execution_time = 60     ; Maximum execution time of each script, in seconds
max_input_time = 120	; Maximum amount of time each script may spend parsing request data
memory_limit = 128M      ; Maximum amount of memory a script may consume (64MB)

Change the default memory from the whopping default of 32m to a minimum of 64m in a busy environment, or preferably to something like 128m, or even 256m if running a sizable store on a standalone server. Setting the ram too high can lead to system instability, loss of performance, and even a loss of privilege stemming from an intervention by your system admins. With this ini in place, you’ve now set a global memory setting across all folders on your server. This is a sure fire way to eliminate freezing during checkout, and other random Magento weirdness.

While here, you may also want to increase server execution time. While not necessary, especially with our now increased Ram, our suggestion would be to double or triple the current settings. If you’ve got a script running longer than a few minutes, there’s probably something wrong, and a forced stop is in order.

Now that we’re utilizing more memory, and have improved overall stability and reliability, it’s time to really make this thing boogie. With our default php.ini still open, search for ob_gzhandler This is also an area where you’ll see the use of either gzip or zlib, and never both. At the time of this tutorial the statement we’re interested in uncommenting is located on line 106. Your location may vary. Note, like # in our .htaccess, ; means that any statement following this character isn’t read by the server, and is “commented out”.

87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
; Output buffering allows you to send header lines (including cookies) even
; after you send body content, at the price of slowing PHP's output layer a
; bit.  You can enable output buffering during runtime by calling the output
; buffering functions.  You can also enable output buffering for all files by
; setting this directive to On.  If you wish to limit the size of the buffer
; to a certain size - you can use a maximum number of bytes instead of 'On', as
; a value for this directive (e.g., output_buffering=4096).
output_buffering = Off
 
; You can redirect all of the output of your scripts to a function.  For
; example, if you set output_handler to "mb_output_handler", character
; encoding will be transparently converted to the specified encoding.
; Setting any output handler automatically turns on output buffering.
; Note: People who wrote portable scripts should not depend on this ini
;       directive. Instead, explicitly set the output handler using ob_start().
;       Using this ini directive may cause problems unless you know what script 
;       is doing.
; Note: You cannot use both "mb_output_handler" with "ob_iconv_handler"
;       and you cannot use both "ob_gzhandler" and "zlib.output_compression". 
output_handler = ob_gzhandler
 
; Transparent output compression using the zlib library
; Valid values for this option are 'off', 'on', or a specific buffer size
; to be used for compression (default is 4KB)
; Note: Resulting chunk size may vary due to nature of compression. PHP 
;       outputs chunks that are few hundreds bytes each as a result of 
;       compression. If you prefer a larger chunk size for better 
;       performance, enable output_buffering in addition.
; Note: You need to use zlib.output_handler instead of the standard
;       output_handler, or otherwise the output will be corrupted.
zlib.output_compression = Off
 
; You cannot specify additional output handlers if zlib.output_compression
; is activated here. This setting does the same as output_handler but in
; a different order.
;zlib.output_handler =

Notice here that zlib is either commented out, or off. Be sure it stays this way.

Something else worth mentioning is the addition of the following statements to your ini file. As of this tutorial, the following statements were added to our php.ini by default. But if your hosting provider isn’t as proactive, they may be missing. If so add them somewhere near the bottom of your ini file as follows.

1125
1126
1127
1128
extension=pdo.so
extension=pdo_sqlite.so
extension=sqlite.so
extension=pdo_mysql.so

We’ve now finished editing our PHP.ini. Upload the file back to the root of your server. This one file provides the single largest performance and stability improvement you’ll find with Magento.

Next retrieve your .htaccess file from the root of your Magento install. Duplicate the settings you see below, and again upload the file back to the root of your server.
Memory settings:

33
34
35
36
37
38
39
40
############################################
## adjust memory limit
 
#    php_value memory_limit 64M
    php_value memory_limit 128M
    php_value max_execution_time 18000
 
############################################

GZip utilization:

78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
############################################
## enable apache served files compression
## http://developer.yahoo.com/performance/rules.html#gzip
 
    # Insert filter on all content
    SetOutputFilter DEFLATE
    # Insert filter on selected content types only
    AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript
 
    # Netscape 4.x has some problems...
    BrowserMatch ^Mozilla/4 gzip-only-text/html
 
    # Netscape 4.06-4.08 have some more problems
    BrowserMatch ^Mozilla/4.0[678] no-gzip
 
    # MSIE masquerades as Netscape, but it is fine
    BrowserMatch bMSIE !no-gzip !gzip-only-text/html
 
    # Don't compress images
    SetEnvIfNoCase Request_URI .(?:gif|jpe?g|png)$ no-gzip dont-vary
 
    # Make sure proxies don't deliver the wrong content
    Header append Vary User-Agent env=!dont-vary
 
</IfModule>
 
<IfModule mod_ssl.c>
 
############################################

Also look at the top of your .htaccess file. If you don’t see the following, and you’re sure you’ve setup your server to use a single php.ini by default, add the following.

1
2
3
4
5
6
7
8
9
10
11
# Use PHP5 Single php.ini as default
AddHandler application/x-httpd-php5s .php
############################################
## uncomment these lines for CGI mode
## make sure to specify the correct cgi php binary file name
## it might be /cgi-bin/php-cgi
 
#    Action php5-cgi /cgi-bin/php5-cgi
#    AddHandler php5-cgi .php
 
############################################

This would be a good time to remove any extra php.ini or .htaccess files you’ve loaded to miscellaneous directories in an attempt to improve Magento’s stability, something we ourselves were guilty of.

And that’s it, within a minute of uploading your .htaccess file you’ll be serving, gziped files with a compression ratio of 70-90 percent. Be sure to check that all scripts being served properly, and are functioning normally. Compression may cause some scripts to behave erratically, or even cause pages to load jumbled content. To find out exactly what your compression ratio is, visit any of the sites below and input your website url.

GZip Testing Sites

  1. GZip Discrimination Test
  2. Whatsmyip

We hope this article was helpful, and if you think we’ve missed anything, let us know. Thanks for stopping by.



Was this article helpful? Here's a few related articles which may also interest you.


6 Comments to “The Correct Way To Set Up gzip with Magento”

  1. Yurii says:

    Thank you so much!!!!!!!!!!!!!

    I had the hardest time getting gzip to work right. I went through everything you wrote. I tried it and its working!! What a huge difference in load times. I was starting to think Magento just had errors out of the box. But this fixed it. Thank you!!!!!

    Did I mention? Thank you. Thank you. Thank you. Thank you. Thank you. Thank you. Thank you. Thank you.

  2. Duarte Netto says:

    Hi,

    I’ve just enabled the Gzip on the server (win 2003 standard with iis 6).

    Now, i have confirmed that the server as the Gzip activated with the test to a domain in the same server but when i try to test it on the Magento domain…it inst activated.

    Test Tool
    http://www.whatsmyip.org/http_compression/

    Domain in the same server
    http://directo.tr2k.com/login.aspx

    Domain with MAGENTO
    http://www.rockartstore.com/index.php/

    The .htaccess doest work on IIS so that’s not a solution…iv tried in the php.ini only seems to work on Apache.

    Any suggestions?

    Is there a place were i can enable it in the admin panel?

  3. Fertiliser says:

    Best version so far as mentioning that the php.ini requirements did the trick for me. Is output_handler = ob_gzhandler better than zlib.output_compression as both are enabled on my server?

    I installed yslow and it shows about 19 .css and .js files are not sent compressed eg. /js/prototype/prototype.js and /css/reset.css but the main site is gziped http://www.biostim.com.au . Is there anyway to get them compressed also.

    I tried to Minify JavaScript and CSS with Foomans speedster extension http://www.magentocommerce.com/magento-connect/FOOMAN/extension/457/fooman-speedster but my theme didn’t work too well so I uninstalled it.

    To Add Expires headers I put the below into .htaccess(after # Make sure proxies don’t deliver the wrong content
    Header append Vary User-Agent env=!dont-vary </IfModule) but a few files still didn't change eg /skin/frontend/default/biostim/favicon.ico

    “Code Edited Here. Revised Code Posted in Reply Below….”

    Thank you for the post.

    Kind regards
    Tim

  4. Fertiliser says:

    The above code for Add expire headers didn’t post correctly. You can find it at http://www.copypastecode.com/38385/

    • Admin says:

      Thanks for the reply. Here’s the code you posted.

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      
      <ifmodule mod_headers.c>
        # Cache specified files for 6 days
        <filesmatch ".(ico|flv|jpg|jpeg|png|gif|css|swf)$">
        Header set Cache-Control "max-age=518400, public"
        </filesmatch>
        # Cache HTML files for a couple hours
        <filesmatch ".(html|htm)$">
        Header set Cache-Control "max-age=7200, private, must-revalidate"
        </filesmatch>
        # Cache PDFs for a day
        <filesmatch ".(pdf)$">
        Header set Cache-Control "max-age=86400, public"
        </filesmatch>
        # Cache Javascripts for 2.5 days
        <filesmatch ".(js)$">
        Header set Cache-Control "max-age=216000, private"
        </filesmatch>
      </ifmodule>
  5. I just finished implementing this on one of my customers website, and I must tell you, it worked. A brilliant job done here by you guys. When I was looking for the right way to get gzip working with Magento, your listing on Google was 3rd but you deserve to be as the first result. A must read for all Magento users. I also liked you on stumble upon, good on you guys. Thanks for your kind work.

Leave a Comment