DjangoCon 2011 – Deployment, Daemons and Datacenters

Following a great talk on Security in Django we now have “Deployment, Daemons and Datacenters” by Andrew Godwin. This talk will go into the deployment strategies at

A tour through the systems that power, the Python hosting platform, from the array of daemons powering the system, to how redundancy is set up, and also covering general best practices for hosting Django sites yourself.

Updates Below:


End of the talk. I’ll try to post the slides once they’re available.


“Have you dealt with the fact that different people have different laws with regards to Backups?”

In the EU you cannot export data outside of the country. You need to be aware of the different laws. Often good idea to keep backups in the same country, but different cities.


“Why did you move from AWS to your own hardware?”

A combination of performance. When you looked at the cost per dollar it was cheaper to have their own hosted service. Disk IO is a lot faster on their own hardware than virtualized hosts.


“How do you handle file uploads with multiple application servers?”

Uses on a shared server.


Andrews done talking. Question time.


Standard tools aren’t always the best.

  • load balancer was initially HAProxy (doesn’t like having 3000 backends being reloaded every 10 seconds)
  • Custom eventlet-based load-balancer was simpler and slightly faster



  • Use Puppet or Chef along with Fabric
  • If you do something more than three times, automate it
  • Everything you manually SSH in, a kitten gets extremely worried


Loose Coupling

  • Simple, loosely-connected components
  • Easier to test and easier to debug
  • Enforces some rough interface definitions


Plan for multiple machines
  • That means no SQLite in production (doesn’t work for multiple machines)
  • Make good use of database transactions
  • How are you going to store uploaded files?


Sensible Architecture

Ship long-running tasks off:

  • Use celery, or your own worker solution
  • Even more critical if you have syncrhonous worker threads in your web apps
  • Email sending can be very slow


An easy start…

  • Dump your database nightly to a SQL file
  • Use rdiff-backup (or similar)_ to sync your DB dump, codebase and uploads to a backup directory
  • Also sync offsite – get a VPS with a different provider than your main one
  • Make your backup server pull the backups, don’t push them to it.


Replication is Hard

  • PostgreSQL and Redis replication both require your code to be modified a bit
  • Django offers some help with database routers
  • It’s also not always necessary and can cause bugs for your users (small sites may not be the answer)


Check your backups restore

  • Just seeing if they’re there isn’t good enough
  • Try restoring your entire site onto a fresh box


Backups before any major change in the database or code.

“It’s tedious but the one time you need it it’ll help you”


Never back up to the same provider. They can cancel your account…


Backups and Redundancy

Archives != High Availability

  • Your PostgreSQL slave is not a backup
  • You should backup using multiple formats to diverse locations


Development and Staging

  • No need to run gunicorn/nginx locally (runserver still works)
  • PostgreSQL 9 still slightly annoying to install
  • Redis is very easy to set up
  • Staging should be EXACTLY the same as live


How to handle higher loads:

  • Varnish for site caching
  • HAProxy or Nginx for load-balancing
  • Give PostgreSQL more resources

17.36 Stack

Three years ago

  • Apache and mod_wsgi
  • PostgreSQL 8.x
  • Memcached
  • Nginx (static files/gzipping)
  • Gunicorn (dynamic pages, unix socket best)
  • PostgreSQL 9
  • Redis
  • virtualenv



  • treas their internal network as public (any traffic has to be signed/encrypted)
  • Firewalling of unnecessary ports
  • Separate machines for higher-risk processes


The Joy of Networks

  • Any network has a significant slowdown compared to local access
  • Locking and concurrent access also an issue
  • Internal latency on EC2 can peak higher than 10s
  • Routing blips can cause very short outages


More statistics

15 requests, some git some pypi

  • Traditional: 300 seconds
  • Parellised, no cache: 30 seconds
  • Parellised, cache: 2 seconds


They run a parallel version of pip (with caching). Not 100% compatible with complex dependencies


Some information

  • Everytime an app is uploaded to it gets a fresh app image to deploy into
  • Each app image has its own virtualenv
  • The typical has around 3 or 4 dependencies
  • Some have more than 40


Using ZeroMQ and Eventlet works well together.


Eventlet is…

  • Coroutine-based asynchronous concurrency
  • Basically, lightweight threads with explicit context switching
  • Reads quite like procedural code


Redundancy’s not easy.

Serveral things can only run once (cronjobs)


sock = ctx.socket(zmq.REQ)
for endpoint in self.config.query_addresses():

payload = json.dumps({'type':type, 'extra':extra})

with Timeout(30):
    return self.decode_message(sock.recv())


ZeroMQ & Redundancy

  • Not a message queue
  • Advanced sockets, with multiple endpoints
  • Has both deliver-to-single-consumer and deliver-to-all-consumers
  • Uses TCP for transport



  • Hosts Python sites/daemons
  • Technically language-independent
  • Supports multiple kinds of databases


Andrew is taking the stage.

Andrew is…

  • Core Developer
  • South author
  • Cofounder of


Everyone just getting settled. Stay tuned.