<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Web Development Blog &#187; caching</title>
	<atom:link href="http://www.leigeber.com/tag/caching/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.leigeber.com</link>
	<description>This web development blog features fresh articles on JavaScript, AJAX, CSS, XHTML, PHP, Photoshop and more.</description>
	<lastBuildDate>Sat, 13 Feb 2010 02:05:55 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Introduction to Web Caching</title>
		<link>http://www.leigeber.com/2008/04/introduction-to-web-caching/</link>
		<comments>http://www.leigeber.com/2008/04/introduction-to-web-caching/#comments</comments>
		<pubDate>Sat, 26 Apr 2008 04:04:05 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[API]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[caching]]></category>

		<guid isPermaLink="false">http://www.leigeber.com/?p=27</guid>
		<description><![CDATA[Intelligent caching can dramatically decrease server load and increase website responsiveness. This article introduces caching and highlights some best practices using Apache and PHP.]]></description>
			<content:encoded><![CDATA[<p>To begin I would like to thank all of you that have shown interest in this blog and posted comments. The site launched one week ago and has already generated over 13,000 unique visitors and 40,000 page views. As I am writing this article my previous post is on the front page of del.icio.us. I look forward to expanding and improving the site and ask that if you have any comments or suggestions please contact me.</p>
<p>Following up on my post last week about the <a href="http://www.leigeber.com/2008/04/eaccelerator-php-accelerator/">eAccelerator PHP optimizer</a> and cache manager I thought I would post a general introduction to caching. This article focuses on caching in an Apache/PHP environment but the principles remain the same for any platform/language you work with.</p>
<h4>Browser Cache</h4>
<p>Every browser has it&#8217;s own cache but the size and behavior of each varies. Fortunately we are not at the sole mercy of the browser to determine how to handle our data. Through the use of HTTP headers you can dictate to the browser when to request updated content and when to serve files from the local cache. I highly suggest downloading the Firefox plugins <a href="https://addons.mozilla.org/en-US/firefox/addon/1843" target="_blank">Firebug</a> and <a href="https://addons.mozilla.org/en-US/firefox/addon/5369" target="_blank">YSlow</a> to help you analyze your HTTP headers. Below you can see a screenshot of the headers tab available on any HTTP request through Firebug.</p>
<p><img src="http://www.leigeber.com/wp-content/uploads/2008/04/firebug_headers.gif" alt="Firebug Headers" width="459" height="360" /></p>
<p>The difficulty of caching is determining how you want the browser to cache and then pulling it all together on the server-side. Different file types, for instance, might be generally more static than others and therefore safer to cache for long periods of time. On the other hand, some content may updated on a regular basis and not need to be cached for long, if at all. Since the browser is closest to the user and your server is potentially never involved in the serving of content the highest performance boost can come from effective browser caching.</p>
<p>Below is an example of setting a header property in PHP. This would tell the browser to cache the files for one year from the date of this post.</p>
<p><code>&lt;?php<br />
header('Expires: Fri, 25 Apr 2009 00:00:00 GMT');<br />
?></code></p>
<p>Here is an example of setting headers with Apache. This would set an expiration of one year from today on all images files.</p>
<p><code>&lt;FilesMatch "\.(jpg|jpeg|png|gif)$"><br />
Header set Expires "Fri, 25 Apr 2009 00:00:00 GMT"<br />
&lt;/FilesMatch></code></p>
<p>There are a number of header parameters that can be sent as part of your response to HTTP requests. Here is a breakdown of the ones you should be familiar with for caching purposes&#8230;</p>
<p><strong>Last-modified: Fri, 25 Apr 2008 00:00:00 GMT</strong><br />
This header tells the browser when the file being requested was last altered. The browser &#8220;asks&#8221; your server if it has a file that has a more recent &#8220;Last-modified&#8221; timestamp than the version that is currently has stored. If a newer file exists on your server then the browser requests the updated file, else the existing file is served. Although the communication does have a little overhead, it is much more efficient than simply serving the same unmodified content over and over.</p>
<p><strong>Etag: &#8220;28ff-44aee6630f900&#8243;</strong><br />
Etags are basically unique identifiers attached to your files that the browser can use to compare cached files against. This works much like the &#8220;Last-modified&#8221; tag and there has been quite a bit of debate as to whether one is better than the other or whether to include both. I personally suggest including both as there may be rare situations where the Etag would detect changes that are not effected in the timestamp.</p>
<p><strong>Expires: Fri, 25 Apr 2009 00:00:00 GMT</strong><br />
The expires header is ideal when you can plan on how long your content is safely cacheable. Why is it superior to the previous two cache controls? Using expires does not require a trip to the server to verify the freshness of your content. The browser simply serves the files from the local cache for the fastest user experience and zero server overhead.</p>
<p><strong>Cache-Control: max-age=86400</strong><br />
The max-age tag, much like the expires header, eliminates the need to check for updated content when the cached file is within the age limit specified. The value assigned to the max-age is the number of milliseconds the file will be considered fresh. During that time, the locally stored files will be served. It is important to note that HTTP/1.1 allows caching of anything unless overridden by the &#8220;Cache-Control&#8221; header.</p>
<hr />
<p>For static content I highly suggest serving files from a cookie-free subdomain (i.e. static.domain.com) and establishing a &#8220;never expires&#8221; policy. Many larger site have already taken advantage of this tactic but smaller sites can also benefit from the method. When you need to make a change to a file simply change the reference to the file to an incremented version (javascrtipt_1.js -> javascript_2.js) of itself and then the newer version will be downloaded and cached. There are even ways to automate the versioning process. </p>
<p>For dynamic files it is best to use the Cache-Control: no-cache header and for more static files the Last-modified header is appropriate. Another method to ensure content is refreshed is to append some unique querystring value to the URI.</p>
<p>Example of setting a &#8220;never expires&#8221; header for all static files&#8230;<br />
<code>&lt;FilesMatch "\.(jpg|jpeg|png|gif|swf|css|js|ico|pdf)$"><br />
Header add "Expires" "Mon, 01 Jan 2018 00:00:00 GMT"<br />
Header add "Cache-Control" "max-age=31536000"<br />
&lt;/FilesMatch></code></p>
<p>or with PHP&#8230;<br />
<code>&lt;?php<br />
header('Expires: Mon, 01 Jan 2018 00:00:00 GMT');<br />
header('Cache-Control: max-age=31536000');<br />
?></code></p>
<h4>Server Caching</h4>
<p>Server-side caching can have a huge impact on performance. Since the highest level of caching your PHP files should be set to is Last-modified, Apache will be serving these files most frequently. There are a number of third party caching/PHP optimizers that make caching a breeze such as <a href="http://xcache.lighttpd.net/" target="_blank">XCache</a>, <a href="http://eaccelerator.net/" target="_blank">eAccelerator</a>, <a href="http://danga.com/memcached/" target="_blank">memcached</a> and others. You can even store your compiled pages in memory with these optimizers for an even faster client/server transaction.</p>
<p>You are not limited to using one of these third parties for caching. You can manually cache files in PHP through the use of code like the following&#8230;</p>
<p><code>&lt;?php<br />
$current = $_SERVER["SCRIPT_NAME"];<br />
$parts = Explode('/', $current);<br />
$current = $parts[count($parts) - 1];<br />
$store = 'cache/';<br />
$page = $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];<br />
$cache = $store.md5($page).'.cache';<br />
if(file_exists($cache) &#038;&#038; (filemtime($current) &lt; filemtime($cache)) ) {<br />
  @readfile($cache);<br />
  exit();<br />
}<br />
ob_start();<br />
// YOUR PHP SCRIPT //<br />
$new = fopen($cache, 'w');<br />
fwrite($new, ob_get_contents());<br />
fclose($new);<br />
ob_end_flush();<br />
?></code></p>
<h4>Intermediary Caching</h4>
<p>By intermediary caching I am referring to anything between the browser and the server that caches your content. Perhaps you are using a third party CDN (content delivery network) such as <a href="www.akamai.com/" target="_blank">Akamai</a> or <a href="http://www.edgecast.com" target="_blank">edgecast</a> to speed up HTTP request delivery. These types of services are tailored to high volume websites with widespread user-bases and are generally cost-prohibitive to small-medium sized websites.</p>
<p>There are also other caches you may not not even know exist. Many large corporations, educational institutions and even countries cache content coming into their network. Oftentimes the proxies function much like browsers in their respect for HTTP headers however they do not always abide by your rules so be sure and identify private content by defining unique querystring parameters lest sensitive information be spread to multiple recipients.</p>
<hr />
<p>Hopefully, if you are not caching now, you will be motivated to implement a caching policy soon. I plan to follow up soon with a more in-depth Apache/PHP caching post.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.leigeber.com/2008/04/introduction-to-web-caching/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
		<item>
		<title>eAccelerator PHP Accelerator</title>
		<link>http://www.leigeber.com/2008/04/eaccelerator-php-accelerator/</link>
		<comments>http://www.leigeber.com/2008/04/eaccelerator-php-accelerator/#comments</comments>
		<pubDate>Thu, 17 Apr 2008 18:50:42 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[caching]]></category>
		<category><![CDATA[eaccelerator]]></category>

		<guid isPermaLink="false">http://www.leigeber.com/?p=8</guid>
		<description><![CDATA[Implementing a PHP accelerator like eAccelerator should yield noticeable speed improvements and give you the ability to use memory as a data store.]]></description>
			<content:encoded><![CDATA[<p>As my first topic I am going to discuss PHP performance boosting utility eAccelerator. I am currently working on a PHP based web project that fires off about 30 XMLHttpRequests in succession. The response of each call is displayed on the website and needed after the completion of all the requests where the responses are added to a database. PHP session variables were a possibility however speed could easily become an issue since PHP would be handling many simultaneous sessions and the values would have the be retrieved from the hard disk. Alternatively a database based session handler might be faster but certainly not practical with so many commands being executed in succession. Cookies would have worked for most users however I do not recommend relying on cookies when the sole functionality of an application depends on them.</p>
<p>I also wanted to store the responses for quick retrieval, which are very small, ranging from a few bytes to half a kilobyte, since it is likely different users will request the same information frequently. With this in mind, neither of the previous options were ideal. Ideally the responses could be stored in memory and the PHP functions have the ability to quickly set and retrieve data. Obviously you would not want to try and store a multitude of very large objects in memory however in my case I could store thousands of key-value pairs using a small block of memory. This is where eAccelerator became a practical match for my application. It is among a few PHP memory caching options available such as XCache and Memcache. Although eAccelerator is first and foremost a PHP cache utility to store compiled scripts it also features the ability use memory as a temporary store for information through a powerful API.</p>
<p>On to the installation process&#8230; If you run a dedicated server with CPanel/WHM there is an option in the Easy Apache configuration wizard to compile with eAccelerator. Unfortunately, with the latest version of eAccelerator the put and get functions are not enabled on a default compile so I had to take the installation to command line. Keep in mind that you will need root access to be able to recompile Apache. The process I followed is below.</p>
<ul class="normallist">
<li>Download the latest release 0.9.5.2 from <a href="http://eaccelerator.net/wiki/Release-0.9.5.2" target="_blank">http://eaccelerator.net/wiki/Release-0.9.5.2</a></li>
<li>Upload the script to your server and extract the package</li>
<li>CD to the directory</li>
<li>Run export PHP_PREFIX=&#8221;/usr/lib&#8221; where &#8220;/usr/lib&#8221; is the location of your PHP installation</li>
<li>Run &#8216;phpize&#8217; if you are running multiple php branches to bootstrap eAccelerator by executing $PHP_PREFIX/bin/phpize</li>
<li>Run ./configure &#8211;enable-eaccelerator=shared &#8211;with-php-config=$PHP_PREFIX/bin/php-config &#8211;with-eaccelerator-shared-memory</li>
<li>There are other configuration options such as session support, a full list of options is available at <a href="http://eaccelerator.net/wiki/CompileConfiguration" target="_blank">http://eaccelerator.net/wiki/CompileConfiguration</a></li>
<li>Run make</li>
<li>Run make install</li>
<li>Locate your php.ini file and locate the eAccelerator configuration section where you can set default garbage collection times, storage options, and memory allocation. You can find more information about the settings at <a href="http://eaccelerator.net/wiki/InstallFromSource" target="_blank">http://eaccelerator.net/wiki/InstallFromSource</a></li>
<li>You need to make sure that the cache directory referenced in your php.ini is created and the chmod is set to 0777.</li>
</ul>
<p>Now you can create a simple test PHP script to put a key-value pair into memory and another to get the value of the key you added. A simple put command would look like &#8220;eaccelerator_put($key, $value, $ttl)&#8221; where $value is the time period in seconds that the key should be stored before being discarded. To retrieve the key&#8217;s value you can simply run the command &#8220;eaccelerator_get($key)&#8221;. You can find complete API details at <a href="http://bart.eaccelerator.net/doc/phpdoc/" target="_blank">http://bart.eaccelerator.net/doc/phpdoc/</a>.</p>
<p>By default if you are in a shared environment this functionality will be extended to everyone but you can disable eAccelerator on a per-domain level in your vhosts file. Extending the get/put methods to all users in a shared environment could potentially be dangerous. If you create a phpinfo() file you can monitor the memory usage, number of cached scripts and number of stored keys.</p>
<p>So, how much does this really help? You should see a nice drop in CPU utilization since PHP scripts will be more efficiently compiled and since they are served from memory as long as you have memory available the response time is noticeably quicker. Overall I didn&#8217;t see any real performance compromises by enabling eAccelerator. Obviously you will be using more memory but you have control over the amount that is used for storage. After the max is reached then scripts and keys are stored in the cache directory reference in the php.ini file. If you are running PHP, have extra memory available and have root access then I highly recommend eAccelerator to increase server speed and add valuable functionality to store, retrieve and remove data in memory. There are a number of practical applications for this utility.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.leigeber.com/2008/04/eaccelerator-php-accelerator/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
	</channel>
</rss>
