How to Speed up Your Django Sites with NginX, Memcached, and django-compress
Posted on April 23rd, 2009 by Greg Allard in Django, Programming, Server Administration | Comments
A lot of these steps will speed up any kind of application, not just django projects, but there are a few django specific things. Everything has been tested on IvyLees which is running in a Debian/Ubuntu environment.
These three simple steps will speed up your server and allow it to handle more traffic.
Reducing the Number of HTTP Requests
Yahoo has developed a firefox extension called YSlow. It analyzes all of the traffic from a website and gives a score on a few categories where improvements can be made.
It recommends reducing all of your css files into one file and all of your js files into one file or as few as possible. There is a pluggable, open source django application available to help with that task. After setting up django-compress, a website will have css and js files that are minified (excess white space and characters are removed to reduce file size). The application will also give the files version numbers so that they can be cached by the web browser and won’t need to be downloaded again until a change is made and a new version of the file is created. How to setup the server to set a far future expiration is shown below in the lightweight server section.
Setting up Memcached
Django makes it really simple to set up caching backends and memcached is easy to install.
sudo aptitude install memcached, python-setuptools
We will need setuptools so that we can do the following command.
sudo easy_install python-memcached
Once that is done you can start the memcached server by doing the following:
sudo memcached -d -u www-data -p 11211 -m 64
-d will start it in daemon mode, -u is the user for it to run as, -p is the port, and -m is the maximum number of megabytes of memory to use.
Now open up the settings.py file for your project and add the following line:
CACHE_BACKEND = 'memcached://127.0.0.1:11211/'Find the MIDDLEWARE_CLASSES section and add this to the beginning of the list:
'django.middleware.cache.UpdateCacheMiddleware',and this to the end of the list:
'django.middleware.cache.FetchFromCacheMiddleware',For more about caching with django see the django docs on caching. You can reload the server now to try it out.
sudo /etc/init.d/apache2 reload
To make sure that memcached is set up correctly you can telnet into it and get some statistics.
telnet localhost 11211
Once you are in type stats and it will show some information (press ctrl ] and then ctrl d to exit). If there are too many zeroes, it either isn’t working or you haven’t visited your site since the caching was set up. See the memcached site for more information.
Don’t Use Apache for Static Files
Apache has some overhead involved that makes it good for serving php, python, or ruby applications, but you do not need that for static files like your images, style sheets, and javascript. There are a few options for lightweight servers that you can put in front of apache to handle the static files. Lighttpd (lighty) and nginx (engine x) are two good options. Adding this layer in front of your application will act as an application firewall so there is a security bonus to the speed bonus.
There is this guide to install a django setup with nginx and apache from scratch. If you followed my guide to set up your server or already have apache set up for your application, then there are a few steps to get nginx handling your static files.
sudo aptitude install nginx
Edit the config file for your site (sudo nano /etc/apache2/sites-available/default) and change the port from 80 to 8080 and change the ip address (might be *) to 127.0.0.1. The lines will look like the following
NameVirtualHost 127.0.0.1:8080 <VirtualHost 127.0.0.1:8080>
Also edit the ports.conf file (sudo nano /etc/apache2/ports.conf) so that it will listen on 8080.
Listen 8080
Don’t restart the server yet, you want to configure nginx first. Edit the default nginx config file (sudo nano /etc/nginx/sites-available/default) and find where it says
location / {
root /var/www/nginx-default;
index index.html index.htm;
}and replace it with
location / {
proxy_pass http://192.168.0.180:8080;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
}
location /files/ {
root /var/www/myproject/;
expires max;
}/files/ is where I’ve stored all of my static files and /var/www/myproject/ is where my project lives and it contains the files directory.
Set static files to expire far in the future
expires max; will tell your users’ browsers to cache the files from that directory for a long time. Only use that if you are use those files won’t change. You can use expires 24h; if you aren’t sure.
Configure gzip
Edit the nginx configuration to use gzip on all of your static files (sudo nano /etc/nginx/nginx.conf). Where it says gzip on; make sure it looks like the following:
gzip on;
gzip_comp_level 2;
gzip_proxied any;
gzip_types text/plain text/html text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;The servers should be ready to be restarted.
sudo /etc/init.d/apache2 reload sudo /etc/init.d/nginx reload
If you are having any problems I suggest reading through this guide and seeing if you have something set up differently.
Speedy Django Sites
Those three steps should speed up your server and allow for more simultaneous visitors. There is a lot more that can be done, but getting these three easy things out of the way first is a good start.
I use webfaction to host a lot of my django projects. It has an easy setup that will get you developing quickly and a great community of talented programmers. There is also a quick setup for rails, wordpress, and a lot more.
Related posts:
- How to Display Realtime Traffic Analytics Users of Presskit’n have been asking for traffic statistics on their press releases so I decided I would get them...
- Python Projects in Users’ Home Directories with wsgi Letting users put static files and php files in a public_html folder in their home directory has been a common...
- Static Files in Django on Production and Development Update 2009-03-25 I realize why this isn’t needed. If your production environment is set up correctly, django will never serve...
Greg Allard is the programmer behind
April 23rd, 2009 on 3:08 pm
There are two more django apps that could help reduce http requests. I didn't find these until after posting this. http://code.google.com/p/django-sprites/ and http://github.com/rnk/django-media-bundler/tree... will help create image sprites so that your css background images are all one file request. CSS sprites are explained in more detail here http://alistapart.com/articles/sprites
April 24th, 2009 on 1:36 am
Have you taken a look at Beaker? You can cache slow functionsthen, so that only parts of a request are cached as needed. It's easier to use with django now as well, I just blogged about it's use as a library on groovie.org
April 24th, 2009 on 8:42 am
I haven't gotten into caching and increasing performance of my application code itself; I was starting with the server. Thanks for the suggestion. When I do get around to speeding up slow parts of my code, I'll keep Beaker in mind.
April 25th, 2009 on 12:37 pm
Added to http://tutlist.com
Great tutorial.
April 25th, 2009 on 2:42 pm
Thanks. I've never been to tutlist before. Sounds like a good idea.
April 29th, 2009 on 1:05 pm
Great post, even for us non-Djangoers.
One other tip on the serving-static-files thing: move them off your server entirely and don't even use the processing power. Store them on S3. From there, you can use the CDN and map multiple subdomains to the content, so you can spread your requests across multiple subdomains.
The reason for this is that web browsers will not open more than N connections to a given domain. Mapping them across multiple subdomains means that an image/static-heavy page will open even more connections and load concurrently.
April 29th, 2009 on 1:33 pm
Yeah amazon's content distribution network is awesome and not a bad price. I'd like to hook that up sometime soon. I didn't know that subdomains would help with the browser limit. That's a good idea.
April 29th, 2009 on 3:44 pm
I just installed django-memcache-status to see the usage of memcache in the django admin interface. It looks pretty good and it's easy to install. Just download it and add it to installed apps. http://github.com/bartTC/django-memcache-status/
January 7th, 2010 on 2:53 am
Hi there,
I don't quite understand here.
Will the django will automatically read the nginx “location /files” ???
Because I got a problem that it couldn't find the url in the urls.py when I tried to open http://localhost/media
Please help me out, Thanks a million !
February 11th, 2010 on 7:43 pm
Hey webmaster, good day. Totally Great work. You have gained a new fan. Please continue this awesome work and I look forward to see more of your excellent posts. Take care. http://www.telebisyonserye.info
March 17th, 2010 on 8:53 am
This is a great information I didn't know that subdomains would help with the browser limit. That's a good idea.
May 9th, 2010 on 1:57 am
I didn't know that Apache has some overhead involved that makes it good for serving php, python, or ruby applications.
May 15th, 2010 on 3:59 pm
Great!
I'm personally using Django compressor for my Django website.
It's very easy to use and I love the “no-settings” approach.
However be careful as by default CSS files are not minimized.
Also be careful not to try to minimize dynamically generated JS as it will try to minimize it each time it'll detect some changes.
June 23rd, 2010 on 3:39 am
[...] How to Speed up Your Django Sites with NginX, Memcached, and django-compress | Code Spatter (tags: apache development tutorial scalability yslow web python optimization cache caching deployment blog django performance programming lighttpd howto server speed tech webdev) Leave a Comment [...]
August 4th, 2010 on 8:56 pm
Honestly guys it works to my ubuntu box it was very useful thanks.
http://pacquiao-vs-margarito.watchonlines.com/
August 31st, 2010 on 4:05 am
This is a great information I didn't know that subdomains would help with the browser limit. That's a good idea.