Types of caching

From Browser to Database: Understanding the 7 Key Types of Caching

Mahabubur Rahman
7 min readOct 13, 2024

If you’re a software engineer, chances are you’ve heard the word “cache” thrown around in meetings, documentation, or even code reviews. It’s one of those terms that we all know is important, but sometimes we don’t dig deeper to fully understand the different types of caching or their real-world use cases. So, let’s take a moment to break down caching in simple, human-friendly terms.

Caching is a technique to store data in a way that makes it quicker to retrieve later on. This is particularly useful for expensive or repetitive operations, like fetching data from a slow external database, generating dynamic content, or performing complex calculations. Think of caching as a way to “remember” frequently used information, so we don’t have to go through the entire process to fetch it again.

There are several types of caching, and each has its specific role and use cases. Let’s explore the most common ones.

1. Browser Cache

What is it?

Your browser (like Chrome, Firefox, or Safari) automatically caches static files like images, CSS, and JavaScript from websites you visit. This allows the next page load to be much faster because your browser doesn’t have to download all those files again.

Use case:

When you visit a website like YouTube or Facebook for the second time, you’ll notice that it loads faster. That’s because the browser has stored elements like images, logos, or stylesheets locally on your device.

When to use it:

As a web developer, you can control the browser’s caching behavior by setting appropriate cache-control headers. If you’re working on a website where certain elements (like the company logo) don’t change often, browser caching is a no-brainer.

Cache-Control: public, max-age=31536000  // Cache for one year
app.use(express.static('public', {
maxAge: '1y' // Cache static assets for one year
}));

2. Memory Cache (In-Memory)

What is it?

Memory caching refers to storing frequently accessed data in the application’s memory (RAM) for faster retrieval. Tools like Redis or Memcached are popular choices for implementing this type of caching.

Use case:

Let’s say your app is fetching a list of popular products from a database over and over again. Instead of querying the database each time, you could cache that list in memory, making it accessible almost instantly.

When to use it:

Use memory caching when you need to access frequently requested data quickly. It’s ideal for things like session data, leaderboard scores, or frequently accessed database queries. However, be cautious with the size of your cache — RAM is limited and can get expensive if mismanaged.

const redis = require('redis');
const client = redis.createClient();

// Function to get popular posts from Redis or database
function getPopularPosts(req, res) {
client.get('popular-posts', (err, data) => {
if (data) {
return res.send(JSON.parse(data)); // Return cached data
} else {
// Simulate database query
const posts = database.getPopularPosts();
client.setex('popular-posts', 3600, JSON.stringify(posts)); // Cache for 1 hour
return res.send(posts);
}
});
}

3. CDN Cache (Content Delivery Network)

What is it?

A Content Delivery Network (CDN) is a global network of servers that store copies of your website’s static assets. The key benefit is that when a user requests data, it gets served from a location closest to them, reducing latency.

Use case:

Imagine you have users from all over the world visiting your website. By using a CDN like Cloudflare or Akamai, assets like images, videos, or CSS files are served from a nearby server, speeding up delivery.

When to use it:

CDNs are perfect for high-traffic websites or applications that need to deliver content to a global audience. They reduce the load on your origin servers and improve performance for users around the world.

app.use((req, res, next) => {
res.set('Cache-Control', 'public, max-age=604800'); // Cache for one week
next();
});

4. Database Cache

What is it?

Database caching involves storing results of database queries in memory or on disk to speed up future queries. Instead of querying the database every time, you pull the data from the cache.

Use case:

You’re running a query that retrieves the most viewed articles on your blog. Since this data doesn’t change every second, you can cache the result and refresh it every few minutes or when there’s new content.

When to use it:

Database caching is useful when you’re dealing with read-heavy applications, such as blogs, e-commerce sites, or reporting dashboards. It can help avoid putting too much pressure on your database and make your application more responsive.

const NodeCache = require('node-cache');
const cache = new NodeCache({ stdTTL: 300 }); // Cache for 5 minutes

