What is Caching? Caching in Django with Redis.
In modern web development loading time of a webpage is fundamental to obtaining and retaining users. There are multiple ways to optimize your site to reduce the load time, one of the ways is by caching web pages that perform heavy queries on the database. This will reduce database hits hence a faster load. So what is caching? 🤷🏾
Caching is storing data in a cache, a temporary storage area that facilitates faster access to data to improve application and system performance.
Picture it like this …
Let’s say you have a large library full of books. You retrieve a book and then return it to the library after usage. When you need the same book again, you’ll have to search for the book in the library once again which will take more time. With the concept of caching, what you can do is, once you obtain the book instead of returning it you can put it on your desk, next time you need the book its retrieval will be quick hence less time taken.
Redis is an open-source, in-memory key-value data store used as a database, cache, and message broker.
One of the key features of Redis Cache is its Time To Live (TTL) feature.
Time To Live (TTL) is a feature of Redis Cache that allows users to set an expiration time for their data. This means that the data will be automatically deleted after the expiration time has passed
1. Setting up cache backend in Django.
We now set up a backend where our cached data will live — whether it’s the database, filesystem, or Redis which is what we are using today.
Your cache preference goes in the CACHES
setting in your settings file as shown below.
Redis
Redis as cache.
Set up a Redis server. You can start a Redis server locally or on a remote machine.
Starting Redis server with docker.
$ docker run -d -p 6379:6379 redis
#Test if the server is running 👇
# for windows users use wsl to run linux commands
$ sudo apt install redis
$ redis-cli
#Once the Redis terminal opens, type PING the server should respond with PONG which means the server is up and running.
Instead of using Docker, you could also use third-party services such as Redislabs which have a free tier option.
2. Configure the CACHES setting.
$ pip install django-redis
Assuming we’ve used Docker to start our Redis server.
# settings.py
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379/1", # for third-party services use the connection string provided instead
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
}
}
The cache backend is now fully set up.
Now we need to identify the data to be cached and set an expiration time for the cached data.
There are 4 ways of performing caching in Django:
a) Per-site cache
This is caching your entire site. It’s the simplest way however it’s costly since caching your entire site will lead to more usage of your production infrastructure which leads to high costs.
Implementation.
# settings.py
MIDDLEWARE = [
"django.middleware.cache.UpdateCacheMiddleware", # add this middleware
"django.middleware.common.CommonMiddleware",
"django.middleware.cache.FetchFromCacheMiddleware", # add this middleware
]
CACHE_MIDDLEWARE_SECONDS = 60 * 15 # time the cached data should last
N/B -> Middleware order matters
b) Per-view cache
Here we cache the output of individual views. This gives you more control over your cached data when compared to the per-site cache.
from django.views.decorators.cache import cache_page
@cache_page(60 * 15)
def my_view(request):
...
#cache_page decorator takes a single argument: the cache timeout, in seconds
c) Template-fragment caching
If you’re after even more control, you can also cache template fragments using the cache template tag. To give your template access to this tag, put {% load cache %}
near the top of your template.
The {% cache %}
template tag takes at least two arguments, cache_timeout in seconds, and the name to give the cache fragment.
Implementation
{% load cache %}
{% cache 500 sidebar %}
.. sidebar ..
{% endcache %}
d) Low-level cache API
We can use this to cache the results of expensive queries instead of caching a whole page.
Check out the docs for more info on low-level cache API.
Django’s cache framework docs.
Thanks for reading 💚
Happy coding 🧑🏾💻