Caching: How to Improve your Application's Performance (with Redis)
Introduction
Caching is the practice of storing previously calculated results to avoid the need for subsequent calculations, saving time and computational resources 🚀
There are several ways to implement caching, from the use of in-memory variables to more robust and reliable solutions, such as dedicated databases. These services manage and store data efficiently.
One of the most popular caching systems is Redis, and this is the one we will use in this guide.
We will explore in practice how to implement caching and apply this technique in production environments. Although we will use Ruby to make the explanation easier, the concepts can be applied in any language.
Setup
What you will need 📝
Programming language (we will use Ruby)
Docker (to run the Redis server) 🐋
Now that Docker is configured and installed on your machine, let's run the following command:
docker run -d -p 6379:6379 -i -t redis
This command starts the Redis server using the latest version of the official image.
After running, we can check if the server is running with:
docker ps
The expected output will be something similar to this:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
986bb85320f8 redis "docker-entrypoint.s…" 11 seconds ago Up 10 seconds 0.0.0.0:6379->6379/tcp, :::6379->6379/tcp focused_jang
Note that the STATUS column should contain the word Up, indicating that the server is running.
Creating the caching file
Now, let's create a file in Ruby to implement caching. We chose Ruby for its didactics, but you can use any other language.
Code structure
=
= Redis.new(host: , port: 6379)
stored_value = REDIS.get(CACHE_KEY_ID)
if stored_value.nil?
stored_value = Net::HTTP.get(URI())
REDIS.set(CACHE_KEY_ID, stored_value, ex: 3600)
end
stored_value
Code explanation
Initialization and configuration:
=
= Redis.new(host: , port: 6379)
- We import the
redis-rblibrary, which allows communication with Redis. In Python, for example, the equivalent library would beredis-py - We define CACHE_KEY_ID, the key used to store and retrieve data in the cache. This key serves as a unique identifier, similar to an ID in a database
- We create the Redis instance, configuring the IP (127.0.0.1) and the port (6379), which are the same values used when running the server in Docker
Caching logic:
stored_value = REDIS.get(CACHE_KEY_ID)
if stored_value.nil?
stored_value = Net::HTTP.get(URI())
REDIS.set(CACHE_KEY_ID, stored_value, ex: 3600)
end
stored_value
Here we perform two main operations: reading and writing to the cache.
- Cache verification
- First, we try to get the value stored in Redis.
- If the value already exists, it will be used and we avoid making a new request.
- Storing the value
- If the value is not stored (
nil), we fetch the HTML page by making aGETrequest - Then, we store the content in Redis with an expiration time of 1 hour (
ex: 3600) - This way, new requests within this period will reuse the saved value, avoiding unnecessary requests to the external site
- Returning the value
- At the end, we return
stored_value, which will contain the cached value or, if necessary, the newly fetched content.
Benefits 🚀
In our example, using a cache significantly improves application performance because:
- It avoids repeated requests to external services, reducing response time.
- It ensures that data is accessed more quickly (user experience).
This strategy allows the application to respond much more efficiently to consumers.
Caching Uses
✅ When to Use
- Data that changes little (e.g. product lists, settings)
- External APIs with request limits (e.g. exchange rates, weather forecasts)
- Heavy database queries (e.g. reports, dashboards)
- Data frequently accessed by many users (e.g. promotional banners)
❌ When Not to Use
- Data that changes constantly (e.g. order status, real-time chats)
- When accuracy is essential (e.g. bank balance, inventory)
- Sensitive or temporary data (e.g. authentication tokens)
Conclusion
If you have any questions, queries or suggestions, don't hesitate to contact me 😊
REDIS.set("new-learning-in-caching", this.post)
Thanks for reading!! 🍻