<?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>god morgon! &#187; nginx</title>
	<atom:link href="http://god.morgon.nu/tag/nginx/feed/" rel="self" type="application/rss+xml" />
	<link>http://god.morgon.nu</link>
	<description></description>
	<lastBuildDate>Fri, 23 Oct 2009 13:35:32 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>staticgenerator for django with gzip support</title>
		<link>http://god.morgon.nu/2009/05/03/staticgenerator-for-django-with-gzip-support/</link>
		<comments>http://god.morgon.nu/2009/05/03/staticgenerator-for-django-with-gzip-support/#comments</comments>
		<pubDate>Sun, 03 May 2009 18:07:15 +0000</pubDate>
		<dc:creator>Andreas</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[gzip_static]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[staticgenerator]]></category>

		<guid isPermaLink="false">http://god.morgon.nu/?p=90</guid>
		<description><![CDATA[I have written about staticgenerator before. It&#8217;s the python library with a django middleware which generates static html, xml or whatever of your dynamic site and let you serve it with for example nginx to speed up things.
One thing that always bothered me with staticgenerator is that nginx had to gzip the same html over [...]]]></description>
			<content:encoded><![CDATA[<p>I have <a href="http://god.morgon.nu/tag/staticgenerator/">written</a> about <a href="http://github.com/JaredKuolt/staticgenerator/tree/master">staticgenerator</a> before. It&#8217;s the python library with a django middleware which generates static html, xml or whatever of your dynamic site and let you serve it with for example nginx to speed up things.</p>
<p>One thing that always bothered me with staticgenerator is that nginx had to gzip the same html over and over again on requests with the <code>Accept-Encoding: gzip</code> header. Now that I <a href="http://god.morgon.nu/2009/05/02/latest-nginx-with-gzip_static-ubuntu-jaunty-jackalope-deb-package/">found love</a> with <a href="http://wiki.nginx.org/NginxHttpGzipStaticModule">gzip_static</a> it&#8217;s super easy to serve precompressed .gz files with nginx. The feature it self has been around in nginx for a while but it wasn&#8217;t untill recently it got to my attention.</p>
<p>Since I already have <a href="http://github.com/andriijas/staticgeneratormem/tree/master">one fork</a> of staticgenerator at github I choosed to fork from <a href="http://github.com/ekarulf/staticgenerator/tree/master">Erik Karulf </a>instead. I wanted his excellent changes which enables atomic file generation anyway.</p>
<p>So straight from the oven, <a href="http://github.com/andriijas/staticgenerator/tree/master">staticgenerator with atomic file generation and atomic gzip support</a>. I&#8217;ll ping <a href="http://github.com/JaredKuolt">Jared Kuolt on github</a> and hopefully he will merge mine and Erik&#8217;s changes into the main repository and makes a new release.</p>
<p>Feel free to post feedback of any kind in the comments.</p>
]]></content:encoded>
			<wfw:commentRss>http://god.morgon.nu/2009/05/03/staticgenerator-for-django-with-gzip-support/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Latest nginx with gzip_static ubuntu jaunty jackalope deb package</title>
		<link>http://god.morgon.nu/2009/05/02/latest-nginx-with-gzip_static-ubuntu-jaunty-jackalope-deb-package/</link>
		<comments>http://god.morgon.nu/2009/05/02/latest-nginx-with-gzip_static-ubuntu-jaunty-jackalope-deb-package/#comments</comments>
		<pubDate>Sat, 02 May 2009 13:35:09 +0000</pubDate>
		<dc:creator>Andreas</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[gzip_static]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://god.morgon.nu/?p=82</guid>
		<description><![CDATA[nginx in ubuntu 9.04 aka jaunty jackalope is compiled without gzip_static support (Bug report).  Waiting for it to be resolved seems like to be waiting for ubuntu karmic koala.
gzip_static enables nginx to check for pre gzip&#8217;d files so it doesn&#8217;t have to gzip the same content over and over again, which saves you a [...]]]></description>
			<content:encoded><![CDATA[<p>nginx in <a href="http://www.ubuntu.com/">ubuntu</a> 9.04 aka jaunty jackalope is compiled without gzip_static support (<a href="https://bugs.launchpad.net/ubuntu/+source/nginx/+bug/346010">Bug report</a>).  Waiting for it to be resolved seems like to be waiting for ubuntu karmic koala.</p>
<p><code>gzip_static</code> enables nginx to check for pre gzip&#8217;d files so it doesn&#8217;t have to gzip the same content over and over again, which saves you a lot of cpu on high traffic sites. Say you request <code>/foo/index.html</code>  with <code>Accept-Encoding: gzip</code> and there is a file in your doc root <code>foo/index.html.gz</code>, nginx will then take that <code>index.html.gz</code> and serve it instead of gziping foo/index.html on the fly.</p>
<p>Upgrading and compiling deb packages seems to be easier than ever, I found a tutorial on the <a href="http://ubuntuforums.org/showthread.php?t=1105902">ubuntu forum</a> which explains in just a few steps on how to always have the latest nginx available in a ubuntu fashion (conf in /etc/nginx,  startup script in /etc/init.d  and so on). I guess the tutorial works for 0.6.x versions aswell as 0.7.x. I only tried 0.7, not that I need any specific 0.7 features but I like to have the latest and greatest :)</p>
<p>Anyway if you still don&#8217;t want to compile it, you can download <a href="http://god.morgon.nu/public/nginx-jaunty/nginx_0.7.54-0ubuntu1_i386.deb">nginx_0.7.54-0ubuntu1_i386.deb</a> from my <a href="http://god.morgon.nu/public/">public files section</a>.</p>
<pre><code>$ wget http://god.morgon.nu/public/nginx-jaunty/nginx_0.7.54-0ubuntu1_i386.deb
$ sudo dpkg -i nginx_0.7.54-0ubuntu1_i386.deb
</code></pre>
<p>I don&#8217;t have any energy to put up an apt repository but chances are I will keep publishing new nginx packages on there. Keep in mind I only have 10 mbit up, feel free to mirror it and include a link back to this post or post a mirror link in the comments. Also feel free to post comments if you like this or if you have any feedback.</p>
]]></content:encoded>
			<wfw:commentRss>http://god.morgon.nu/2009/05/02/latest-nginx-with-gzip_static-ubuntu-jaunty-jackalope-deb-package/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Why this site is crazy fast</title>
		<link>http://god.morgon.nu/2009/05/01/why-this-site-is-crazy-fast/</link>
		<comments>http://god.morgon.nu/2009/05/01/why-this-site-is-crazy-fast/#comments</comments>
		<pubDate>Fri, 01 May 2009 08:29:34 +0000</pubDate>
		<dc:creator>Andreas</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[gzip_static]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[wp-super-cache]]></category>

		<guid isPermaLink="false">http://god.morgon.nu/?p=73</guid>
		<description><![CDATA[I love web performence pretty much like 15 years likes to trim their mopeds. (At least they did like to  before web). While the blog definitely scaled better over at wordpress.com, I believe it performs better on my ubuntu server powered laptop at home, since it only powers one instead of gazillions of blogs. [...]]]></description>
			<content:encoded><![CDATA[<p>I love web performence pretty much like 15 years likes to trim their mopeds. (At least they did like to  before web). While the blog definitely scaled better over at <a href="http://www.wordpress.com">wordpress.com</a>, I believe it performs better on my ubuntu server powered laptop at home, since it only powers one instead of gazillions of blogs. Also I was surprised I needed to pay $15/year just to be able to customize the css on wp.com. So here follows a short description of how I took full control over the stack.</p>
<p>The bad parts of making the switch was that I needed to bloat my precious server with <a href="http://dev.mysql.com/">mysql</a> and <a href="http://www.php.net">php</a> ;)  I might move to <a href="http://zine.pocoo.org/">Zine</a> when it gets a little more mature but for now I really don&#8217;t care. Anyway. Basicly it&#8217;s the <a href="http://wordpress.org/extend/plugins/wp-super-cache/">wp-super-cache</a> plugin that makes the most from a performence perspective. It&#8217;s pretty much <a href="http://github.com/JaredKuolt/staticgenerator/">staticgenerator</a> for wordpress, it generates static html files from the blog. But instead of letting the proxypassed apache serve those html files, I of course serve them with nginx. Not only is it faster, it let&#8217;s me fine tune the config in ways apache doesn&#8217;t, beacuse of it&#8217;s support for if statements. That makes it easy to serve the cached created files with expire headers.</p>
<pre><code>if (-f $document_root/$supercache_file) {
  rewrite ^(.*)$ $supercache_file;
  expires 1h;
  break;
}</code></pre>
<p>Obvious overkill you might think. But fact is I don&#8217;t post new posts very often, so why should one need to download the same html twice? wp-super-cache also generates gzip&#8217;d files, so you don&#8217;t need to waste cpu on gziping the same html over and over again. With <a href="http://god.morgon.nu/2009/05/02/latest-nginx-with-gzip_static-ubuntu-jaunty-jackalope-deb-package/">gzip_static in nginx</a> this is possible. If you request <code>/foo/index.html</code> with <code>Accept-Encoding: gzip</code> and have <code>gzip_static on</code>, nginx automaticly checks if there is a file <code>/foo/index.html.gz</code> and serves it.</p>
<p>Does all this makes this site diggproof? I don&#8217;t know for sure. I guess it all depends on my bandwidth (10 mbit up should be enough) and also if many people makes comments on the same time. Chances are pretty low I will get that much traffic anyway. But a fast site makes visitors happy anyway.</p>
]]></content:encoded>
			<wfw:commentRss>http://god.morgon.nu/2009/05/01/why-this-site-is-crazy-fast/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Introducing StaticGeneratorMem for django</title>
		<link>http://god.morgon.nu/2009/03/23/introducing-staticgeneratormem-for-django/</link>
		<comments>http://god.morgon.nu/2009/03/23/introducing-staticgeneratormem-for-django/#comments</comments>
		<pubDate>Sun, 22 Mar 2009 23:03:44 +0000</pubDate>
		<dc:creator>Andreas</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[memcached]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[staticgenerator]]></category>
		<category><![CDATA[staticgeneratormem]]></category>

		<guid isPermaLink="false">http://god.morgon.nu/?p=28</guid>
		<description><![CDATA[As a result of the last post about serving static content vs memcached content with nginx I&#8217;m hereby introducing StaticGeneratorMem, a fork of the excellent StaticGenerator by Jared Kuolt which speeds up your django powered site by generating static files and let nginx serve it if exists, if not hitting the django app server. Instead [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align:left;">As a result of the last post about <a href="http://god.morgon.nu/2009/03/12/thoughts-on-static-vs-memcached-serving-by-nginx/">serving static content vs memcached content with nginx</a> I&#8217;m hereby introducing <a href="http://github.com/andriijas/staticgeneratormem/tree/master">StaticGeneratorMem</a>, a fork of the excellent <a href="http://github.com/JaredKuolt/staticgenerator/tree/master">StaticGenerator</a> by <a href="http://superjared.com/">Jared Kuolt</a> which speeds up your <a href="http://djangoproject.com">django</a> powered site by generating static files and let nginx serve it if exists, if not hitting the django app server. Instead of generating static files, StaticGeneratorMem puts the generated content in a <a href="http://www.danga.com/memcached/">memcached</a> and guess what, it let you serve that html directly from memcached with <a href="http://wiki.codemongers.com/Main">nginx</a> and its <a href="http://wiki.nginx.org/NginxHttpMemcachedModule">memcached module</a>. In other words, StaticGenerator is pretty much a combination of StaticGenerator and <a href="http://soyrex.com/blog/django-nginx-and-memcached/">this code from Alex Holt</a>.</p>
<p style="text-align:left;">It&#8217;s pretty much a drop-in replacement for StaticGenerator except that you need to edit your <code>settings.py</code> to use <a href="http://docs.djangoproject.com/en/dev/topics/cache/#memcached">memcached as cache backend. </a></p>
<pre><code>CACHE_BACKEND = 'memcached://127.0.0.1:11211/'</code></pre>
<p>And of course you need to update your nginx config. It could look like something like this:</p>
<pre><code># This example configuration only shows relevant parts
# It assumes your django app is served via http on localhost:9004
location / {
    #pass POST requests to django
    if ($request_method = POST) {
            proxy_pass http://localhost:9004;
            break;
    }
    default_type  "text/html; charset=utf-8";
    set $memcached_key "$host$uri";
    memcached_pass localhost:11211;
    error_page 404 502 = /django;
}

location = /django  {
    proxy_pass http://localhost:9004;
    break;
}
</code></pre>
<p>I tried to cover everything in the <a href="http://github.com/andriijas/staticgeneratormem/tree/master#readme">README</a>.</p>
<h2>Bonus feature!</h2>
<p>I included one bonus feature not exisiting in StaticGenerator. You can add the following line to your <code>settings.py</code> which will make StaticGeneratorMem not to put responses in memcached if there is any user logged in.</p>
<pre><code>STATIC_GENERATOR_ANON_ONLY = True</pre>
<p></code></p>
<p>You can the modify your nginx config to something like this. Note that you need to edit the domain field for your settings id in your database to reflect the <code>server_name</code> which is used in the memcache key. You can also set it as <code>SERVER_NAME</code> in <code>settings.py</code> if you are not using <a href="http://docs.djangoproject.com/en/dev/ref/contrib/sites/">contrib.sites</a>.</p>
<pre><code># This example configuration only shows relevant parts
# It assumes your django app is served via http on localhost:9004
location / {
    #pass POST requests to django
    if ($request_method = POST) {
            proxy_pass http://localhost:9004;
            break;
    }
    #pass logged in users to django
    if ($http_cookie ~* &quot;sessionid=.{32}&quot;) {
        proxy_pass http://localhost:9004;
        break;
    }
    default_type  &quot;text/html; charset=utf-8&quot;;
    set $memcached_key &quot;$host$uri&quot;;
    memcached_pass localhost:11211;
    error_page 404 502 = /django;
}

location = /django  {
    proxy_pass http://localhost:9004;
    break;
}
</code></pre>
<p>And logged in users will hit the django app with a dynamic request instead of the cached content in memcached. If you changed the cookie name of your session id to something else than sessionid you need to take that into consideration aswell. From my experience this doesn't work 100%, if a user logs out the cookie usally remain with an invalid session id which will cause logged-in-and-then-logged-out users to hit the django app directly and not cached content. On a blog or content heavy site which is StaticGeneratorMems primary usage this would only be you and any other authors so it's probably not a big deal, just something good to know.</p>
<h2>Should I use this or StaticGenerator?</h2>
<p>This is totaly up to you. Both will give you excellent perforemence boosts though StaticGenerator will give you the best performence. If you prefer puting cached things in memcached, using StaticGeneratorMem is a neat way of doing it. With StaticGeneratorMem a restart of memcached and the cache is gone. More on this in my previous <a href="http://god.morgon.nu/2009/03/12/thoughts-on-static-vs-memcached-serving-by-nginx/">post about this</a>.</p>
<p>That's all for know. Remember to tail your apache (or whatever httpd you are using) access log side by side with your nginx acceess log to make sure that only the first request hits both servers and the second only nginx. I'd be glad for any feedback on this.</p>
]]></content:encoded>
			<wfw:commentRss>http://god.morgon.nu/2009/03/23/introducing-staticgeneratormem-for-django/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Thoughts on static vs memcached serving by nginx</title>
		<link>http://god.morgon.nu/2009/03/12/thoughts-on-static-vs-memcached-serving-by-nginx/</link>
		<comments>http://god.morgon.nu/2009/03/12/thoughts-on-static-vs-memcached-serving-by-nginx/#comments</comments>
		<pubDate>Thu, 12 Mar 2009 10:13:17 +0000</pubDate>
		<dc:creator>Andreas</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[memcached]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[staticgenerator]]></category>

		<guid isPermaLink="false">http://god.morgon.nu/?p=8</guid>
		<description><![CDATA[If you been around in the django community for a while chances are you have heard of staticgenerator, the excellent tool that speeds up your blog or content heavy site by generating static html out of it which can be served by nginx (the webserver/reverse proxy/mail proxy from Russia with love that needs no introduction [...]]]></description>
			<content:encoded><![CDATA[<p>If you been around in the <a href="http://www.djangoproject.com/community/">django community</a> for a while chances are you have heard of <a href="http://github.com/JaredKuolt/staticgenerator/tree/master">staticgenerator</a>, the excellent tool that speeds up your blog or content heavy site by generating static html out of it which can be served by <a href="http://wiki.codemongers.com/Main">nginx</a> (the webserver/reverse proxy/mail proxy from Russia with love that needs no introduction today) directly. Recently <a href="http://soyrex.com/blog/django-nginx-and-memcached/">more</a> <a href="http://weichhold.com/2009/02/16/high-performance-media-merging-with-django-nginx-and-memcached/">and</a> <a href="http://www.willmcgugan.com/blog/tech/2009/3/1/fast-caching-with-django-and-nginx/">more</a> has done the samething but instead of generating static files, they put the generated content in <a href="http://www.danga.com/memcached/">memcached</a> and lets nginx serve it directly from memcached with it&#8217;s sweet <a href="http://wiki.codemongers.com/NginxHttpMemcachedModule">memcached module</a>. Which should you use? Memcached or static files? With this post I&#8217;d like to adress the benefits by using either of these strategies to speed up your dynamic webapp monster.</p>
<h2>Benchmarks</h2>
<p>Some people chooses strategy after benchmarks numbers without any other considerations so I&#8217;ll start by just stating that nginx serves static content ~270% faster than memcached content and Im sure some people stops reading here and goes with staticgenerator.</p>
<p>I didn&#8217;t just make that number up, I used the excellent <a href="http://www.hpl.hp.com/research/linux/httperf/">httperf</a> with the following settings:</p>
<pre><code>$ httperf --client=0/1 --server=foo.bar --port=80 --uri=/test/ --send-buffer=4096 --recv-buffer=16384 --num-conns=1 --num-calls=10000</code></pre>
<p>With a static html file on /test/ i got this result:</p>
<blockquote><p>Request rate: 6243.8 req/s (0.2 ms/req)</p>
</blockquote>
<p>And with the exact same html in memcached i got this:</p>
<blockquote><p>Request rate: 2285.5 req/s (0.4 ms/req)</p>
</blockquote>
<p>These benchmarks were made with &#8220;warm cache&#8221;, the html file was pregenerated aswell as put into the memcache before the tests were made. So does this mean nginx is actually 270% faster on serving the same html from static files than from memcached? No. I don&#8217;t have any proper benchmark environment. This numbers just gave me hints about nginx being faster on static content than serving from memcached with its memcached module and most important, the test numbers made me thinking about what was going on behind the curtains.</p>
<h2>Interpreting the benchs</h2>
<p>I think one of the reasons the memcached solution does&#8217;nt perform as well as static files is that on every single request the nginx needs to open up a new tcp socket, handshake with the memcached etc. Hold it right there, this is starting to sound like a dialog from <a href="http://fox.com/24">24</a> with <a href="http://en.wikipedia.org/wiki/Chloe_O%27Brian">Chloe O&#8217;Brian</a>. Im not familiar with the core stuff of the <a href="http://en.wikipedia.org/wiki/Transmission_Control_Protocol">tcp protocol</a> but what I mean is that on every single nginx request, nginx has to connect to the memcached, there is no keepalive or persistent connection between nginx and memcached. Running both memcached and nginx on localhost may not add any significant delay, but the fact that it&#8217;s a completly another program with its own processes that nginx needs to &#8220;connect to&#8221;, and wait for an answer is pretty clear to me that it adds some delay on vs just serving the file from local disk within the same process.</p>
<p>But doesn&#8217;t serving static files means that nginx hits the disk on every request? Yes and no. All *bsd and linux systems (I can&#8217;t speak for windows) has excellent fs usage. Frequently requested files are cached automaticly by the os,  though the files are stated on every request to see if they have been changed for example. The above benchsmarks was done on two laptops (with 5400 rpm drives), one with nginx and memcache and one running httperf. With 5400 rpm drives.</p>
<h2>Conclusion</h2>
<p>Either you choose to use staticgenerator or one of the memcached ways you will speed up your site significantly. If you want the fastest available option use a staticgenerator with a <a href="http://en.wikipedia.org/wiki/Ramdisk">ramdisk</a> (mount some of your ram as a dir). Generally I think it&#8217;s a cleaner concept to put generated content in mem instead of disk. A restart of memcache and the cache is gone. Also, your memcache doesn&#8217;t need to be running on the same machine as the nginx or the webapp. It makes it easier for flexible setups and scale, pushing around static files over network with scp/rsync/nfs/&lt;your preferred tool for moving data over network here&gt; is messier but fact remains static files are served faster.</p>
<p>Consider adding expires headers on like 1 hour and clients browsing around the site will not even have to download the same html over and over again aswell. But then clients won&#8217;t necessary always see the latest content you say? They may not, you could adjust the expire header depending on how often you post to your blog or how often you update your content.</p>
<p>I use these strategies even on sites without any load. Why? When that somebody actually visits the site I wan&#8217;t it to be served as fast as possible. Performence and usabillity goes hand in hand, a fast experience is a good experience.</p>
]]></content:encoded>
			<wfw:commentRss>http://god.morgon.nu/2009/03/12/thoughts-on-static-vs-memcached-serving-by-nginx/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
