Recommended resources
The freely available resources this lesson will direct you to.
Introduction
In our previous lesson, we explored how asynchronous communication with message queues decouples services, making our systems more resilient and scalable. We addressed the problem of services failing or slowing down by breaking their direct, temporal dependencies. Now that we have a robust communication backbone, our focus shifts to another critical aspect of high-performance system design: speed. How do we ensure our application feels "instant" to the user and avoids overwhelming our databases?
This lesson delves into the world of caching, a fundamental technique for dramatically improving application performance and reducing costs. You will learn to explain and contrast the most common caching strategies used in modern web applications: in-memory caching, database-level caching, and Content Delivery Networks (CDNs). Understanding the trade-offs of each is a hallmark of a senior developer who designs systems that are not only functional but also fast, efficient, and cost-effective.
1. The Core Principle of Caching
At its heart, caching is simple: it's the practice of storing a copy of frequently accessed data in a temporary, fast-access storage location. The goal is to avoid repeating expensive operations, such as complex database queries, calls to external services, or intensive computations. Think of it as keeping your most-used reference books on your desk instead of walking to the library every time you need to look something up.
The core mechanics of any cache revolve around a few key terms:
- Cache Hit: The requested data is found in the cache. This is the ideal scenario—it's fast.
- Cache Miss: The requested data is not in the cache. The application must then retrieve the data from the original source (the "source of truth," like a database), which is slower. Typically, the data is then placed in the cache for future requests.
- Time to Live (TTL): An expiration date set on cached data. After the TTL, the data is considered "stale" and removed from the cache to ensure that users don't see outdated information.
System Design Fundamentals | Caching | by Shobhit Chauhan | Dev Genius
This article from Dev Genius provides an excellent introduction to the fundamental concepts of caching.
Read the first two sections, Why Caching Matters and the key players. Focus on understanding the flow of a data request and the definitions of a cache hit, a cache miss, and TTL.
The benefits of a well-implemented caching strategy are significant: reduced latency for users, lower load on your backend services and databases, and consequently, reduced infrastructure costs.
2. Layers of Caching: From Application to the Edge
Caching isn't a single solution but a multi-layered strategy. Different types of caches are used at various points in a system's architecture, each optimized for a specific purpose. Let's explore the three main strategies you'll encounter as a backend developer.

