Caching is one of the easiest ways to improve your website’s performance. In this post I’ll describe how adding caching to your Django site can reduce page load time down to milliseconds across an entire site.

What is Caching?

Every time a user requests a URL on your Django site, the web server makes multiple calculations to create the final page your visitor sees: database queries, template rendering, view logic, and more. This is a slow and computationally expensive process for your server.

With caching, we can save the result of an expensive calculation so you don’t have to perform the same calculation again. Instead the result is stored, and served, from a cache. This is a much, much faster approach.

Django provides built-in support for one of the most popular types of cache, Memcached, which is used by companies including Facebook, YouTube, and Twitter.

Django Caching Options

In Django there are four different caching options in descending order of granularity:

1) The per-site cache is the simplest to setup and caches your entire site.

2) The per-view cache lets you cache individual views.

3) Template fragment caching lets you specify a specific section of a template to cache.

4) The low-level cache API lets you manually set, retrieve, and maintain specific objects in the cache.

Why not just cache everything all the time? The short answer is that cache memory is expensive. With Memcached, our cache is stored as RAM. If you think of a typical computer, it has two types of storage: a hard drive and RAM. Hard drives typically have hundreds if not thousands of gigabytes of storage; RAM rarely exceeds 16 gigabytes.

As a result, for a medium to large site, a simple per-site cache may not be sufficient. Hence the need for the more granular caching options Django provides.

Setup the Per-Site Cache

In your settings file, update MIDDLEWARE_CLASSES with two new lines so that it reads as follows (make sure the order is exactly like this, with the “update” middleware first):

MIDDLEWARE_CLASSES = [
    django.middleware.cache.UpdateCacheMiddleware,
    django.middleware.common.CommonMiddleware,
    django.middleware.cache.FetchFromCacheMiddleware,
]

Next add 3 additional settings fields below MIDDLEWARE_CLASSES:

CACHE_MIDDLEWARE_ALIAS = 'default'
CACHE_MIDDLEWARE_SECONDS = 604800 			
CACHE_MIDDLEWARE_KEY_PREFIX = ‘’

At this point, the only setting you might want to adjust is CACHE_MIDDLEWARE_SECONDS which is the default number of seconds to cache a page. After the period is up, the cache expires and becomes empty. A good default when starting out is 604800 seconds or 1 week (60secs x 60minutes x 168hours) for a site with content that doesn’t change very often. But if you find your cache filling up rapidly or you are running a site where the content changes on a frequent basis, shortening this setting is a good step to start.

Setup the Cache

Now we need to setup the cache itself. This part can be tricky. For experienced developers, Django provides an in-depth overview of how to install a Memcached binding and update your BACKEND settings for it to run.

If you’re a beginner, I strongly recommend using a Platform-as-a-Service such as Heroku for your hosting as it makes life much simpler when starting out. Even better, with one line you can install django-heroku-memcacheify to setup Memcached via the add-on Memcachier.

Wrap Up

Caching is an essential part of modern websites. With Django and Memcached, it is relatively easy to implement and will dramatically improve your website’s performance.

Next Steps

Check out Django for Beginners, a free online book on how to create and deploy multiple Django applications. Starting with a simple “Hello, World” application it progresses through multiple web applications of increasing complexity showing Django best practices along the way.