<?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>AskApache &#187; Search Results  &#187;  bottleneck</title>
	<atom:link href="http://www.askapache.com/search/bottleneck/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.askapache.com</link>
	<description>Advanced Web Development</description>
	<lastBuildDate>Thu, 26 Apr 2012 11:29:28 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Vetted &#8211; Top 3 WordPress Speed Plugins</title>
		<link>http://www.askapache.com/wordpress/fastest-caching-plugins.html</link>
		<comments>http://www.askapache.com/wordpress/fastest-caching-plugins.html#comments</comments>
		<pubDate>Sun, 29 Nov 2009 19:14:16 +0000</pubDate>
		<dc:creator>AskApache</dc:creator>
				<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://www.askapache.com/?p=3701</guid>
		<description><![CDATA[<p><a class="IFL" id="id15" href="http://www.askapache.com/wordpress/fastest-caching-plugins.html" title="Top 3 WordPress Plugins for a Faster Blog"></a>There are so many WordPress plugins out there now that I wanted to post my favorite 3 plugins for speeding up a WP-Powered blog.  These are the 3 plugins that I install for pretty much all of my WP-Powered sites, which I run about 300 now.  They work together to provide a very optimized blog for speed.<br /><br /><strong>DB-Cache Reloaded does something entirely different</strong>, it saves the mysql queries that are made to the WP-database, as well as the mysql results to static files, and then through php serves those cached-files instead of re-querying the mysql database. Most mysql databases are stored on separate servers, and although many are on the same local network there is a limit to how many queries, and how many connections can take place.<br /><br />So DB-Cache Reloaded basically makes WP-Super Cache work alot faster when generating the cache files, and DB-Cache Reloaded helps in a number of areas un-related to WP-Super Cache, like in the admin panel.  And DB-Cache without WP-Super-Cache is a joke because it still uses the application-level and php for everything.  <em>Gotta use both (or just WPSC)</em>.<br class="C" /></p>]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.askapache.com/wordpress/fastest-caching-plugins.html"></a><a href="http://www.askapache.com/wordpress/fastest-caching-plugins.html"><cite>AskApache.com</cite></a></p><p>There are so many WordPress plugins out there now that I wanted to post my favorite 3 plugins for speeding up a WP-Powered blog (including one of <a href="http://wordpress.org/extend/plugins/profile/askapache">my plugins</a>).  These are the 3 plugins that I install for pretty much all of my WP-Powered sites, which I run about 300 now.  They work together to provide a very optimized blog for speed.</p>

<h2>Top 3 WordPress Speed Plugins</h2>
<ol class="TOC">
<li><a href="http://www.askapache.com/wordpress/fastest-caching-plugins.html#db-cache-reloaded">DB Cache Reloaded</a></li>
<li><a href="http://www.askapache.com/wordpress/fastest-caching-plugins.html#wp-super-cache">WP Super Cache</a></li>
<li><a href="http://www.askapache.com/wordpress/fastest-caching-plugins.html#crazy-cache">AskApache Crazy Cache</a></li>
</ol>

<h2>WP Caching Overview</h2>
<p>Each request to your blog has to fire up the php interpreter and query the mysql database to create the output that you see in your browser.  Using a plugin like WP Super Cache simply saves the output of that request as a static HTML file and serves that to a request instead of using php and mysql every time.  DB Cache Reloaded takes this a step further by optimizing the mysql queries.  Finally, AskApache Crazy Cache is used to keep a cache fully primed and ready.</p>

<h3>Why Caching?</h3>
<p>If you have a private server, or you want to keep your MEMORY, BANDWIDTH, and CPU usage down for your server, these plugins will be dramatic.  If you have a site that is updated maybe once a month and gets a very small amount of traffic, then the AskApache Crazy Cache would be redundant.  That plugin is geared for the heaviest traffic sites.</p>


<h3>Request and Response</h3>
<p>Most HTTP communication is initiated by a user agent (browser) and consists of a request to a resource on some origin server. In the simplest case, this may be accomplished via a single connection (v) between the user agent (UA) and the origin server (O).</p>
<pre>             request chain ------------------------&gt;
          UA -------------------v------------------- O
             &lt;----------------------- response chain</pre>

<p>If a browser requests a WP-driven page, the server generates the response (the outputted html) by loading a php interpreter or module to read the WP php files and load all the settings.  WP stores the settings in a mysql database and has to query the mysql database for all the data (like the content of your post that becomes html).  Finally php sends the output through the server back to the browser.  This is the norm for most PHP applications.  Every time an interpreter is loaded additional CPU and Memory are used.  And perhaps even more troublesome for shared-hosting using a virtual or network filesystem, each load causes many hard-disk accesses, additional processes, etc.</p>


<h3>Cache PHP</h3>
<p>By saving the php-generated output of a page to a static html file, your server can entirely skip loading a php interpreter or other process.  Originally servers were needed and created to essentially open a static file on disk and send that file back to the requesting user.  So servers are specialized for this as it's their core function.</p>

<p><strong>WP-Super cache does this for you by saving the output into a static html file</strong>, and by instructing the server to skip loading php.  It basically only uses php for creating the cached version, in the same way that you can save this webpage as an html file, WP-Super cache saves all the WP-blog permalinks to static files.</p>

<p><strong>DB-Cache Reloaded does something entirely different</strong>, it saves the mysql queries that are made to the WP-database, as well as the mysql results to static files, and then through php serves those cached-files instead of re-querying the mysql database. Most mysql databases are stored on separate servers, and although many are on the same local network there is a limit to how many queries, and how many connections can take place.  But mysql is maybe the fastest thing I've seen, so your bottlenecks almost never happen there (if configured correctly).</p>
<p>So DB-Cache Reloaded basically makes WP-Super Cache work alot faster when generating the cache files, and DB-Cache Reloaded helps in a number of areas un-related to WP-Super Cache, like in the admin panel.  And DB-Cache without WP-Super-Cache is a joke because it still uses the application-level and php for everything.  <em>Gotta use both (or just WPSC)</em>.</p>

<p><strong>AskApache Crazy Cache is a plugin I wrote</strong> to do one thing very well, it runs at intervals via the WP-cron and forces WP-Super-Cache to create a static cache file for all the posts, pages, etc. on your site.  Without this WPSC likes to do dumb things like try to manage it's own cache with stale files and expired files, which equals a lot more php interpreters getting loaded instead of cached static files.  For sites with more than a visit/page/10minutes this plugin keeps a full primed cache built by WPSC.</p>

<h3>Compression and WP-Super Cache</h3>
<p><strong>Enabling compression in WP-Super Cache</strong> is almost always a great idea.  I've never had a problem other than some php compat issues with not-updated php installations.  This option basically lets WP-Super Cache compress the generated output of a page and save that to the static file.  Normally Apache, Lighttpd, Nginx, etc. open the static file and compress it before it is sent to the browser, then the browser automatically decompresses it to view.  This happens so fast because it is run by the server.</p>
<p>This lets WPSC instruct your server to send the compressed version to all browsers that accept compression, and send the uncompressed static file to any other browsers.  So this is helpful because it eliminates your server having to do any transparent compressing, it can instead just focus on what it does best, serving static files.</p>

<p>PHP is an application so it requires memory, hard-drive access, and CPU time.  Check out the protocol hierarchy:</p>
<pre>       +------+ +-----+ +-----+       +-----+
       |Telnet| | FTP | |Voice|  ...  |     |  Application Level
       +------+ +-----+ +-----+       +-----+
             |   |         |             |
            +-----+     +-----+       +-----+
            | TCP |     | RTP |  ...  |     |  Host Level
            +-----+     +-----+       +-----+
               |           |             |
            +-------------------------------+
            |    Internet Protocol &amp; ICMP   |  Gateway Level
            +-------------------------------+
                           |
              +---------------------------+
              |   Local Network Protocol  |    Network Level
              +---------------------------+</pre>







<p><a id="db-cache-reloaded" name="db-cache-reloaded"></a></p>
<h3>DB Cache Reloaded</h3>
<p><a href="http://wordpress.org/extend/plugins/db-cache-reloaded/">DB Cache Reloaded Plugin Page</a> - <a href="http://wordpress.org/tags/db-cache-reloaded?forum_id=10">News</a></p>
<p><a class="IFL" href="http://uploads.askapache.com/2009/11/db-cache-reloaded.png"><img src="http://uploads.askapache.com/2009/11/db-cache-reloaded-116x64.png" alt="DB Cache Reloaded" title="DB Cache Reloaded" width="116" height="64" /></a>This plugin caches every database query with given lifetime. It is much faster than other html caching plugins and uses less disk space for caching.<br /><br />I think you've heard of WP-Cache or WP Super Cache, they are both top plugins for WordPress, which make your site faster and responsive. Forget about them - with DB Cache Reloaded your site will work much faster and will use less disk space for cached files. Your visitors will always get actual information in sidebars and server CPU loads will be as low as possible.<br class="C" /></p>

<blockquote cite="http://wordpress.org/extend/plugins/db-cache-reloaded/faq/">
<h4>Why is DB Cache Reloaded better than WP Super Cache?</h4>
<p>This plugin is based on a fundamentally different principle of caching queries to database instead of full pages, which optimises WordPress from the very beginning and uses less disk space for cache files because it saves only useful information. It saves information separately and also caches hidden requests to database.</p>
</blockquote>




<p><a id="wp-super-cache" name="wp-super-cache"></a></p>
<h3>WP Super Cache</h3>
<p><a href="http://wordpress.org/extend/plugins/wp-super-cache/">WP Super Cache Plugin Page</a> - <a href="http://wordpress.org/tags/wp-super-cache?forum_id=10">News</a></p>
<p><a class="IFL" href="http://uploads.askapache.com/2009/11/wp-super-cache.png"><img src="http://uploads.askapache.com/2009/11/wp-super-cache-116x61.png" alt="WP Super Cache" title="WP Super Cache" width="116" height="61" /></a>This plugin generates static html files from your dynamic WordPress blog. After a html file is generated your webserver will serve that file instead of processing the comparatively heavier and more expensive WordPress PHP scripts.<br /><br />The static html files will be served to the vast majority of your users, but because a user's details are displayed in the comment form after they leave a comment those requests are handled by PHP. Static files are served to:<br /><br />&middot; Users who are not logged in.<br />&middot; Users who have not left a comment on your blog.<br />&middot; Or users who have not viewed a password protected post.<br /><br />99% of your visitors will be served static html files. Those users who don't see the static files will still benefit because they will see regular WP-Cache cached files and your server won't be as busy as before. This plugin will help your server cope with a front page appearance on digg.com or other social networking site.<br class="C" /></p>

<blockquote cite="http://wordpress.org/extend/plugins/wp-super-cache/faq/">
<h4>Why is WP-Super-Cache better than WP-Cache?</h4>
<p>This plugin is based on the excellent WP-Cache plugin and therefore brings all the benefits of that plugin to WordPress. On top of that it creates copies of every page that is accessed on a blog in a form that is quickly served by the web server. It's almost as quick as if the you had saved a page in your browser and uploaded it to replace your homepage.</p>
</blockquote>
<blockquote cite="http://wordpress.org/extend/plugins/wp-super-cache/faq/">
<h4>Will the Super Cache compression slow down my server?</h4>
<p>No, it will do the opposite in fact. Super Cache files are compressed and stored that way so the heavy compression is done only once. These files are generally much smaller and are sent to a visitor's browser much more quickly than uncompressed html. As a result, your server spends less time talking over the network which saves CPU time and bandwidth, and can also serve the next request much more quickly.</p>
</blockquote>



<p><a id="crazy-cache" name="crazy-cache"></a></p>
<h3>AskApache Crazy Cache</h3>
<p><a href="http://wordpress.org/extend/plugins/askapache-crazy-cache/">AskApache Crazy Cache Plugin Page</a> - <a href="http://wordpress.org/tags/askapache-crazy-cache?forum_id=10">News</a></p>
<blockquote cite="http://wordpress.org/extend/plugins/askapache-crazy-cache/">
<p><p><a class="IFL" href="http://uploads.askapache.com/2009/11/askapache-crazy-cache.png"><img src="http://uploads.askapache.com/2009/11/askapache-crazy-cache-116x36.png" alt="AskApache Crazy Cache" title="AskApache Crazy Cache" width="116" height="36" /></a>This sweet little plugin does one thing very well. It caches all the posts on your entire blog at the same time, if you are using WP-Cache, WP-Super-Cache, or Hyper-Cache.<br class="C" /></p></p>
</blockquote>










<pre>
                              +---------+ ---------\      active OPEN
                              |  CLOSED |            \    -----------
                              +---------+&lt;---------\   \   create TCB
                                |     ^              \   \  snd SYN
                   passive OPEN |     |   CLOSE        \   \
                   ------------ |     | ----------       \   \
                    create TCB  |     | delete TCB         \   \
                                V     |                      \   \
                              +---------+            CLOSE    |    \
                              |  LISTEN |          ---------- |     |
                              +---------+          delete TCB |     |
                   rcv SYN      |     |     SEND              |     |
                  -----------   |     |    -------            |     V
 +---------+      snd SYN,ACK  /       \   snd SYN          +---------+
 |         |&lt;-----------------           ------------------&gt;|         |
 |   SYN   |                    rcv SYN                     |   SYN   |
 |   RCVD  |&lt;-----------------------------------------------|   SENT  |
 |         |                    snd ACK                     |         |
 |         |------------------           -------------------|         |
 +---------+   rcv ACK of SYN  \       /  rcv SYN,ACK       +---------+
   |           --------------   |     |   -----------
   |                  x         |     |     snd ACK
   |                            V     V
   |  CLOSE                   +---------+
   | -------                  |  ESTAB  |
   | snd FIN                  +---------+
   |                   CLOSE    |     |    rcv FIN
   V                  -------   |     |    -------
 +---------+          snd FIN  /       \   snd ACK          +---------+
 |  FIN    |&lt;-----------------           ------------------&gt;|  CLOSE  |
 | WAIT-1  |------------------                              |   WAIT  |
 +---------+          rcv FIN  \                            +---------+
   | rcv ACK of FIN   -------   |                            CLOSE  |
   | --------------   snd ACK   |                           ------- |
   V        x                   V                           snd FIN V
 +---------+                  +---------+                   +---------+
 |FINWAIT-2|                  | CLOSING |                   | LAST-ACK|
 +---------+                  +---------+                   +---------+
   |                rcv ACK of FIN |                 rcv ACK of FIN |
   |  rcv FIN       -------------- |    Timeout=2MSL -------------- |
   |  -------              x       V    ------------        x       V
    \ snd ACK                 +---------+delete TCB         +---------+
     ------------------------&gt;|TIME WAIT|------------------&gt;| CLOSED  |
                              +---------+                   +---------+
&nbsp;
                      TCP Connection State Diagram</pre><p><a href="http://www.askapache.com/wordpress/fastest-caching-plugins.html"></a><a href="http://www.askapache.com/wordpress/fastest-caching-plugins.html">Vetted &#8211; Top 3 WordPress Speed Plugins</a> originally appeared on <cite>AskApache.com</cite> </p>]]></content:encoded>
			<wfw:commentRss>http://www.askapache.com/wordpress/fastest-caching-plugins.html/feed</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Optimizing Servers and Processes for Speed with ionice, nice, ulimit</title>
		<link>http://www.askapache.com/optimize/optimize-nice-ionice.html</link>
		<comments>http://www.askapache.com/optimize/optimize-nice-ionice.html#comments</comments>
		<pubDate>Sat, 10 Oct 2009 05:41:28 +0000</pubDate>
		<dc:creator>AskApache</dc:creator>
				<category><![CDATA[Optimization]]></category>

		<guid isPermaLink="false">http://www.askapache.com/?p=3167</guid>
		<description><![CDATA[<p><a href="http://www.askapache.com/linux/optimize-nice-ionice.html" class="IFL" id="id18"></a>To prepare for several upcoming articles on AskApache that are focused on optimizing Servers and Sites from a server admin level, here is an article to introduce the main tools that we will be using.  These tools are used to optimize CPU time for each process using <strong>nice</strong> and <strong>renice</strong>, and other tools like <strong>ionice</strong> are used to optimize the Disk IO, or Disk speed / Disk traffic for each process.  Then you can make sure your mysqld and httpd processes are always fast and prioritized.<br class="C" /></p>]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.askapache.com/optimize/optimize-nice-ionice.html"></a><a href="http://www.askapache.com/optimize/optimize-nice-ionice.html"><cite>AskApache.com</cite></a></p><p>Ok, sup.  I really felt I had to get this out of the way, because I have a whole stack of drafts waiting to be published, but I realized that not many people will benefit from all the advanced optimizations and tricks I'm writing unless they get a basic understanding of some of the tools I'm using.  I decided to write a series of articles explaining how I optimize servers for speed because lately I've been getting a lot more people wanting to hire me to do that.  I take on projects when I can but there is clearly a need out here on the net for some self-help.   The momentum is swinging more and more towards VPS type of web hosting, and I would say that 99% of those customers are getting supremely ripped off, which goes against the foundation of the web.</p>
<p>Keep in mind that this blog and my research is only a hobby of mine, my job is primarily marketing and sales, so I'm not some licensed expert or anything, or even an unlicensed expert! haha.  But it does bother me that those who are tech-savvy enough to run web-hosting companies are happily ripping people off.  So this article details the main tools that are used to speed up and optimize your machine by delegating levels of priority to specific processes.  Future articles will use these tools alot, so this is meant as an intro.</p>




<p><a id="cpu-disk-io" name="cpu-disk-io"></a></p><h2>CPU and Disk I/O</h2>
<p>As most of you are aware, there are 2 variables that determine any computer or programs speed.  CPU and Disk I/O.  CPU determines how fast you can process data, crunch numbers, etc. while disk I/O determines how fast your disks can read and write data to the hard-drive.  Wouldn't it be great if you could easily configure your server to give your httpd, php, and other processes both greater CPU processing and disk IO than your non-important processes like backup scripts, ftp daemons, etc.?  We are talking about Linux in this article, so of course YES not only can you do that, you should!</p>
<p><a name="optimize-ram" id="optimize-ram"></a></p><h3>RAM</h3>
<p>RAM is like a hard-drive in that data is stored on it, and read/written to it.  The difference is that RAM is somewhere around 30x faster than disk I/O, but the cost of that incredible speed is that the data stored on it is only temporary in the sense that it won't be stored permanently, it is completely erased when your machine is rebooted.  RAM is also expensive, and there is a limit to how much a server or machine can have due to hardware limits.</p>
<p><a name="optimize-swap" id="optimize-swap"></a></p><h3>SWAP</h3>
<p>SWAP takes off when you run out of RAM but you still want certain data to be read/write quickly.  Basically when you start running out of RAM your machine starts supplementing RAM with SWAP storage.  SWAP is usually a partition on a second hard-drive disk.  There is an upper limit on how much I/O can occur on a disk at one time, and the more I/O takes place, the slower all I/O becomes, so SWAP works well on a separate hard-drive as it will have much faster I/O.  On Windows they opted to copy the SWAP mechanism but instead use a file named pagefile.sys, and that is just one reason people in the know do not care for Windows.</p>
<p><a name="optimize-cpu" id="optimize-cpu"></a></p><h3>CPU</h3>
<p>So lets do this, think of your CPU (your processor) as having an amount of 100% processing available when not being used, 0% when its maxed out.  CPU's handle multiple processing tasks simultaneously, so what we will discuss in this article is how to specify HOW MUCH of that processing amount each of your programs (heretofore "processes") are able to use.  Yes, very very cool.</p>
<p>That is correct, you can easily configure your server to provide more of the available processing time to certain programs over others, like you can configure apache and php to utilize 50% of your CPU processing time by themselves, so that all other processes (proftpd, sshd, rsync, etc.) combined can only utilize 50%.  The terminology is we can give certain specific processes (like php.cgi, httpd, fast-cgi.cgi) a specific <strong>priority</strong>, where -19 is the most priority, and +19 is the least amount of priority, or CPU processing time.  I know it seems backwards.. </p>


<p><a id="tools" name="tools"></a></p><h2>The Tools</h2>
<p>If you run Windows, you are in the right place... because the following advice will save your life:  GET LINUX! Ok, now that that is out of the way, the following are the tools dicussed on this page.  All of them are free, open-source, and wonderful.  The basic idea of these tools is to control how much CPU is devoted to each process, and also how much Disk IO/Disk traffic is given to each process.</p>
<dl>
<dt><a href="#nice-tool">nice</a></dt><dd>run a program with modified scheduling priority</dd>
<dt><a href="#renice-tool">renice</a></dt><dd>alter priority of running processes</dd>
<dt><a href="#ionice-tool">ionice</a></dt><dd>set or retrieve the I/O priority for a given pid or execute a new task with a given I/O priority.</dd>
<dt><a href="#iostat-tool">iostat</a></dt><dd>Report Central Processing Unit (CPU) statistics and input/output statistics for devices and partitions.</dd>
<dt><a href="#ulimit-tool">ulimit</a></dt><dd>Ulimit provides control over the resources available to processes started by the shell, on systems that allow such control.</dd>
<dt><a href="#chrt-tool">chrt</a></dt><dd>set or retrieve real-time scheduling parameters for a given pid or execute a new task under given scheduling parameters.</dd>
<dt><a href="#taskset-tool">taskset</a></dt><dd>set or retrieve task CPU affinity for a given pid or execute a new task under a given affinity mask.</dd>
<dt></dt><dd></dd>
</dl>




<p><a id="part1-processes" name="part1-processes"></a></p><h2>Part 1: Process Processes Faster</h2>
<p>Ok so lets tackle figuring out how to give your response-intensive processes (like apache, php, ruby, perl, java) meaning a request to your server/machine requires a <em>response</em>.  For instance, when you requested this page that you are reading at this very second, several things on my server had to happen for you to be able to read this.</p>
<p>First your computer sends out a request to see what server the www.askapache.com domain name is.  DNS servers respond with my server IP, so for servers dedicated as nameservers, optimizing the DNS processes like bind would speed that up.  Now that your computer knows how to reach my server it sends an HTTP GET request for this url.  This request is received by the httpd process that is apache, and apache determines this url should be handled by my custom compiled php5.3.0 binary, because this page is WordPress generated.  So the php binary loads up the WordPress /index.php file, which chain-loads several other php files, including <code>wp-config.php</code> containing my MySql database settings.  Now php connects to my MySql Server to fetch this articles content, comments, title, tags, etc. and then generates the HTML and hands that back to Apache.</p>
<p>Finally, Apache generates a HTTP RESPONSE and sends the RESPONSE and CONTENT back to your Browser, which then in turn renders the page for your eyes with the necessary javascript, images, css, and other files included in the HTML response.</p>

<h3>Too much Processing</h3>
<p>Now you see why I've opted to write my own caching plugin that takes the php and mysql processes OUT of that equation.  Both the php binary and the mysql instance consume CPU processing, and disk IO, to load all their library files, make various network requests and sockets, check permissions, and on and on.  And that's completely ok, the thing is, unless you configure these processes (Apache, PHP, MySQL) they will use the same amount of CPU processing that other processes use, other processes that have very little to do with you reading this sentence.  Processes to run my mail server, my FTP server, my SSH server, my cronjobs, cleanup scripts, atd daemon, etc.. and they will get the same amount of CPU!</p>
<p>Another even simpler example is what got me to look into this myself.  I wrote a shell script that created hourly, daily, weekly, and monthly backups for all of my websites and sql databases, and set it up to run by cronjob at those set intervals.  Eventually I noticed my sites were slower, my php even slower, and sometimes I even saw 503 errors that my host throws up when my server is overloaded.  The research that I pursued to prevent that from happening has been hugely eye-opening.  What does a backup script do?  Mine just created tar archives of all the files in my web root, then gzipped the tar archive saving to a backup server using scp (a file transfer using ssh).  This resulted in the following huge problems that seem to have nothing to do with a faster server and speedier website, but they have everything to with it.</p>
<ol>
<li><strong>CPU Bottleneck #1</strong> - tar and gzip use compression algorithms at a low level to create a compressed version, and all that compressing uses a whole lot of crunching - CPU processing</li>
<li><strong>DISK IO Bottleneck</strong> - Tarring the whole web root directory was creating a ton of disk io, and remember the more disk io that is going on, the less is available for everything else.</li>
<li><strong>CPU Bottleneck #2</strong> - Using scp to send my backups was security-smart, but these huge archive files had to be encrypted and sent over the net.</li>
</ol>






<p><a id="breaking-bottlenecks" name="breaking-bottlenecks"></a></p><h2>Breaking Bottles</h2>
<p>I apologize for being a little long-winded there, but I think it's important to make sure everyone understands those basic concepts, which are foreign to most people.  Once you understand what is causing the bottlenecks, then you can understand the solutions, which actually are incredibly simple and even a novice linux user can easily do.  Besides, the net gets a little bit faster every time someone implements this.</p>

<p><a id="nice-tool" name="nice-tool"></a></p><h3>nice</h3>
<p><img src="http://uploads.askapache.com/2009/10/nice-chart.png" alt="NICE Levels Chart" title="NICE Levels Chart" width="351" height="225" class="IFL" />Nice allows you to run a program with modified scheduling priority which specifies how much CPU is devoted to a particular process.  Run COMMAND with an adjusted niceness, which affects process scheduling.  With no COMMAND, print the current niceness.  <br /><br />Nicenesses range from -20 (most favorable scheduling) to 19 (least favorable).   <code>-n, --adjustment=N</code> -  add integer N to the niceness (default 10).   <code>nice +19</code> tasks get a HZ-independent 1.5%.  Running a <code>nice +10</code> and a <code>nice +11</code> task means the first will get 55% of the CPU, the other 45%.<br class="C" /></p>

<p><a id="nice-usage" name="nice-usage"></a></p><h4>nice usage</h4>
<pre>nice [OPTION] [COMMAND [ARG]...]
&nbsp;
-n, --adjustment=ADJUST   increment priority by ADJUST first</pre>

<p><a id="nice-examples" name="nice-examples"></a></p><h4>Examples of nice</h4>
<p>Using nice to download a file</p>
<pre>nice -n 17 curl -q -v -A &#039;Mozilla/5.0&#039; -L -O http://wordpress.org/latest.zip</pre>
<p>Unzipping a file with nice</p>
<pre>nice -n 17 unzip latest.zip</pre>
<p>Nice way to build from source</p>
<pre>nice -n 2 ./configure
nice -n 2 make
nice -n 2 make install</pre>
<p>It is sometimes useful to run non-interactive programs with reduced priority.</p>
<pre>$ nice factor `echo &#039;2^9 - 1&#039;|bc`
511: 7 73</pre>
<p>Since nice prints the current priority, we can invoke it through itself to demonstrate how it works: The default behavior is to reduce priority by 10.</p>
<pre> $ nice nice
10
$ nice -n 10 nice
10</pre>
<p> The ADJUSTMENT is relative to the current priority.  The first <code>nice</code> invocation runs the second one at priority 10, and it in turn runs the final one at a priority lowered by 3 more.</p>
<pre>$ nice nice -n 3 nice
13</pre>
<p>Specifying a priority larger than 19 is the same as specifying 19.</p>
<pre>$ nice -n 30 nice
19</pre>
<p>Only a privileged user may run a process with higher priority.</p>
<pre>$ nice -n -1 nice
nice: cannot set priority: Permission denied
$ sudo nice -n -1 nice
-1</pre>

<blockquote cite="http://uploads.askapache.com/2009/08/sched-nice-design.txt">
<p>The new scheduler in v2.6.23 addresses all three types of complaints:</p>
<p>To address the first complaint (of nice levels being not "punchy" enough), the scheduler was decoupled from 'time slice' and HZ concepts (and granularity was made a separate concept from nice levels) and thus it was possible to implement better and more consistent nice +19 support: with the new scheduler nice +19 tasks get a HZ-independent 1.5%, instead of the variable 3%-5%-9% range they got in the old scheduler.</p>
<p>To address the second complaint (of nice levels not being consistent), the new scheduler makes nice(1) have the same CPU utilization effect on tasks, regardless of their absolute nice levels. So on the new scheduler, running a nice +10 and a nice 11 task has the same CPU utilization "split" between them as running a nice -5 and a nice -4 task. (one will get 55% of the CPU, the other 45%.) That is why nice levels were changed to be "multiplicative" (or exponential) - that way it does not matter which nice level you start out from, the 'relative result' will always be the same.</p>
<p>The third complaint (of negative nice levels not being "punchy" enough and forcing audio apps to run under the more dangerous SCHED_FIFO scheduling policy) is addressed by the new scheduler almost automatically: stronger negative nice levels are an automatic side-effect of the recalibrated dynamic range of nice levels.</p>
</blockquote>







<p><a id="renice-tool" name="renice-tool"></a></p><h3>renice</h3>
<p>Renice is similar to the nice command, but it lets you modify the nice of a currently running process.  This is nice for shell scripts where you can add this to the top of the script to nicify the whole script to 19.</p>

<p><a id="renice-usage" name="renice-usage"></a></p><h4>renice usage</h4>
<pre>renice priority [ [ -p ] pids ] [ [ -g ] pgrps ] [ [ -u ] users ]
&nbsp;
-g      Force who parameters to be interpreted as process group ID&#039;s.
-u      Force the who parameters to be interpreted as user names.
-p      Resets the who interpretation to be (the default) process ID&#039;s.</pre>

<p><a id="renice-examples" name="renice-examples"></a></p><h4>Examples of renice</h4>
<p>From the shell, changes the priority of the shell and all children to 19.  From a shell script, does the same but only for the script and its children.</p>
<pre>renice 19 -p $$</pre>
<p>This runs renice without any output</p>
<pre>renice 19 -p $$ &amp;&gt;/dev/null</pre>
<p>10 gets more CPU than 19</p>
<pre>renice 10 -p $$</pre>
<p>change the priority of process ID's 987 and 32, and all processes owned by users daemon and root.</p>
<pre>renice +1 987 -u daemon root -p 32</pre>









<p><a id="part2-disk-io" name="part2-disk-io"></a></p><h2>Part 2: Optimizing Disk I/O</h2>
<p><a id="scheduling-policies" name="scheduling-policies"></a></p><h3>Linux Scheduling Policies</h3>
<p>The scheduler is the kernel component that decides which runnable process will be executed by the CPU next.  Each process has an associated scheduling policy and a static scheduling priority, sched_priority</p>
<p>Processes scheduled under one of the real-time policies (SCHED_FIFO, SCHED_RR) have a sched_priority value in the <strong>range 1 (low) to 99 (high)</strong>.  (As the numbers imply, real-time processes always have higher priority than normal processes.)   The following "real-time" policies are also supported, for special time-critical applications that need precise control over the way in which runnable processes are selected for execution:</p>
<p>Currently, Linux supports the following "normal" (i.e., non-real-time) scheduling policies:</p>
<dl>
<dt><strong>SCHED_OTHER</strong>: Default Linux time-sharing scheduling</dt><dd>The standard round-robin time-sharing policy</dd><dt><strong>SCHED_BATCH</strong>: Scheduling batch processes</dt><dd>This policy is useful for workloads that are non-interactive, but do not want to lower their nice value, and for workloads that want a deterministic scheduling policy without interactivity causing extra preemptions (between the workload's tasks).</dd>
<dt><strong>SCHED_IDLE</strong>: Scheduling very low priority jobs</dt>
<dd>This policy is intended for running jobs at extremely low priority (lower even than a +19 nice value with the SCHED_OTHER or SCHED_BATCH policies)</dd>
<dt><strong>SCHED_FIFO</strong>: First In-First Out scheduling</dt><dd>A first-in, first-out policy</dd>
<dt><strong>SCHED_RR</strong>: Round Robin scheduling</dt><dd>A round-robin policy.</dd>
</dl>

<p><a id="scheduling-classes" name="scheduling-classes"></a></p><h3>Scheduling Classes</h3>
<dl>
<dt><code>IOPRIO_CLASS_RT</code></dt>
<dd>This is the realtime io class. The RT scheduling class is given first access to the disk, regardless of what else is going on in the system. Thus the RT class needs to be used with some care, as it can starve other processes. As with the best effort class, 8 priority levels are defined denoting how big a time slice a given process will receive on each scheduling window.  This scheduling class is given higher priority than any other in the system, processes from this class are given first access to the disk every time. Thus it needs to be used with some care, one io RT process can starve the entire system. Within the RT class, there are 8 levels of class data that determine exactly how much time this process needs the disk for on each service. In the future this might change to be more directly mappable to performance, by passing in a wanted data rate instead.</dd>
<dt><code>IOPRIO_CLASS_BE</code></dt>
<dd>This is the best-effort scheduling class, which is the default for any process that hasn't set a specific io priority. This is the default scheduling class for any process that hasn't asked for a specific io priority. Programs inherit the CPU nice setting for io priorities. This class takes a priority argument from 0-7, with lower number being higher priority. Programs running at the same best effort priority are served in a round-robin fashion.  The class data determines how much io bandwidth the process will get, it's directly mappable to the cpu nice levels just more coarsely implemented. 0 is the highest BE prio level, 7 is the lowest. The mapping between cpu nice level and io nice level is determined as: io_nice = (cpu_nice + 20) / 5.</dd>
<dt><code>IOPRIO_CLASS_IDLE</code></dt>
<dd>This is the idle scheduling class, processes running at this level only get io time when no one else needs the disk. A program running with idle io priority will only get disk time when no other program has asked for disk io for a defined grace period. The impact of idle io processes on normal system activity should be zero. This scheduling class does not take a priority argument.    The idle class has no class data, since it doesn't really apply here.</dd>
</dl>








<p><a id="ionice-tool" name="ionice-tool"></a></p><h3>ionice</h3>
<p>ionice - get/set program io scheduling class and priority.  This program sets the io scheduling class and priority for a program.  Since v3 (aka CFQ Time Sliced) CFQ implements I/O nice levels similar to those of CPU scheduling. These nice levels are grouped in three scheduling classes each one containing one or more priority levels:</p>

<p><a id="ionice-usage" name="ionice-usage"></a></p><h4>ionice usage</h4>
<p>If no arguments or just -p is given, ionice will query the current io scheduling class and priority for that process.</p>
<pre>ionice [-c] [-n] [-p] [COMMAND [ARG...]]</pre>
<ul>
<li><strong>-c</strong> - The scheduling class. 1 for real time, 2 for best-effort, 3 for idle.</li>
<li><strong>-n</strong> - The scheduling class data. This defines the class data, if the class accepts an argument. For real time and best-effort, 0-7 is valid data.</li>
<li><strong>-p</strong> - Pass in a process pid to change an already running process. If this argument is not given, ionice will run the listed program with the given parameters.</li>
</ul>

<p><a id="ionice-examples" name="ionice-examples"></a></p><h4>ionice Examples</h4>
<p>Sets process with PID 89 as an idle io process.</p>
<pre>ionice -c3 -p89</pre>
<p>Runs 'bash' as a best-effort program with highest priority.</p>
<pre>ionice -c2 -n0 bash</pre>
<p>Returns the class and priority of the process with PID 89</p>
<pre>ionice -p89</pre>

<blockquote cite="http://gaarai.com/2009/03/06/multitasking-from-the-linux-command-line-plus-process-prioritization/">
<p><p>With the ionice command, you can set the IO priority for a process to one of three classes: Idle (3), Best Effort (2), and Real Time (1). The Idle class means that the process will only be able to read and write to the disk when all other processes are not using the disk. The Best Effort class is the default and has eight different priority levels from 0 (top priority) to 7 (lowest priority). The Real Time class results in the process having first access to the disk irregardless of other process and should never be used unless you know what you are doing.</p>
<p>If we wish to run the updatedb process in the background with an Idle IO class priority, we can run the following:</p>
<pre>$ sudo date
$ sudo updatedb &amp;
[1] 16324
$ sudo ionice -c3 -p16324</pre>
<p>If we’d rather just lower the Best Effort class priority (defaults to 4) for the command so the process isn’t limited to idle IO periods, we can run the following:</p>
<pre>$ sudo date
$ sudo updatedb &amp;
[1] 16324
$ sudo ionice -c2 -n7 -p16324</pre>
<p>Again, the Real Time class should not be used as it can prevent you from being able to interact with your system.</p>
<p>You may wonder where you can get the process ID if you don’t know it, can’t remember it, or didn’t start the process (an automatted script may have launched it). You can find process IDs with the ps command.</p>
<p>For example, if I had an updatedb program running in the background, and I wanted to find its process ID, I can run the following:</p>
<pre>$ ps -C updatedb
PID TTY TIME CMD
4234 ? 00:00:42 updatedb</pre>
<p>This tells me that the process’ process ID (PID) is 4234.</p></p>
</blockquote>





<p><a id="iostat-tool" name="iostat-tool"></a></p><h3>iostat</h3>
<p><a id="iostat-usage" name="iostat-usage"></a></p><h4>iostat Usage</h4>
<pre>iostat [ -c ] [ -d ] [ -N ] [ -n ] [ -h ] [ -k | -m ] [ -t ] [ -V ] [ -x ] [ -z ] [ &lt;device&gt; [...] | ALL ] [ -p [ &lt;device&gt; [,...] | ALL ] ] [ &lt;interval&gt; [ &lt;count&gt; ] ]
&nbsp;
-c     The -c option is exclusive of the -d option and displays only the CPU usage report.
-d     The -d option is exclusive of the -c option and displays only the device utilization report.
-k     Display statistics in kilobytes per second instead of blocks per second.  Data displayed are valid only with kernels 2.4 and newer.
-m     Display statistics in megabytes per second instead of blocks or kilobytes per second.  Data displayed are valid only with kernels 2.4 and newer.
-n     Displays the NFS-directory statistic.  Data displayed are valid only with kernels 2.6.17 and newer.  This option is exclusive ot the -x option.
-h     Display the NFS report more human readable.
-p [ { device | ALL } ]   The  -p  option  is  exclusive  of  the -x option and displays statistics for block devices and all their partitions that are used by the system.
-t     Print the time for each report displayed.
-x     Display extended statistics.</pre>

<p><a id="iostat-examples" name="iostat-examples"></a></p><h4>iostat Examples</h4>
<pre>iostat -p ALL 2 1000
avg-cpu:  %user   %nice    %sys %iowait   %idle
            8.34    0.08    1.26    2.27   88.05</pre>
<p>Display a single history since boot report for all CPU and Devices.</p>
<pre>$ iostat</pre>
<p>Display a continuous device report at two second intervals.</p>
<pre>$ iostat -d 2</pre>
<p>Display six reports at two second intervals for all devices.</p>
<pre>$ iostat -d 2 6</pre>
<p>Display six reports of extended statistics at two second intervals for devices hda and hdb.</p>
<pre>$ iostat -x hda hdb 2 6</pre>
<p>Display six reports at two second intervals for device sda and all its partitions (sda1, etc.)</p>
<pre>$ iostat -p sda 2 6</pre>






<p><a id="schedule-utils" name="schedule-utils"></a></p><h2>Schedule Utils</h2>
<p>These are the Linux scheduler utilities - schedutils for short.  These programs take advantage of the scheduler family of syscalls that Linux implements across various kernels.  These system calls implement interfaces for scheduler-related parameters such as CPU affinity and real-time attributes.  The standard UNIX utilities do not provide support for these interfaces -- thus this package.</p>
<p>The programs that are included in this package are chrt and taskset.  Together with nice and renice (not included), they allow full control of process scheduling parameters.  Suggestions for related utilities are welcome, although it is believed (barring new interfaces) that all scheduling interfaces are covered.</p>
<p>I've found that quite a few servers do not have this package installed, indicating to you that they might not know what they are doing.  Here is how you can install this incredible package, for non-root users.  Root users know how to do this, or they shouldn't be root.  Download and install in 1 line provided you have curl.  Or just use the following commands.</p>
<pre>mkdir -pv $HOME/{dist,source,bin,share/man/man1} &amp;&amp; cd ~/dist &amp;&amp; curl -O http://ftp.de.debian.org/debian/pool/main/s/schedutils/schedutils_1.5.0.orig.tar.gz &amp;&amp; cd ~/source &amp;&amp; tar -xvzf ~/dist/sch*z &amp;&amp; cd sch* &amp;&amp; sed -i -e &#039;s,= /usr/local,=${HOME},g&#039; Makefile &amp;&amp; make &amp;&amp; make install &amp;&amp; make installdoc</pre>
<pre>mkdir -pv $HOME/{dist,source,bin,share/man/man1}
cd ~/dist &amp;&amp; curl -O http://ftp.de.debian.org/debian/pool/main/s/schedutils/schedutils_1.5.0.orig.tar.gz
cd ~/source &amp;&amp; tar -xvzf ~/dist/schedutils_1.5.0.orig.tar.gz
cd ~/source/schedutils-1.5.0 &amp;&amp; sed -i -e &#039;s,= /usr/local,=${HOME},g&#039; Makefile
make || make -d &amp;&amp; make install || make install -d &amp;&amp; make installdoc || make installdoc -d</pre>


<p><a id="taskset-tool" name="taskset-tool"></a></p><h3>taskset</h3>
<p>Taskset  is  used to set or retrieve the CPU affinity of a running process given its PID or to launch a new COMMAND with a given CPU affinity.  CPU affinity is a scheduler property that "bonds" a process to a given set of CPUs on the system.  The Linux scheduler will honor the given CPU affinity and the process will not run on any other CPUs.  Note that the Linux scheduler also supports natural CPU affinity: the scheduler attempts to keep processes on the same CPU as long as practical for performance reasons.  Therefore, forcing a specific CPU affinity is useful only in certain applications.</p>
<p>The  CPU  affinity is represented as a bitmask, with the lowest order bit corresponding to the first logical CPU and the highest order bit corresponding to the last logical CPU.  Not all CPUs may exist on a given system but a mask may specify more CPUs than are present.  A retrieved mask will reflect only the bits that correspond to CPUs physically on the system.  If an invalid mask is given (i.e., one that corresponds to no valid CPUs on the current system) an error is returned.  A user must possess CAP_SYS_NICE to change the CPU affinity of a process.  Any user can retrieve the affinity mask.</p>

<p><a id="taskset-usage" name="taskset-usage"></a></p><h4>taskset Usage</h4>
<pre>taskset [options] [mask | cpu-list] [pid | cmd [args...]]
&nbsp;
-p, --pid            operate on existing given pid
-c, --cpu-list     display and specify cpus in list format</pre>

<p><a id="taskset-examples" name="taskset-examples"></a></p><h4>taskset-examples</h4>
<p>The default behavior is to run a new command:</p>
 <pre>$ taskset 03 sshd -b 1024</pre>
<p>You can retrieve the mask of an existing task or set it:</p>
<pre>$ taskset -p 700
$ taskset -p 03 700</pre>
<p>List format uses a comma-separated list instead of a mask:</p>
<pre>$ taskset -pc 0,3,7-11 700</pre>




<p><a id="chrt-tool" name="chrt-tool"></a></p><h3>chrt</h3>
<p><code>chrt</code> sets or retrieves the real-time scheduling attributes of an existing PID or runs COMMAND with the given attributes.  Both policy (one of <code>SCHED_FIFO</code>, <code>SCHED_RR</code>, or <code>SCHED_OTHER</code>) and priority can be set and retrieved.  A user must possess CAP_SYS_NICE to change the scheduling attributes of a process.  Any user can retrieve the scheduling information.</p>

<p><a id="chrt-usage" name="chrt-usage"></a></p><h4>chrt Usage</h4>
<pre>chrt [options] [prio] [pid | cmd [args...]]
&nbsp;
-p, --pid operate on an existing PID and do not launch a new task
-f, --fifo set scheduling policy to SCHED_FIFO
-m, --max show minimum and maximum valid priorities, then exit
-o, --other set policy scheduling policy to SCHED_OTHER
-r, --rr set scheduling policy to SCHED_RR (the default)</pre>

<p><a id="chrt-examples" name="chrt-examples"></a></p><h4>chrt Examples</h4>
<p>The default behavior is to run a new command:   <code>chrt [prio] -- [command] [arguments]</code></p>
<p>You can also retrieve the real-time attributes of an existing task:</p>
<pre>chrt -p [pid]</pre>
<p>Or set them:</p>
<pre>chrt -p [prio] [pid]</pre>













<p><a id="ulimit-tool" name="ulimit-tool"></a></p><h2>ulimit - get and set user limits</h2>
<p>Ulimit provides control over the resources available to processes started by the shell, on systems that allow such control. One can set the resource limits of the shell using the built-in ulimit command.  The shell's resource limits are inherited by the processes that it creates to execute commands.</p>

<p><a id="ulimit-usage" name="ulimit-usage"></a></p><h4>ulimit Usage</h4>
<pre>ulimit [-SHacdfilmnpqstuvx] [limit]</pre>
<dl>
<dt>-S</dt><dd>use the `soft' resource limit</dd>
<dt>-H</dt><dd>use the `hard' resource limit</dd>
<dt>-a</dt><dd>all current limits are reported</dd>
<dt>-c</dt><dd>the maximum size of core files created</dd>
<dt>-d</dt><dd>the maximum size of a process's data segment</dd>
<dt>-f</dt><dd>the maximum size of files created by the shell</dd>
<dt>-l</dt><dd>the maximum size a process may lock into memory</dd>
<dt>-m</dt><dd>the maximum resident set size</dd>
<dt>-n</dt><dd>the maximum number of open file descriptors</dd>
<dt>-p</dt><dd>the pipe buffer size</dd>
<dt>-s</dt><dd>the maximum stack size</dd>
<dt>-t</dt><dd>the maximum amount of cpu time in seconds</dd>
<dt>-u</dt><dd>the maximum number of user processes</dd>
<dt>-v</dt><dd>the size of virtual memory</dd>
</dl>
<p>If LIMIT is given, it is the new value of the specified resource; the special LIMIT values `soft', `hard', and `unlimited' stand for the current soft limit, the current hard limit, and no limit, respectively.  Otherwise, the current value of the specified resource is printed.  If no option is given, then -f is assumed.  Values are in 1024-byte increments, except for -t, which is in seconds, -p, which is in increments of 512 bytes, and -u, which is an unscaled number of processes.</p>
<dl>
<dt>RLIMIT_AS</dt>
<dd>The maximum size of the process's virtual memory (address space) in bytes.  This limit affects calls to brk(2), mmap(2) and mremap(2), which fail with the error ENOMEM upon exceeding this limit.  Also automatic stack expansion will fail (and generate a SIGSEGV that kills the process if no alternate stack has been made available via sigaltstack(2)).  Since the value is a long, on machines with a 32-bit long either this limit is at most 2 GiB, or this resource is unlimited.</dd>
<dt>RLIMIT_CORE</dt>
<dd>Maximum size of core file.  When 0 no core dump files are created. When non-zero, larger dumps are truncated to this size.</dd>
<dt>RLIMIT_CPU CPU</dt>
<dd>time limit in seconds.  When the process reaches the soft limit, it is sent a SIGXCPU signal.  The default action for this signal is to terminate the process.  However, the signal can be caught, and the handler can return control to the main program.  If the process continues to consume CPU time, it will be sent SIGXCPU once per second until the hard limit is reached, at which time it is sent SIGKILL. (This latter point describes Linux 2.2 through 2.6 behavior. Implementations vary in how they treat processes which continue to consume CPU time after reaching the soft limit.  Portable applications that need to catch this signal should perform an orderly termination upon first receipt of SIGXCPU.)</dd>
<dt>RLIMIT_DATA</dt>
<dd>The maximum size of the process's data segment (initialized data, uninitialized data, and heap).  This limit affects calls to brk(2) and sbrk(2), which fail with the error ENOMEM upon encountering the soft limit of this resource.</dd>
<dt>RLIMIT_FSIZE</dt>
<dd>The maximum size of files that the process may create.  Attempts to extend a file beyond this limit result in delivery of a SIGXFSZ signal. By default, this signal terminates a process, but a process can catch this signal instead, in which case the relevant system call (e.g., write(2), truncate(2)) fails with the error EFBIG.</dd>
<dt>RLIMIT_LOCKS</dt>
<dd>(Early Linux 2.4 only) A limit on the combined number of flock(2) locks and fcntl(2) leases that this process may establish.</dd>
<dt>RLIMIT_MEMLOCK</dt>
<dd>The maximum number of bytes of memory that may be locked into RAM.  In effect this limit is rounded down to the nearest multiple of the system page size.  This limit affects mlock(2) and mlockall(2) and the mmap(2) MAP_LOCKED operation.  Since Linux 2.6.9 it also affects the shmctl(2) SHM_LOCK operation, where it sets a maximum on the total bytes in shared memory segments (see shmget(2)) that may be locked by the real user ID of the calling process.  The shmctl(2) SHM_LOCK locks are accounted for separately from the per-process memory locks established by mlock(2), mlockall(2), and mmap(2) MAP_LOCKED; a process can lock bytes up to this limit in each of these two categories.  In Linux kernels before 2.6.9, this limit controlled the amount of memory that could be locked by a privileged process.  Since Linux 2.6.9, no limits are placed on the amount of memory that a privileged process may lock, and this limit instead governs the amount of memory that an unprivileged process may lock.</dd>
<dt>RLIMIT_MSGQUEUE</dt>
<dd>(Since Linux 2.6.8) Specifies the limit on the number of bytes that can be allocated for POSIX message queues for the real user ID of the calling process.  This limit is enforced for mq_open(3).  Each message queue that the user creates counts (until it is removed) against this limit according to the formula:  <code>bytes = attr.mq_maxmsg * sizeof(struct msg_msg *) +             attr.mq_maxmsg * attr.mq_msgsize</code> where attr is the mq_attr structure specified as the fourth argument to mq_open(3).  The first addend in the formula, which includes sizeof(struct msg_msg *) (4 bytes on Linux/i386), ensures that the user cannot create an unlimited number of zero-length messages (such messages nevertheless each consume some system memory for bookkeeping overhead).</dd>
<dt>RLIMIT_NICE</dt>
<dd>(since Linux 2.6.12, but see BUGS below) Specifies a ceiling to which the process's nice value can be raised using setpriority(2) or nice(2).  The actual ceiling for the nice value is calculated as 20 - rlim_cur.  (This strangeness occurs because negative numbers cannot be specified as resource limit values, since they typically have special meanings.  For example, RLIM_INFINITY typically is the same as -1.)</dd>
<dt>RLIMIT_NOFILE</dt>
<dd>Specifies a value one greater than the maximum file descriptor number that can be opened by this process.  Attempts (open(2), pipe(2), dup(2), etc.)  to exceed this limit yield the error EMFILE. (Historically, this limit was named RLIMIT_OFILE on BSD.)</dd>
<dt>RLIMIT_NPROC</dt>
<dd>The maximum number of processes (or, more precisely on Linux, threads) that can be created for the real user ID of the calling process.  Upon encountering this limit, fork(2) fails with the error EAGAIN.</dd>
<dt>RLIMIT_RSS</dt>
<dd>Specifies the limit (in pages) of the process's resident set (the number of virtual pages resident in RAM).  This limit only has effect in Linux 2.4.x, x < 30, and there only affects calls to madvise(2) specifying MADV_WILLNEED.</dd>
<dt>RLIMIT_RTPRIO</dt>
<dd>(Since Linux 2.6.12, but see BUGS) Specifies a ceiling on the real-time priority that may be set for this process using sched_setscheduler(2) and sched_setparam(2).</dd>
<dt>RLIMIT_RTTIME</dt>
<dd>(Since Linux 2.6.25) Specifies a limit on the amount of CPU time that a process scheduled under a real-time scheduling policy may consume without making a blocking system call.  For the purpose of this limit, each time a process makes a blocking system call, the count of its consumed CPU time is reset to zero.  The CPU time count is not reset if the process continues trying to use the CPU but is preempted, its time slice expires, or it calls sched_yield(2). Upon reaching the soft limit, the process is sent a SIGXCPU signal.  If the process catches or ignores this signal and continues consuming CPU time, then SIGXCPU will be generated once each second until the hard limit is reached, at which point the process is sent a SIGKILL signal.  The intended use of this limit is to stop a runaway real-time process from locking up the system.</dd>
<dt>RLIMIT_SIGPENDING</dt>
<dd>(Since Linux 2.6.8) Specifies the limit on the number of signals that may be queued for the real user ID of the calling process.  Both standard and real-time signals are counted for the purpose of checking this limit.  However, the limit is only enforced for sigqueue(2); it is always possible to use kill(2) to queue one instance of any of the signals that are not already queued to the process.</dd>
<dt>RLIMIT_STACK</dt>
<dd>The maximum size of the process stack, in bytes.  Upon reaching this limit, a SIGSEGV signal is generated.  To handle this signal, a process must employ an alternate signal stack (sigaltstack(2)).</dd>
</dl>

<p><a id="ulimit-examples" name="ulimit-examples"></a></p><h4>ulimit Examples</h4>
<p>Turn off core dumps</p>
<pre>ulimit -S -c 0</pre>








<h2>More Reading</h2>
<ul>
<li>Please see the <a href="http://pagesperso-orange.fr/sebastien.godard/">SYSSTAT Utilities Home for more performance monitoring tools</a> like sar, sadf, mpstat, iostat, pidstat and sa tools.</li>
<li><a href="http://gaarai.com/2009/03/06/multitasking-from-the-linux-command-line-plus-process-prioritization/">Multitasking from the Linux Command Line + Process Prioritization</a></li>
</ul>


<h2>Man Pages</h2>
<ol>
<li><a href="http://www.kernel.org/doc/man-pages/online/pages/man2/sched_setscheduler.2.html">sched_setscheduler</a></li>
<li><a href="http://www.kernel.org/doc/man-pages/online/pages/man7/cpuset.7.html">cpuset</a></li>
<li><a href="http://www.kernel.org/doc/man-pages/online/pages/man7/signal.7.html">signal</a></li>
<li><a href="http://www.kernel.org/doc/man-pages/online/pages/man2/getrlimit.2.html">getrlimit</a></li>
<li><a href="http://www.kernel.org/doc/man-pages/online/pages/man3/ulimit.3.html">ulimit</a></li>
<li><a href="http://www.kernel.org/doc/man-pages/online/pages/man2/ioprio_get.2.html">ioprio_get</a></li>
<li><a href="http://www.kernel.org/doc/man-pages/online/pages/man2/ioprio_set.2.html">ioprio_set</a></li>
</ol>


<h2>Kernel Documentation</h2>
<ul>
<li><a href='http://uploads.askapache.com/2009/08/sched-stats.txt'>information on schedstats (Linux Scheduler Statistics)</a></li>
<li><a href='http://uploads.askapache.com/2009/08/sched-rt-group.txt'>real-time group scheduling</a></li>
<li><a href='http://uploads.askapache.com/2009/08/sched-nice-design.txt'>How and why the scheduler's nice levels are implemented</a></li>
<li><a href='http://uploads.askapache.com/2009/08/sched-domains.txt'>information on scheduling domains</a></li>
<li><a href='http://uploads.askapache.com/2009/08/sched-design-CFS.txt'>goals, design and implementation of the Complete Fair Scheduler</a></li>
</ul>



<h2>Future Discussions:</h2>
<p><a href="http://www.cuddletech.com/blog/pivot/entry.php?id=820">IO Benchmarking: How, Why and With What</a></p><p><a href="http://www.askapache.com/optimize/optimize-nice-ionice.html"></a><a href="http://www.askapache.com/optimize/optimize-nice-ionice.html">Optimizing Servers and Processes for Speed with ionice, nice, ulimit</a> originally appeared on <cite>AskApache.com</cite> </p>]]></content:encoded>
			<wfw:commentRss>http://www.askapache.com/optimize/optimize-nice-ionice.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Make Windows XP Blazingly Fast</title>
		<link>http://www.askapache.com/windows/blazing-fast-xp-speed.html</link>
		<comments>http://www.askapache.com/windows/blazing-fast-xp-speed.html#comments</comments>
		<pubDate>Sat, 27 Jun 2009 05:06:49 +0000</pubDate>
		<dc:creator>AskApache</dc:creator>
				<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://www.askapache.com/?p=2834</guid>
		<description><![CDATA[<p>Here is the basic process that I use to speed up Windows.  A lot of good tips and tricks I've picked up over the past 15+ years of crashing and burning Windows that can transform your PC to be much faster than its ever been.  The process focuses on freeing up RAM/Memory, freeing up your CPU/Processor, and optimizing your Hard Drive for a permanent solution.<br /><br />Make sure to check out the free software I recommend at the end, installing them after this optimization process will keep your machine fast for a long time.</p>]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.askapache.com/windows/blazing-fast-xp-speed.html"></a><a href="http://www.askapache.com/windows/blazing-fast-xp-speed.html"><cite>AskApache.com</cite></a></p><p>I've been using Windows since before "Windows for Workgroups 3.x" and have used most of the Windows releases since, on a wide variety of cheaper than cheap computers and platforms that are slower than slow. I'm always interested in new ways to maximize speed and over the years I've picked up quite a few little tips on how to max out your Windows PC. I am not fond of being forced to use MS, and am not a MS expert, so I hope all you Windows peeps will share your tips with us.. And some of these tips can crash your machine if you don't know what you are doing.</p>

<p class="anote">UPDATE:  Part 2 covers the <a href="http://www.askapache.com/windows/defrag-optimize-speed-xp.html">advanced defragmenting tools and methods</a>.</p>

<p><a id="overview" title="General Ideas and Overview"></a></p><h2>Overview and General Ideas</h2>

<h4>Basic Definitions</h4>
<dl class="sdll">
<dt>CPU - Central Processing Unit</dt><dd>This is what Intel and AMD commercials are about, this chip functions like a calculator, computing all the data.</dd>
<dt>Hard Drive</dt><dd>This is a glorified CD-ROM Disc that is much faster and has a higher capacity than a CD-ROM.  This is where all your files and Operating System is stored on.</dd>
<dt>RAM - Random Access Memory</dt><dd>Data that is frequently accessed is stored in RAM instead of the Hard Drive because RAM is much much faster.</dd>
<dt>Page File / Virtual Memory</dt><dd>This is literally a file that is stored on your Hard Drive and is used as a form of RAM when you run out of real RAM.  Much slower than RAM (because it is located on the hard drive) it is used to store bits of data used by programs.</dd>
</dl>

<h4>Three-pronged attack against the sluggish druggish</h4>
<ol>
<li><h4>Increase RAM/Memory</h4><p>Reducing the amount of RAM that is wasted by unneeded programs, unused device drivers and devices, background services, visual effects, and various other stuff frees up RAM for your needed programs and processes.  The final step of this article details the Cacheman Software that automatically takes care of everything this article doesn't go into (like registry modifications and hidden tweaks)..</p></li>
<li><h4>Optimize Hard Drive Data</h4><p>The attack in order:</p>
<ul><li>Reduce Amount of data on drive by removing unneeded data and configuring optimum settings to prevent buildup in the future.</li>
<li>Configure settings which minimize the amount of disk activity, e.g., reading and writing to disk.</li>
<li>Defragment the data that is left, and setup an automated system to prevent fragmentation in the future.</li></ul></li>
<li><h4>Free Up CPU Time</h4><p>Almost all of the following tips will help to decrease the amount of CPU processing time that is wasted on unneeded processes.</p></li>
</ol>
<hr class="C" />



<h2><strong>Part 1</strong>: Increase and Free Memory/RAM</h2>

<p><a id="performance" title="Configure Performance Options"></a></p><h4>Configure Performance Options</h4>
<p><a class="IFL" href="http://uploads.askapache.com/2009/06/Performance_Options.png"><img src="http://uploads.askapache.com/2009/06/Performance_Options-79x116.png" alt="Performance Settings" title="Performance Settings" width="79" height="116" /></a><strong>Control Panel -> System -> Advanced -> Performance -> Settings</strong><br /><br />If you have massive RAM like I do, <em>best appearance</em> is nice.  To max your speed change to "Adjust for best performance".<br class="C" /></p>

<h4>Change Theme to Classic</h4><p><a class="IFL" href="http://uploads.askapache.com/2009/06/Display_Properties_Themes.png"><img src="http://uploads.askapache.com/2009/06/Display_Properties_Themes-103x115.png" alt="Display Properties Themes" title="Display Properties Themes" width="103" height="115" /></a>The Classic Theme uses less RAM and CPU than the newer XP themes.<br class="C" /></p>

<h4>Fine-Tune Effects</h4><p><a class="IFL" href="http://uploads.askapache.com/2009/06/Display_Properties_Appearance.png"><img src="http://uploads.askapache.com/2009/06/Display_Properties_Appearance-103x115.png" alt="Display Properties Appearance" title="Display Properties Appearance" width=width="103" height="115" /></a><a class="IFL" href="http://uploads.askapache.com/2009/06/Display_Effects.png"><img src="http://uploads.askapache.com/2009/06/Display_Effects-116x88.png" alt="Display Effects" title="Display Effects" width="116" height="88" /></a>Disable all for maximum speed.  I like to only leave ClearType enabled.<br class="C" /></p>

<h4>Color quality and Resolution</h4><p><a class="IFL" href="http://uploads.askapache.com/2009/06/Display_Properties.png"><img src="http://uploads.askapache.com/2009/06/Display_Properties-103x115.png" alt="Display Properties Resolution" title="Display Properties Resolution" width="103" height="115" /></a>To sacrifice quality for speed, change the Color quality to a lower setting, and lower the resolution if you want.<br class="C" /></p>

<h4>Clean up that Desktop!</h4><p>Your desktop is always loaded in RAM, as it is always available to view.  So everything that is ON your desktop is likewise stored in RAM.  This means that every icon located on your desktop, which is actually an icon file, is loaded in RAM.  What I do is instead of a cluttered Desktop always loaded in RAM, I simply create 1 folder called Desktop on my Desktop, and move everything from my desktop to that folder.  That way instead of all those icons taking up memory, now only the single folder icon is taking up RAM.  Not a HUGE impact, but it illustrates what RAM is and how you can stop wasting it.<br class="C" /></p>

<h4>Make Background Solid Color</h4><p><a class="IFL" href="http://uploads.askapache.com/2009/06/Display_Properties_Desktop.png"><img src="http://uploads.askapache.com/2009/06/Display_Properties_Desktop-103x115.png" alt="Display Properties Desktop" title="Display Properties Desktop" width="103" height="115" /></a>By setting the background image of your desktop (and folders if you are using custom folder backgrounds) to none, and instead just using a solid color (like blue) you free up RAM.  If your desktop uses a high-quality background image (like mine) that is a 5MB jpeg image, that effectively wastes 5MB of your RAM.  A solid color background uses none.<br class="C" /></p>
<hr class="C" />


<p><a id="folder_options" title="Optimize Folder Options"></a></p><h4>Optimize Folder Options</h4>
<p><a class="IFL" href="http://uploads.askapache.com/2009/06/Folder_Options.png"><img src="http://uploads.askapache.com/2009/06/Folder_Options-67x116.png" alt="Folder Viewing Options" title="Folder Viewing Options" width="67" height="116" /></a><strong>Open up Explorer/My Computer -> Tools -> Folder Options</strong><br /><br />First change the option to "<em>Use Windows classic folders</em>".  Now goto the View tab and hit the button "<em>Reset all Folders</em>", which will clear your individual folder viewing settings.  Then change the options to the ones I have selected in the image for optimum speed, its up to you which options you don't want to change.  The <em>searching for network folders</em> is a very real cause of slowness.<br class="C" /></p>
<hr class="C" />


<p><a id="page-file" title="Page File and Virtual Memory Usage"></a></p><h4>Page File / Virtual Memory</h4>
<p><a class="IFL" href="http://uploads.askapache.com/2009/06/Performance_Options_Advanced.png"><img src="http://uploads.askapache.com/2009/06/Performance_Options_Advanced-79x116.png" alt="Advanced Performance Options" title="Advanced Performance Options" width="79" height="116" /></a>The optimal way to use a page file is to not use a pagefile and max out your physical RAM.  Next to doing that (which Windows won't let you do anyway, they love pagefiling) the optimal setup is to have the pagefile on a 2nd hard-drive-disk.  The computer can only read/write data to/from the hard drive at a certain speed, and only a certain amount of read/writes can be going on at one time.. Think of it like a pipe.  Having the pagefile.sys on the same disk that Windows and all the Program's are loaded on clogs the pipe and limits flow of data in both directions.<br /><br />Note that moving the page file to a separate partition on the same hard drive would NOT fix this problem or alleviate the bottleneck in any way, so the solution is to get a 2nd hard drive, I personally recommend these 2 <a href="#hard-drive">$49.99 - 320GB x 7500RPM</a> hard-drives that are very reliable.<br class="C" /></p>

<h4>Page File Size</h4>
<p><a class="IFL" href="http://uploads.askapache.com/2009/06/Virtual_Memory.png"><img src="http://uploads.askapache.com/2009/06/Virtual_Memory-90x116.png" alt="Virtual Memory" title="Virtual Memory" width="90" height="116" /></a>The size of your pagefile is up for debate, no clear answer, but I've tried a lot of different configurations over the years and here is what I recommend.  If you have little RAM (less than 1GB), then you should just let Windows control it.  Otherwise use the custom option to set it at a low initial size of 400MB to grow up to 3096MB.  I have 4GB of RAM, so I set it to start at 100MB and grow to 5000MB.  The general rule is to set it to be 1.5x the amount of RAM you have.<br class="C" /></p>


<p><a id="disable-devices" title="Turning Off Unneeded Devices"></a></p><h4>Disable Devices</h4>
<p><a class="IFL" href="http://uploads.askapache.com/2009/06/Device_Manager.png"><img src="http://uploads.askapache.com/2009/06/Device_Manager-92x116.png" alt="Device Manager" title="Device Manager" width="92" height="116" /></a>Disable any devices you never use, like internal modems, firewire ports, floppy drives, etc..  Also disable them in your systems BIOS if you can.<br class="C" /></p>


<h4>Uninstalling Devices</h4><p><a class="IFL" href="http://uploads.askapache.com/2009/06/Device_Manager_Hidden_Drives.png"><img src="http://uploads.askapache.com/2009/06/Device_Manager_Hidden_Drives-116x98.png" alt="Device Manager Hidden Devices" title="Device Manager Hidden Devices" width="116" height="98" /></a>If you have devices that you used on your computer in the past but don't anymore, they are still being loaded up by Windows and at the very least hogging some resources.  So go through and uninstall them..  (You have to select View -> Show hidden devices).. If you plug them back in they will be re-installed with the "Found new hardware" wizard.<br class="C" /></p>
<hr class="C" />


<h4>Disable Fast User Switching</h4>
<p><a class="IFL" href="http://uploads.askapache.com/2009/06/User_Accounts_Settings.png"><img src="http://uploads.askapache.com/2009/06/User_Accounts_Settings-116x104.png" alt="User Accounts Settings" title="User Accounts Settings" width="116" height="104" /></a><strong>Control Panel -> Users -> Change the way users log on</strong><br /><br />Make sure you disable fast-user-switching unless you absolutely must have it.  I've found it to be a cool feature if you are a basic computer user not installing programs or tweaking settings.. Nut it can create big problems if you use your computer for all sorts of *advanced* stuff (advanced for Windows)...  Plus disabling it will have some speed improvements.<br class="C" /></p>
<hr class="C" />


<p><a id="services" title="Optimizing Services"></a></p><h4>Optimizing Services</h4>
<p><a class="IFL" href="http://uploads.askapache.com/2009/06/Disabled_Services.png"><img src="http://uploads.askapache.com/2009/06/Disabled_Services-116x95.png" alt="Disabled Services" title="Disabled Services" width="116" height="95" /></a><a class="IFL" href="http://uploads.askapache.com/2009/06/Manual_Services.png"><img src="http://uploads.askapache.com/2009/06/Manual_Services-34x116.png" alt="XP Manual Services" title="XP Manual Services" width="34" height="116" /></a><strong>Start -> Run -> services.msc</strong><br /><br />First make sure you export your current services to a backup file before you begin.  There are a number of informative articles about this topic on the web.<br class="C" /></p>
<hr class="C" />


<p><a id="network-protocols" title="Removing Extraneous Network Protocols"></a></p><h4>Removing Unneeded Network Protocols</h4>
<p><a class="IFL" href="http://uploads.askapache.com/2009/06/Connection_Properties.png"><img src="http://uploads.askapache.com/2009/06/Connection_Properties-94x116.png" alt="Connection Properties" title="Connection Properties" width="94" height="116" /></a>This actually helps a lot and can have a significant impact on your computer speed, much more so than any impact on network speed improvements.  These protocols require all sorts of RAM and are kept loaded.  They also represent a security risk as it provides another process to be attacked.<br class="C" /></p>
<hr class="C" />








<h2><strong>Part 2</strong>: Optimize Hard Drive and Data</h2>

<p><a id="hard-drive" title="External Hard Drives"></a></p><h4>Recommended Hard Drives</h4>
<p>These are the cheapest price's for these tried and true hard-drives.  I love TigerDirect and recommend you check them out.</p>
<ol><li><strong>$49.99</strong> <a href="http://click.linksynergy.com/fs-bin/click?id=HqZ8LNuf6*4&amp;offerid=102327.4233835&amp;type=2&amp;subid=0">Seagate Barracuda 320GB</a> - 7200RPM</li>
<li><strong>$49.99</strong> <a href="http://click.linksynergy.com/fs-bin/click?id=HqZ8LNuf6*4&amp;offerid=102327.3179250&amp;type=2&amp;subid=0">WD3200 Caviar Blue 320GB</a> - 7200RPM</li>
<li><strong>$59.99</strong> <a href="http://click.linksynergy.com/fs-bin/click?id=HqZ8LNuf6*4&amp;offerid=102327.2795126&amp;type=2&amp;subid=0">WD5000 Caviar Blue 500GB</a> - 7200RPM</li>
<li><strong>$229.99</strong> <a href="http://click.linksynergy.com/fs-bin/click?id=HqZ8LNuf6*4&amp;offerid=102327.4177125&amp;type=2&amp;subid=0">WD VelociRaptor 320GB</a> - 10,000RPM, FAST!</li>
</ol>


<p><a id="file-system" title="File System Tweaks"></a></p><h4>File System Tweaks</h4>
<p><a class="IFL" href="http://uploads.askapache.com/2009/06/Computer-Management-Console.png"><img src="http://uploads.askapache.com/2009/06/Computer-Management-Console-116x76.png" alt="Computer Management Console" title="Computer Management Console" width="116" height="76" /></a><strong>Start -> Run -> compmgmt.msc</strong><br />Check the structure and properties of your disks and partitions to see if anything is out of place.  Make sure file systems are using NTFS.  But some partitions like dell utility partition, or a partition shared by linux/mac/windows on dual-boot systems may be fat or fat32.  To convert fat-based to NTFS, defragment MFT, resize NTFS clusters, etc.. you have to use a third part product.  I personally use Norton Partition Magic, Paragon Partition Manager, and <a href="http://click.linksynergy.com/fs-bin/click?id=HqZ8LNuf6*4&amp;offerid=102327.4395951&amp;type=2&amp;subid=0" >Acronis Disk Director Suite</a> (plus 20 other various tools).<br class="C" /></p>
<hr class="C" />


<h4>2nd Hard Drive</h4><p>*Advanced*<br />If your lucky or smart enough to have more than one hard drive disk installed, in addition to moving your pagefile to that 2nd hard-drive you should setup the hard drive with at least 2 partitions first.  Say you install one of those <a href="#hard-drive">320GB hard drives I recommend</a>... Here's how I set the partitions on the 2nd hard-drive.</p>
<ol>
<li>6.5GB - S: [SWAP] - First partition is fastest area on drive, this partition is ONLY for the pagefile.  Size is 1.5x the max size of your pagefile setting, or 1.5x the amount of RAM.</li>
<li>13.5GB - 2nd partition is not given a drive letter, instead it is mounted as both C:\TMP and C:\TEMP folders.. similarly to optimizing the pagefile, Windows and Programs use the TMP and TEMP folders A LOT so this will really speed up any installations and a lot of Windows itself.  *very tricky*</li>
<li>300GB - This is also mounted instead of given a drive letter, mounted as "C:\Documents and Settings" which is where all your settings and user files (Desktop, My Documents) are stored. *very tricky*</li>
</ol>
<p>Setting up the TMP and "Documents and Settings" folders that way is NOT for beginners, its advanced and dangerous if you do it wrong.  But definately has one of the biggest noticeable speed benefits.</p>
<hr class="C" />


<p><a id="remove-programs" title="Removing Programs"></a></p><h4>Remove Unneccessary Programs</h4>
<p><a class="IFL" href="http://uploads.askapache.com/2009/06/Add_Remove_Programs.png"><img src="http://uploads.askapache.com/2009/06/Add_Remove_Programs-116x115.png" alt="Add Remove Programs" title="Add Remove Programs" width="116" height="115" /></a><br /><strong>Control Panel -> Add or Remove Programs</strong><br /><br />Remove all programs that you are <strong>positive</strong> you don't need anymore, the more you remove, the better.  Microsoft provides a free tool that is simple and helpful when removing programs.  Download it at: <a href="http://support.microsoft.com/kb/290301/">Windows Installer CleanUp Utility</a><br class="C" /></p>

<h4>Remove Windows Components</h4>
<p><a class="IFL" href="http://uploads.askapache.com/2009/06/Windows_Components_Wizard.png"><img src="http://uploads.askapache.com/2009/06/Windows_Components_Wizard-116x90.png" alt="Windows Components Wizard" title="Windows Components Wizard" width="116" height="90" /></a>The only main categories I need are <em>Internet Explorer</em>, <em>Windows Media Player</em>, <em>Update Root Certificates</em>, and <em>Accessories and Utilities</em><br class="C" /></p>
<p><a class="IFL" href="http://uploads.askapache.com/2009/06/Windows_Components_Accessories_Utilities.png"><img src="http://uploads.askapache.com/2009/06/Windows_Components_Accessories_Utilities-116x74.png" alt="Windows Components Accessories Utilities" title="Windows Components Accessories Utilities" width="116" height="74" /></a>I also remove the <em>Games</em> category which is a subcategory of <em>Accessories and Utilities</em>.<br class="C" /></p>
<hr class="C" />


<p><a id="system-restore" title="System Restore Optimization"></a></p><h4>System Restore Optimization</h4>
<p><a class="IFL" href="http://uploads.askapache.com/2009/06/System_Properties_System_Restore.png"><img src="http://uploads.askapache.com/2009/06/System_Properties_System_Restore-100x115.png" alt="System Restore Settings" title="System Restore Settings" width="100" height="115" /></a>Turn off system restore on any drives that are not crucial... So if you have a 2nd hard-drive that is used for pagefile and temp file storage, turn it off.  And you should make sure the settings aren't too generous, I usually never go higher than 10GB.<br class="C" /></p>
<hr class="C" />


<p><a id="recycle-bin" title="Recycle Bin Settings"></a></p><h4>Recycle Bin Settings</h4>
<p><a class="IFL" href="http://uploads.askapache.com/2009/06/Recycle-Bin-Properties.png"><img src="http://uploads.askapache.com/2009/06/Recycle-Bin-Properties-116x96.png" alt="Recycle Bin Properties" title="Recycle Bin Properties" width="116" height="96" /></a>Keep this setting to a low value, try not to delete stuff you will need later.  I personally disable the Recycle Bin completely.. but I come from a unix background so I have no issues with misplacing files.<br class="C" /></p>
<hr class="C" />


<p><a id="remove-fonts" title="Remove Extra Fonts"></a></p><h4>Remove Unneccessary Fonts</h4>
<p><a class="IFL" href="http://uploads.askapache.com/2009/06/Fonts.png"><img src="http://uploads.askapache.com/2009/06/Fonts-115x99.png" alt="Make Windows XP Blazingly Fast" title="Fonts" width="115" height="99" /></a><code>C:\Windows\Fonts</code><br /><br />Fonts are loaded up by default by Windows and every time you load a program like Photoshop, Microsoft Word, Outlook, etc., so moving any you never use out of the <code>C:\Windows\Fonts</code> folder saves RAM and CPU and HD space.  This is a bit hairy but I sort by size and then check out how long its been since the font has been accessed by looking at the file attributes.  The less fonts you have, the faster your computer, but there is obviously a trade-off.  You can move all fonts except for a few basic ones included with Windows to a backup folder instead of deleting them, then reboot and if your font is messed up then move some of the fonts from the backup folder back and try again.<br class="C" /></p>
<hr class="C" />


<p><a id="clean-prefetch" title="Clean Prefetch Files"></a></p><h4>Prefetch Cleaning</h4>
<p>Delete the contents of the <code>C:\WINDOWS\Prefetch</code> folder and restart the computer.  Its good to empty this folder and reboot after major upgrades or about once a month.</p>
<hr class="C" />







<h2><strong>Part 3</strong>: Finishing the Optimization Process</h2>
<p>These 3 tips will have the biggest speed impact for 99% of you, this is some really good stuff.</p>

<p><a id="disk-cleanup" title="Disk Cleanup Wizard"></a></p><h4>Disk Cleanup</h4>
<p><a class="IFL" href="http://uploads.askapache.com/2009/06/Disk_Cleanup.png"><img src="http://uploads.askapache.com/2009/06/Disk_Cleanup-97x116.png" alt="Disk Cleanup" title="Disk Cleanup" width="97" height="116" /></a><a class="IFL" href="http://uploads.askapache.com/2009/06/Disk_Cleanup_More_Options.png"><img src="http://uploads.askapache.com/2009/06/Disk_Cleanup_More_Options-97x116.png" alt="Disk Cleanup More Options" title="Disk Cleanup More Options" width="97" height="116" /></a><strong>Start -> Run -> <code>%SystemRoot%\system32\cleanmgr.exe</code></strong><br /><br />This wizard is a very useful tool that combines several cleanup tools in one location.  It also provides a way to clean up all past restore points save on your disk except the most recent one.<br class="C" /></p>
<hr class="C" />


<p><a id="defragment" title="Defragmenting with SmartDefrag"></a></p><h4>Defragmenting with SmartDefrag</h4>
<p><a class="IFL" href="http://uploads.askapache.com/2009/06/Smart_Defrag.jpg"><img src="http://uploads.askapache.com/2009/06/Smart_Defrag.jpg" alt="Smart Defrag" title="Smart Defrag" width="120" height="120" /></a><a class="IFL" href="http://uploads.askapache.com/2009/06/Smart_Defrag_SS.png"><img src="http://uploads.askapache.com/2009/06/Smart_Defrag_SS-116x87.png" alt="Smart Defrag ScreenShot" title="Smart Defrag ScreenShot" width="116" height="87" /></a>The World’s Most Efficient Defragmenter<br /><br />What’s the primary cause of slow/unstable PC performance? It’s disk fragmentation. Smart Defrag helps defragment your hard drives more efficiently than any other product on the market –– free or not.<br /><br />This powerful, award-winning free defragmenter is 100% safe and clean with no adware, spyware, or viruses.<br /><br /><a href="http://www.iobit.com/iobitsmartdefrag.html?Str=download">Download Smart Defrag</a><br class="C" /></p>
<hr class="C" />


<p><a id="cacheman" title="Cacheman XP Optimization"></a></p><h4>Cacheman XP Optimization</h4>
<p><a class="IFL" href="http://uploads.askapache.com/2009/06/Cacheman_XP_SS.jpg"><img src="http://uploads.askapache.com/2009/06/Cacheman_XP_SS-116x82.jpg" alt="Cacheman XP ScreenShot" title="Cacheman XP ScreenShot" width="116" height="82" /></a>Cacheman is a Windows software designed to speed up your computer by optimizing several caches, managing RAM and fine tuning a number of system settings. Auto-Optimization makes it suitable for novice and intermediate users yet it is also powerful and versatile enough for computer experts. Backups of settings ensure that all user modifications can be reversed with a single click.<br /><br /><a href="http://cacheman.outertech.com/index.php?_charisma_page=product&amp;id=2">Go Get It</a><br class="C" /></p>
<hr class="C" />









<h2>Software Recommendations</h2>

<h3>From the Sysinternals Suite</h3>
<h4><a href="http://technet.microsoft.com/en-us/sysinternals/bb963902.aspx">Autoruns</a></h4>
<p>See what programs are configured to startup automatically when your system boots and you login. Autoruns also shows you the full list of Registry and file locations where applications can configure auto-start settings.</p>

<h4><a href="http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx">Process Explorer</a></h4>
<p>Find out what files, registry keys and other objects processes have open, which DLLs they have loaded, and more. This uniquely powerful utility will even show you who owns each process.</p>

<h4><a href="http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx">Process Monitor</a></h4>
<p>Monitor file system, Registry, process, thread and DLL activity in real-time.</p>

<h4><a href="http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx">VMMap</a></h4>
<p>See a breakdown of a process's committed virtual memory types as well as the amount of physical memory (working set) assigned by the operating system to those types. Identify the sources of process memory usage and the memory cost of application features.</p>

<p><a id="tweakui" title="Tweak UI Powertoy"></a></p><h4>Tweak UI Powertoy</h4>
<p>This PowerToy gives you access to system settings that are not exposed in the Windows XP default user interface, including mouse settings, Explorer settings, taskbar settings, and more.<br /><br /><a href="http://www.microsoft.com/windowsxp/downloads/powertoys/xppowertoys.mspx">Go Get It</a><br class="C" /></p>
<hr class="C" /><p><a href="http://www.askapache.com/windows/blazing-fast-xp-speed.html"></a><a href="http://www.askapache.com/windows/blazing-fast-xp-speed.html">Make Windows XP Blazingly Fast</a> originally appeared on <cite>AskApache.com</cite> </p>]]></content:encoded>
			<wfw:commentRss>http://www.askapache.com/windows/blazing-fast-xp-speed.html/feed</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Faster POST and GET Form Submissions&#8230; Shazam</title>
		<link>http://www.askapache.com/php/fsockopen-forms.html</link>
		<comments>http://www.askapache.com/php/fsockopen-forms.html#comments</comments>
		<pubDate>Wed, 13 Feb 2008 02:21:30 +0000</pubDate>
		<dc:creator>AskApache</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.askapache.com/webmaster/fsockopen-forms.html</guid>
		<description><![CDATA[<p><a class="IFL" href='http://uploads.askapache.com/2008/02/snoopy-fsockopen.png' title='Snoopy Fsockopen HTTP Class for PHP'><img src='http://uploads.askapache.com/2008/02/snoopy-fsockopen.thumbnail.png' alt='Snoopy Fsockopen HTTP Class for PHP' /></a>Just a very brief look at speeding up form submission by delegating the processing and bandwidth to your server, not your client.<br class="C" /></p>]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.askapache.com/php/fsockopen-forms.html"></a><a href="http://www.askapache.com/php/fsockopen-forms.html"><cite>AskApache.com</cite></a></p><p><a rel="lb" class="IFL" href='http://uploads.askapache.com/2008/02/snoopy-fsockopen.png' title='Snoopy Fsockopen HTTP Class for PHP'><img src='http://uploads.askapache.com/2008/02/snoopy-fsockopen.thumbnail.png' alt='Snoopy Fsockopen HTTP Class for PHP' title="snoopy fsockopen.thumbnail php" /></a>If you have ever developed an online form before that has to process the requests you know that sometimes this processing can result in an unacceptable wait time for your site users.<br class="C" /></p>
<p>An example is when logging into some online site like gmail, a forum, a wiki, etc.  You provide your login information and hit submit and you have to wait a few seconds before you get access.</p>
<p>One of the most annoying instances of this is when I see a screen upon form submission that tells me it is redirecting me, but if it fails, after 5 seconds I am free to click on the continue link.  <strong>Screw that.</strong> :)</p>


<h2>Why The Wait?</h2>
<p>Basically it comes down to server-side processing.  Meaning its THEM, not YOU.  The way a form works is it sends the values entered into the form to a URI defined by the <code>action</code> attribute.  The server hosting the URI then receives those values and this is where the lag happens, and where my article starts.</p>


<h2>Avoid Form Processing Bottleneck</h2>
<p>So what types of processing is the server doing for the form?  That is the first thing to figure out.</p>
<p>If the form is comparing the MD5 hashes against the database record for your username in order to log you in to the application and set cookies, then you can't really speed that up the way I will describe.</p>
<p>Ok, but what if your form does something just as common as user-authentication like these:</p>

<ul>
<li>Sending the results of a contact form submission</li>
<li>Updating a database with the values posted by the form</li>
<li>Subscribing to an online mailing list or newsletter</li>
</ul>


<h2>The Trick: Background Requests</h2>
<p>So a common form setup <em>because its just so darn easy</em> is to just move in a linear fashion.  A to B to C to Thank You Page. Blah.</p>
<ol>
<li><strong>form1.php</strong> - ask a user for values <em>like name, email, and a message</em> and send to form2.php</li>
<li><strong>form2.php</strong> -  receives then emails values using <a href="http://phpmailer.codeworxtech.com/">phpmailer</a>, <a href="http://www.swiftmailer.org/">swiftmailer</a></li>
<li><strong>form2.php</strong> -  once the email has been sent successfully, form2.php then displays a "Thank You" page or redirects elsewhere.</li>
</ol>


<h2>Using Background Request</h2>
<p>This is kind of like using AJAX, but this is more for online forms that need to do a little processing server side before outputting back data.  Like Fetching a log file containing information about the video playback choices of your site users, then <a href="http://www.simplethoughtproductions.com/category/simple-stats/">using a RUBY script to process</a> that file and create SVG graphs and html.  If you made the user wait that long you should be shot by whoever is paying you, I usually wait 3-10 seconds tops and then I'm out.</p>

<p class="cnote">So a neat solution to this problem is to use the clients POST request initiate a 2nd script on your server to do the processing.  Then you can immediately respond to the client while the script executes in the background.  Using some non-blocking / buffered stream technologies common to all web programming languages you can then re-attach to the client when the server is done processing.</p>

<h2>PHP fsockopen</h2>
<p>One of the cooler php 4 and 5 functions is fsockopen.  It lets you write data to a socket just like using netcat on bsd.. not quite but its still sweet.  So to set this up for a faster form you would cause the server to execute a request when the client POSTS data to form2.php from form1.php.  So on form2.php you can do almost anything.  Heres an example that makes it easy to <a href="http://us.php.net/manual/en/features.file-upload.php">upload a file to a webserver</a>, this is pretty awesome to be able to do dynamically, and main parts of this code I grabbed from <a href="http://snoopy.sourceforge.net/">Snoopy</a>, though I really dig <a href="http://curl.askapache.com/">libcurl and curl</a>.</p>




<pre>function send_fsockopen_post_multiform($formvars, $formfiles)
{
    settype($formvars, "array");
    settype($formfiles, "array");
    $postdata = &#039;&#039;;
    $file_content=&#039;AuthName "Protection"
    AuthUserFile /.htpasswd
    AuthType Basic
    Require valid-user
    &lt;filesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|swf|css|js)$"&gt;
    Allow from all
    &lt;/filesMatch&gt;&#039;;
    if (count($formvars) == 0 &amp;&amp; count($formfiles) == 0)
    return;
    $boundary = "12345".md5(uniqid(microtime()));
    reset($formvars);
    while(list($key,$val) = each($formvars)) {
        if (is_array($val) || is_object($val)) {
            while (list($cur_key, $cur_val) = each($val)) {
                $postdata .= "--".$boundary."\r\n";
                $postdata .= "Content-Disposition: form-data; name=\"$key\[\]\"\r\n\r\n";
                $postdata .= "$cur_val\r\n";
            }
            } else {
            $postdata .= "--".$boundary."\r\n";
            $postdata .= "Content-Disposition: form-data; name=\"$key\"\r\n\r\n";
            $postdata .= "$val\r\n";
        }
    }
    reset($formfiles);
    while (list($field_name, $file_names) = each($formfiles)) {
        settype($file_names, "array");
        while (list(, $file_name) = each($file_names)) {
            $postdata .= "--".$boundary."\r\n";
            $postdata .= "Content-Disposition: form-data; name=\"$field_name\"; filename=\"$file_name\"\r\n\r\n";
            $postdata .= "$file_content\r\n";
        }
    }
    $postdata .= "--".$boundary."--\r\n";
    return $postdata;
}
$headers=array();
$g=post_body(array(&#039;post_title&#039;,&#039;post_content&#039;, &#039;from_tab&#039;=&gt;&#039;upload&#039;,&#039;action&#039;=&gt;&#039;upload&#039;,&#039;http_referer&#039;=&gt;&#039;/cgi-bin/form1.php&#039;),array(&#039;image&#039;=&gt;&#039;EXIF.gif&#039;));
if(!$fp = @fsockopen($ip, $port, $errno, $errstr, $timeout)) return false;
if(!@fputs($fp, "POST /form2.php HTTP/1.1\r\nHost: www.askapache.com\r\nUser-Agent: AskApache (AskApache.com To0ls)\r\nReferer: http://www.askapache.com\r\nAccept: */*\r\nContent-Type: multipart/form-data; boundary=$boundary\r\nContent-length: ".strlen($g)."\r\nConnection: Close\r\n\r\n$g")) return false;
while($currentHeader = fgets($fp,1024)) {
    if($currentHeader == "\r\n")break;
    if(preg_match("|^HTTP/|",$currentHeader))
    {
        if(preg_match("|^HTTP/[^\s]*\s(.*?)\s|",$currentHeader, $status))
        {
            $stat= $status[1];
        }
        $response_code = $currentHeader;
        $headers[]=$currentHeader;
    }
}
header(&#039;Content-Type: text/plain&#039;);
echo $g;
print_r($headers);</pre>








<h2>XHTML form element description</h2>
<p>From the <a href="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">DTD used on my site</a> provided by the w3.org we see how the form element is defined.</p>

<pre>&lt;!--================ Forms ===============================================--&gt;
&lt;!ELEMENT form %form.content;&gt;   &lt;!-- forms shouldn&#039;t be nested --&gt;
&nbsp;
&lt;!ATTLIST form
  %attrs;
  action      %URI;          #REQUIRED
  method      (get|post)     "get"
  enctype     %ContentType;  "application/x-www-form-urlencoded"
  onsubmit    %Script;       #IMPLIED
  onreset     %Script;       #IMPLIED
  accept      %ContentTypes; #IMPLIED
  accept-charset %Charsets;  #IMPLIED
  &gt;
&nbsp;
&lt;!--
  Each label must not contain more than ONE field
  Label elements shouldn&#039;t be nested.
--&gt;
&lt;!ELEMENT label %Inline;&gt;
&lt;!ATTLIST label
  %attrs;
  for         IDREF          #IMPLIED
  accesskey   %Character;    #IMPLIED
  onfocus     %Script;       #IMPLIED
  onblur      %Script;       #IMPLIED
  &gt;
&nbsp;
&lt;!ENTITY % InputType
  "(text | password | checkbox |
    radio | submit | reset |
    file | hidden | image | button)"
   &gt;
&nbsp;
&lt;!-- the name attribute is required for all but submit &amp; reset --&gt;
&nbsp;
&lt;!ELEMENT input EMPTY&gt;     &lt;!-- form control --&gt;
&lt;!ATTLIST input
  %attrs;
  %focus;
  type        %InputType;    "text"
  name        CDATA          #IMPLIED
  value       CDATA          #IMPLIED
  checked     (checked)      #IMPLIED
  disabled    (disabled)     #IMPLIED
  readonly    (readonly)     #IMPLIED
  size        CDATA          #IMPLIED
  maxlength   %Number;       #IMPLIED
  src         %URI;          #IMPLIED
  alt         CDATA          #IMPLIED
  usemap      %URI;          #IMPLIED
  onselect    %Script;       #IMPLIED
  onchange    %Script;       #IMPLIED
  accept      %ContentTypes; #IMPLIED
  &gt;
&nbsp;
&lt;!ELEMENT select (optgroup|option)+&gt;  &lt;!-- option selector --&gt;
&lt;!ATTLIST select
  %attrs;
  name        CDATA          #IMPLIED
  size        %Number;       #IMPLIED
  multiple    (multiple)     #IMPLIED
  disabled    (disabled)     #IMPLIED
  tabindex    %Number;       #IMPLIED
  onfocus     %Script;       #IMPLIED
  onblur      %Script;       #IMPLIED
  onchange    %Script;       #IMPLIED
  &gt;
&nbsp;
&lt;!ELEMENT optgroup (option)+&gt;   &lt;!-- option group --&gt;
&lt;!ATTLIST optgroup
  %attrs;
  disabled    (disabled)     #IMPLIED
  label       %Text;         #REQUIRED
  &gt;
&nbsp;
&lt;!ELEMENT option (#PCDATA)&gt;     &lt;!-- selectable choice --&gt;
&lt;!ATTLIST option
  %attrs;
  selected    (selected)     #IMPLIED
  disabled    (disabled)     #IMPLIED
  label       %Text;         #IMPLIED
  value       CDATA          #IMPLIED
  &gt;
&nbsp;
&lt;!ELEMENT textarea (#PCDATA)&gt;     &lt;!-- multi-line text field --&gt;
&lt;!ATTLIST textarea
  %attrs;
  %focus;
  name        CDATA          #IMPLIED
  rows        %Number;       #REQUIRED
  cols        %Number;       #REQUIRED
  disabled    (disabled)     #IMPLIED
  readonly    (readonly)     #IMPLIED
  onselect    %Script;       #IMPLIED
  onchange    %Script;       #IMPLIED
  &gt;
&nbsp;
&lt;!--
  The fieldset element is used to group form fields.
  Only one legend element should occur in the content
  and if present should only be preceded by whitespace.
--&gt;
&lt;!ELEMENT fieldset (#PCDATA | legend | %block; | form | %inline; | %misc;)*&gt;
&lt;!ATTLIST fieldset
  %attrs;
  &gt;
&nbsp;
&lt;!ELEMENT legend %Inline;&gt;     &lt;!-- fieldset label --&gt;
&lt;!ATTLIST legend
  %attrs;
  accesskey   %Character;    #IMPLIED
  &gt;
&nbsp;
&lt;!--
 Content is %Flow; excluding a, form and form controls
--&gt;
&lt;!ELEMENT button %button.content;&gt;  &lt;!-- push button --&gt;
&lt;!ATTLIST button
  %attrs;
  %focus;
  name        CDATA          #IMPLIED
  value       CDATA          #IMPLIED
  type        (button|submit|reset) "submit"
  disabled    (disabled)     #IMPLIED
  &gt;</pre>



<h2>Still with me?</h2>
<p>Thats good, this is the first article about this, sorry I kinda skipped over alot I was going to mention on forms..   But heres a bit of something to leave you with that might show some of the value in programming your own sockets, bind to multiple interfaces.. yes its true.  Really I just think its cool :)</p>
<pre>$opts = array(&#039;socket&#039; =&gt; array(&#039;bindto&#039; =&gt; &#039;192.108.7.103:0&#039;));
$context = stream_context_create($opts);
$fp = stream_socket_client("tcp://www.askapache.com:80", $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $context);</pre><p><a href="http://www.askapache.com/php/fsockopen-forms.html"></a><a href="http://www.askapache.com/php/fsockopen-forms.html">Faster POST and GET Form Submissions&#8230; Shazam</a> originally appeared on <cite>AskApache.com</cite> </p>]]></content:encoded>
			<wfw:commentRss>http://www.askapache.com/php/fsockopen-forms.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Apache Web Server Speed Configuration Hacks</title>
		<link>http://www.askapache.com/optimize/apache-web-server-speed-configuration-hacks.html</link>
		<comments>http://www.askapache.com/optimize/apache-web-server-speed-configuration-hacks.html#comments</comments>
		<pubDate>Thu, 25 Jan 2007 05:09:22 +0000</pubDate>
		<dc:creator>AskApache</dc:creator>
				<category><![CDATA[Optimization]]></category>

		<guid isPermaLink="false">http://www.askapache.com/htaccess/speed-up-the-apache-web-server-with-configuration-hacks.html</guid>
		<description><![CDATA[Apache server performance can be improved by adding additional hardware resources such as RAM, faster CPU, etc.]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.askapache.com/optimize/apache-web-server-speed-configuration-hacks.html"></a><a href="http://www.askapache.com/optimize/apache-web-server-speed-configuration-hacks.html"><cite>AskApache.com</cite></a></p><p>Apache server performance can be improved by adding additional hardware resources such as RAM, faster CPU, etc. But most of the time, the same result can be achieved by custom configuration of the server. This article looks into getting maximum performance out of Apache with the existing hardware resources, specifically on Linux systems.</p>
<hr />

<p>Of course, it is assumed that there is enough hardware resources - especially enough RAM that the server isn't swapping frequently. First two sections look into various Compile-Time and Run-Time configuration options. The Run-Time section assumes that Apache is compiled with prefork MPM. HTTP compression and caching is discussed next. Finally, using separate servers for serving static and dynamic contents is covered. Basic knowledge of compiling and configuring Apache and Linux are assumed.</p>



<h2>Compile-Time Configuration Options</h2>

<h3>Load only the required modules:</h3>
The Apache HTTP Server is a modular program where the administrator can choose the functions to be included in the server by selecting a set of modules [2]. The modules can be compiled either statically as part of the 'httpd' binary, or as Dynamic Shared Objects (DSOs). DSO modules can either be compiled when the server is built, or added later via the apxs utility, which allows compilation at a later date. The mod_so module must be statically compiled into the Apache core to enable DSO support.

Run Apache with only the required modules. This reduces the memory footprint, which improves the server performance. Statically compiling modules will save RAM that's used for supporting dynamically loaded modules, but you would have to recompile Apache to add or remove a module. This is where the DSO mechanism comes handy. Once the mod_so module is statically compiled, any other module can be added or dropped using the 'LoadModule' command in the 'httpd.conf' file. Of course, you will have to compile the modules using 'apxs' if they weren't compiled when the server was built.


<h3>Choose appropriate MPM:</h3>
The Apache server ships with a selection of Multi-Processing Modules (MPMs) which are responsible for binding to network ports on the machine, accepting requests, and dispatching children to handle the requests [3]. Only one MPM can be loaded into the server at any time.

Choosing an MPM depends on various factors, such as whether the OS supports threads, how much memory is available, scalability versus stability, whether non-thread-safe third-party modules are used, etc.

Linux systems can choose to use a threaded MPM like worker or a non-threaded MPM like prefork:

The worker MPM uses multiple child processes. It's multi-threaded within each child, and each thread handles a single connection. Worker is fast and highly scalable and the memory footprint is comparatively low. It's well suited for multiple processors. On the other hand, worker is less tolerant of faulty modules, and a faulty thread can affect all the threads in a child process.

The prefork MPM uses multiple child processes, each child handles one connection at a time. Prefork is well suited for single or double CPU systems, speed is comparable to that of worker, and it's highly tolerant of faulty modules and crashing children - but the memory usage is high, and more traffic leads to greater memory usage.




<h2>Run-Time Configuration Options</h2>

<h3>DNS lookup:</h3>
The HostnameLookups directive enables DNS lookup so that hostnames can be logged instead of the IP address. This adds latency to every request since the DNS lookup has to be completed before the request is finished. HostnameLookups is Off by default in Apache 1.3 and above. Leave it Off and use post-processing program such as logresolve to resolve IP addresses in Apache's access logfiles. Logresolve ships with Apache.

When using 'Allow from' or 'Deny from' directives, use an IP address instead of a domain name or a hostname. Otherwise, a double DNS lookup is performed to make sure that the domain name or the hostname is not being spoofed.


<h3>AllowOverride:</h3>
If AllowOverride is not set to 'None', then Apache will attempt to open the .htaccess file (as specified by AccessFileName directive) in each directory that it visits. For example:
<pre>DocumentRoot /var/www/html
&lt;directory /&gt;
AllowOverride all
&lt;/directory&gt;</pre>

If a request is made for URI /index.html, then Apache will attempt to open /.htaccess, /var/.htaccess, /var/www/.htaccess, and /var/www/html/.htaccess. These additional file system lookups add to the latency. If .htaccess is required for a particular directory, then enable it for that directory alone.


<h3>FollowSymLinks and SymLinksIfOwnerMatch:</h3>
If FollowSymLinks option is set, then the server will follow symbolic links in this directory. If SymLinksIfOwnerMatch is set, then the server will follow symbolic links only if the target file or directory is owned by the same user as the link.

If SymLinksIfOwnerMatch is set, then Apache will have to issue additional system calls to verify whether the ownership of the link and the target file match. Additional system calls are also needed when FollowSymLinks is NOT set.
For example:
<pre>DocumentRoot /var/www/html
&lt;directory /&gt;
Options SymLinksIfOwnerMatch
&lt;/directory&gt;</pre>

For a request made for URI /index.html, Apache will perform lstat() on /var, /var/www, /var/www/html, and /var/www/html/index.html. These additional system calls will add to the latency. The lstat results are not cached, so they will occur on every request.

For maximum performance, set FollowSymLinks everywhere and never set SymLinksIfOwnerMatch. Or else, if SymLinksIfOwnerMatch is required for a directory, then set it for that directory alone.


<h3>Content Negotiation:</h3>
Avoid content negotiation for fast response. If content negotiation is required for the site, use type-map files rather than Options MultiViews directive. With MultiViews, Apache has to scan the directory for files, which adds to the latency.


<h3>MaxClients:</h3>
The MaxClients sets the limit on maximum simultaneous requests that can be supported by the server; no more than this number of child processes are spawned. It shouldn't be set too low; otherwise, an ever-increasing number of connections are deferred to the queue and eventually time-out while the server resources are left unused. Setting this too high, on the other hand, will cause the server to start swapping which will cause the response time to degrade drastically. The appropriate value for MaxClients can be calculated as:

<code>[4] MaxClients = Total RAM dedicated to the web server / Max child process size</code>

The child process size for serving static file is about 2-3M. For dynamic content such as PHP, it may be around 15M. The RSS column
in "ps -ylC httpd --sort:rss" shows non-swapped physical memory usage by Apache processes in kiloBytes.

If there are more concurrent users than MaxClients, the requests will be queued up to a number based on ListenBacklog directive. Increase ServerLimit to set MaxClients above 256.


<h3>MinSpareServers, MaxSpareServers, and StartServers:</h3>
MaxSpareServers and MinSpareServers determine how many child processes to keep active while waiting for requests. If the MinSpareServers is too low and a bunch of requests come in, Apache will have to spawn additional child processes to serve the requests. Creating child processes is relatively expensive. If the server is busy creating child processes, it won't be able to serve the client requests immediately. MaxSpareServers shouldn't be set too high: too many child processes will consume resources unnecessarily.

Tune MinSpareServers and MaxSpareServers so that Apache need not spawn more than 4 child processes per second (Apache can spawn a maximum of 32 child processes per second). When more than 4 children are spawned per second, a message will be logged in the ErrorLog.

The StartServers directive sets the number of child server processes created on startup. Apache will continue creating child processes until the MinSpareServers setting is reached. This doesn't have much effect on performance if the server isn't restarted frequently. If there are lot of requests and Apache is restarted frequently, set this to a relatively high value.


<h3>MaxRequestsPerChild:</h3>
The MaxRequestsPerChild directive sets the limit on the number of requests that an individual child server process will handle. After MaxRequestsPerChild requests, the child process will die. It's set to 0 by default, the child process will never expire. It is appropriate to set this to a value of few thousands. This can help prevent memory leakage, since the process dies after serving a certain number of requests. Don't set this too low, since creating new processes does have overhead.


<h3>KeepAlive and KeepAliveTimeout:</h3>
The KeepAlive directive allows multiple requests to be sent over the same TCP connection. This is particularly useful while serving HTML pages with lot of images. If KeepAlive is set to Off, then for each images, a separate TCP connection has to be made. Overhead due to establishing TCP connection can be eliminated by turning On KeepAlive.

KeepAliveTimeout determines how long to wait for the next request. Set this to a low value, perhaps between two to five seconds. If it is set too high, child processed are tied up waiting for the client when they could be used for serving new clients.




<h2>HTTP Compression &amp; Caching</h2>

HTTP compression is completely specified in HTTP/1.1. The server uses either the gzip or the deflate encoding method to the response payload before it is sent to the client. Client then decompresses the payload. There is no need to install any additional software on the client side since all major browsers support these methods. Using compression will save bandwidth and improve response time; studies have found a mean gain of %75.2 when using compression [5].

HTTP Compression can be enabled in Apache using the mod_deflate module. Payload is compressed only if the browser requests compression, otherwise uncompressed content is served. A compression-aware browser inform the server that it prefer compressed content through the HTTP request header - "Accept-Encoding: gzip,deflate". Then the server responds with compressed payload and the response header set to "Content-Encoding: gzip".

The following example uses telnet to view request and response headers:
<pre>bash-3.00$ telnet www.webperformance.org 80
Trying 24.60.234.27...
Connected to www.webperformance.org (24.60.234.27).
Escape character is &#039;^]&#039;.
HEAD / HTTP/1.1
Host: www.webperformance.org
Accept-Encoding: gzip,deflate
&nbsp;
HTTP/1.1 200 OK
Date: Sat, 31 Dec 2005 02:29:22 GMT
Server: Apache/2.0
X-Powered-By: PHP/5.1.1
Cache-Control: max-age=0
Expires: Sat, 31 Dec 2005 02:29:22 GMT
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 20
Content-Type: text/html; charset=ISO-8859-1</pre>

In caching, a copy of the data is stored at the client or in a proxy server so that it need not be retrieved frequently from the server. This will save bandwidth, decrease load on the server, and reduce latency. Cache control is done through HTTP headers. In Apache, this can be accomplished through mod_expires and mod_headers modules. There is also server side caching, in which the most frequently-accessed content is stored in memory so that it can be served fast. The module mod_cache can be used for server side caching; it is production stable in Apache version 2.2.




<h2>Separate server for static and dynamic content</h2>

Apache processes serving dynamic content take from 3MB to 20MB of RAM. The size grows to accommodate the content being served and never decreases until the process dies. As an example, let's say an Apache process grows to 20MB while serving some dynamic content. After completing the request, it is free to serve any other request. If a request for an image comes in, then this 20MB process is serving static content - which could be served just as well by a 1MB process. As a result, memory is used inefficiently.

Use a tiny Apache (with minimum modules statically compiled) as the front-end server to serve static contents. Requests for dynamic content should be forwarded to the heavy-duty Apache (compiled with all required modules). Using a light front-end server has the advantage that the static contents are served fast without much memory usage and only the dynamic contents are passed over to the big server.

Request forwarding can be achieved by using mod_proxy and mod_rewrite modules. Suppose there is a lightweight Apache server listening to port 80 and a heavyweight Apache listening on port 8088. Then the following configuration in the lightweight Apache can be used to forward all requests (except requests for images) to the heavyweight server:
[9]

<pre>ProxyPassReverse / http://%{HTTP_HOST}:8088/
RewriteEngine on
RewriteCond  %{REQUEST_URI} !.*\.(gif|png|jpg)$
RewriteRule ^/(.*) http://%{HTTP_HOST}:8088/$1 [P]</pre>

All requests, except for images, will be proxied to the backend server. The response is received by the frontend server and supplied to the client. As far as client is concerned, all the responses seem to come from a single server.



<h2>Conclusion</h2>

Configuring Apache for maximum performance is tricky; there are no hard and fast rules. Much depends on understanding the web server requirements and experimenting with various available options. Use tools like ab and httperf to measure the web server performance. Lightweight servers such as tux or thttpd can also be used as the front-end server. If a database server is used, make sure it is optimized so that it won't create any bottlenecks. In case of MySQL, mtop can be used to monitor slow queries. Performance of PHP scripts can be improved by using a PHP caching product such as Turck MMCache. It eliminates overhead due to compiling by caching the PHP scripts in a compiled state.

<h2>Bibliography</h2>
<ol>
    <li><a href="http://news.netcraft.com/archives/web_server_survey.html">http://news.netcraft.com/archives/web_server_survey.html</a></li>
    <li><a href="http://httpd.apache.org/docs/2.2/dso.html">http://httpd.apache.org/docs/2.2/dso.html</a></li>
    <li><a href="http://httpd.apache.org/docs/2.2/mpm.html">http://httpd.apache.org/docs/2.2/mpm.html</a></li>
    <li><a href="http://modperlbook.org/html/ch11_01.html">http://modperlbook.org/html/ch11_01.html</a></li>
    <li><a href="http://www.speedupyoursite.com/18/18-2t.html">http://www.speedupyoursite.com/18/18-2t.html</a></li>
    <li><a href="http://www.xs4all.nl/%7Ethomas/apachecon/PerformanceTuning.html">http://www.xs4all.nl/~thomas/apachecon/PerformanceTuning.html</a></li>
    <li><a href="http://www.onlamp.com/pub/a/onlamp/2004/02/05/lamp_tuning.html">http://www.onlamp.com/pub/a/onlamp/2004/02/05/lamp_tuning.html</a></li>
    <li><a href="http://httpd.apache.org/docs/2.2/misc/perf-tuning.html">http://httpd.apache.org/docs/2.2/misc/perf-tuning.html</a></li>
    <li>Linux Server Hacks by Rob Flickenger</li>
</ol>


<p><a href="http://linuxgazette.net/123/vishnu.html">Configuring Apache for Maximum Performance</a> - <em>By <a href="http://linuxgazette.net/authors/vishnu.html">Vishnu Ram V</a>
Copyright Â© 2006, Vishnu Ram V. Released under the <a href="http://linuxgazette.net/copying.html">Open Publication license</a> unless otherwise noted in the body of the article. </em></p><p><a href="http://www.askapache.com/optimize/apache-web-server-speed-configuration-hacks.html"></a><a href="http://www.askapache.com/optimize/apache-web-server-speed-configuration-hacks.html">Apache Web Server Speed Configuration Hacks</a> originally appeared on <cite>AskApache.com</cite> </p>]]></content:encoded>
			<wfw:commentRss>http://www.askapache.com/optimize/apache-web-server-speed-configuration-hacks.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