In-Memory Caching
This is the fastest form of caching available to your application. Data is stored directly in the application's memory (RAM).
There are two main flavors:
- Local (In-Process) Cache: The cache lives inside a single instance of your application. For a Java/Spring Boot developer like yourself, libraries like Caffeine or Ehcache are common choices. They are extremely fast as there are no network calls involved.
- Distributed Cache: The cache is an external service shared by multiple instances of your application. Systems like Redis and Memcached are industry standards. They introduce a network call, making them slightly slower than a local cache, but they solve a critical problem for distributed systems.
Trade-offs:
- Pros: Extremely low latency, especially for local caches. Great for storing data that is expensive to compute or fetch, like user sessions or results of complex queries.
- Cons:
- Volatility: Data in RAM is lost if the application or server restarts (though some systems like Redis offer persistence options).
- Limited Capacity: RAM is more expensive and limited than disk storage.
- Inconsistency (for Local Caches): If you run multiple instances of your application, each will have its own local cache. If one instance updates a piece of data, the other instances' caches become stale. This is why distributed caches like Redis are essential for horizontally scaled services.
Choosing the Right Caching Strategy - Java
This article is highly relevant to your background, as it discusses caching within the context of Java and Spring Boot.
First, read the section on in-memory caching, which introduces Caffeine. Then, jump to the section on Redis. Notice how the author positions local caches for single services and Redis for scalable, distributed systems.
Database-Level Caching
Databases themselves are highly optimized and employ their own internal caching mechanisms to speed up performance. This type of caching is often transparent to you as an application developer but is crucial for the database's efficiency.
Examples include:
- Buffer Pool / Page Cache: The database keeps frequently accessed data blocks from disk in memory. When you query for data, the database first checks this memory buffer before reading from the much slower disk.
- Query Cache: Some databases cache the results of identical
SELECTqueries. If the same query is run again, the result is returned from the cache instead of re-executing it (though this is less common in modern databases due to invalidation complexities). - Materialized Views: A pre-computed result set of a query, stored as a physical table. This is useful for complex analytical queries or reports that are run frequently.
Trade-offs:
- Pros: Managed automatically by the database, requiring no application code. It directly speeds up query execution at the source.
- Cons: It's a "black box" with limited control. It only caches data or query results, not the output of your application's business logic. It may not be sufficient for applications with extremely high read traffic, where an external cache like Redis is still needed to shield the database.
Cache Systems Every Developer Should Know
This short video from ByteByteGo provides a great visual overview of the different caching layers in a system.
Watch the segment on database caching. It concisely explains the roles of the buffer pool and materialized views.
Content Delivery Network (CDN) Caching
While in-memory and database caches optimize your backend, CDNs optimize the delivery of content to the end-user, no matter where they are in the world. A CDN is a geographically distributed network of servers that caches static assets like images, videos, CSS, and JavaScript files.
When a user requests a file, the request is routed to the nearest CDN "edge server" instead of your origin server.
Trade-offs:
- Pros: Drastically reduces latency for users far from your origin server. It offloads a significant amount of traffic, reducing the load and bandwidth costs on your main application servers. CDNs also often provide additional security benefits like DDoS protection.
- Cons: Primarily designed for static or infrequently changing public content. Caching dynamic, user-specific content is more complex. There's an additional cost, and managing cache invalidation across the globe (known as "purging") can be challenging.
The Ultimate Guide to Caching and CDNs
This video clearly explains how CDNs work and their role in a caching strategy.
Watch the section explaining what CDNs are and how they function. Pay attention to the distinction between "pull-based" and "push-based" CDNs, as this relates to how content gets onto the CDN in the first place.
3. The Hardest Problem: Cache Invalidation
There's a famous saying in computer science: "There are only two hard things: cache invalidation and naming things." Cache invalidation is the process of ensuring that stale data is removed or updated in the cache when the source of truth (the database) changes. If you fail at this, you risk serving incorrect, outdated information to your users.
There are several strategies, each with its own trade-offs regarding consistency and performance.
- Write-Through: The application writes data to the cache and the database simultaneously.
- Pro: The cache is always consistent with the database.
- Con: Every write operation is slower because it has to complete two writes.
- Write-Back (or Write-Behind): The application writes data only to the fast cache and immediately returns. The cache then asynchronously writes the data to the database later.
- Pro: Write operations are extremely fast.
- Con: There's a risk of data loss if the cache fails before the data is persisted to the database. The system is "eventually consistent."
- Write-Around: The application writes data directly to the database, bypassing the cache entirely. The data only gets into the cache on a subsequent read miss.
- Pro: Write operations are fast, and the cache isn't filled with data that might never be read again.
- Con: A read request immediately following a write will result in a cache miss, increasing latency for that specific flow.
The Ultimate Guide to Caching and CDNs
Let's revisit the same video, as it has a clear, concise explanation of these write policies.
Watch the segment on server-side caching, which covers the write-around, write-through, and write-back strategies. This is a crucial concept in system design.
Beyond these write policies, you also need an eviction policy for when the cache is full. The most common is Least Recently Used (LRU), where the data that hasn't been accessed for the longest time is removed to make space for new data.
Conclusion
In this lesson, you've moved from building robust systems to building fast ones. You've seen that caching is not a single tool but a layered approach to performance optimization, from your application's memory all the way to the user's geographical location.
Key Takeaways:
- Caching's Purpose: To improve performance and reduce load by storing copies of data in faster, closer storage locations.
- In-Memory Caching (e.g., Redis, Caffeine): Offers the lowest latency but is volatile and has capacity limits. Essential for scalable applications to share state.
- Database Caching: An internal optimization within the database that speeds up queries but offers limited control and scope.
- CDN Caching: A geographically distributed network for serving static content close to users, drastically reducing global latency.
- Trade-offs are Everything: The choice of caching strategy is a constant balance between performance, cost, and data consistency.
- Cache Invalidation is Hard: Strategies like TTL, write-through, and write-back present different trade-offs between data freshness and write performance.
We've now covered how services communicate (synchronously and asynchronously), how they store data, and how they speed up access to that data. The next logical question is: how do we handle increasing amounts of traffic? In our next lesson, we will explore horizontal vs. vertical scaling and the critical role of a load balancer in distributing requests across your application servers.