async function getTopProducts(req, res) {
const cachedProducts = cache.get('top-products');

if (cachedProducts) {
return res.json(cachedProducts);
} else {
const products = await ProductModel.find().sort({ sales: -1 }).limit(10); // DB query
cache.set('top-products', products); // Cache result
return res.json(products);
}
}

5. Application-Level Cache

What is it?

This is where you manually implement caching in your app’s code. For example, you might cache an API response inside your server or even on the client-side, using a library like LocalStorage in a web browser.

Use case:

Let’s say your app relies on an external API that provides weather data. Instead of hitting the API every time a user visits the page, you could store the latest response in the app and only refresh the data when it’s necessary.

When to use it:

Application-level caching is often used when working with external APIs or microservices that are prone to slow response times. It gives you full control over what gets cached and for how long.

let cache = {};

function getConfig() {
if (!cache.config) {
// Simulate fetching configuration from database or file
cache.config = loadConfigurationFromDatabase();
}
return cache.config;
}

6. Distributed Cache

What is it?

A distributed cache stores data across multiple servers, allowing for higher availability and scalability. When your app is running in a cloud environment, you don’t want your cache to live on just one server. Tools like Redis and Memcached can also be deployed in a distributed fashion to handle large-scale caching.

Use case:

Imagine you’re running a popular online store during Black Friday. Millions of users are hitting your app at the same time. A distributed cache ensures that cached data is available to all users, regardless of which server they’re connected to.

When to use it:

This is great for applications that need to scale horizontally, meaning they can run on multiple servers or instances at the same time, like social networks or large e-commerce sites.

const redis = require('redis');
const client = redis.createClient();

function getUserData(userId, callback) {
client.get(userId, (err, data) => {
if (data) {
callback(null, JSON.parse(data)); // Return cached data
} else {
// Simulate database query
const user = database.getUserById(userId);
client.setex(userId, 3600, JSON.stringify(user)); // Cache for 1 hour
callback(null, user);
}
});
}

7. Persistent Cache

What is it?

Persistent caching stores data in a way that survives a server restart. Unlike memory caching, which is volatile, persistent caching ensures that the cached data is still there even if your app or server goes down.

Use case:

You’re running a task that processes user uploads. To ensure faster uploads, you cache the processed files in a persistent store like a local database or a file system. This way, if your server restarts, users don’t lose access to their uploaded content.

When to use it:

Persistent caching is useful when you need durability in your cache — such as caching user-generated content or slow-to-generate data that you don’t want to reprocess every time.

const cacheManager = require('cache-manager');
const fsStore = require('cache-manager-fs');

// Set up disk cache
const diskCache = cacheManager.caching({
store: fsStore,
options: {
ttl: 60, // Cache for 1 minute
maxsize: 1000 * 1000 * 1000, // 1 GB cache limit
path: 'cache', // Directory to store cache
preventfill: false
}
});

async function getData() {
const cachedData = await diskCache.get('my-key');
if (cachedData) {
return cachedData;
} else {
const data = await fetchExpensiveData(); // Simulate expensive operation
await diskCache.set('my-key', data, { ttl: 300 }); // Cache for 5 minutes
return data;
}
}

Choosing the Right Cache

Choosing the right caching strategy depends on your use case. If you’re building a high-traffic website, a combination of browser, CDN, and memory caching can dramatically reduce load times. For apps that rely on frequent database queries, in-memory database caching (e.g., Redis) can offload pressure from your database.

Whatever the case, caching is about making your app faster, more efficient, and scalable. Just remember, like all things in software, caching comes with trade-offs — especially in terms of cache invalidation and data consistency. But used correctly, caching can be a game-changer for performance and scalability.

Conclusion: Caching isn’t just a technical term — it’s a vital strategy for making your apps run faster and more smoothly. Whether you’re speeding up database queries or reducing server load during high-traffic periods, choosing the right type of cache for the job is essential. Now that you know the different types of caching, you’re better equipped to make the right decisions for your next project!

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Mahabubur Rahman
Mahabubur Rahman

Written by Mahabubur Rahman

Software Engineer | Full Stack Developer | Competitive Programmer | Data Science Practitioner

No responses yet

Write a response