Three Strategies for Caching Paginated List Results
This article explains three progressively refined approaches to caching paginated list data—directly caching whole pages, caching individual object entries after querying ID lists, and caching both ID lists and object entries—highlighting trade‑offs, implementation details, and performance considerations using Java and Redis.
1. Directly Cache Paginated List Results
The simplest solution is to cache the entire page result after querying with specific pagination parameters.
Pseudo‑code:
public List<Product> getPageList(String param, int page, int size) {
String key = "productList:page:" + page + "size:" + size + "param:" + param;
List<Product> dataList = cacheUtils.get(key);
if (dataList != null) {
return dataList;
}
dataList = queryFromDataBase(param, page, size);
if (dataList != null) {
cacheUtils.set(key, dataList, Constants.ExpireTime);
}
}The advantage is simplicity and speed, but the granularity is large; any data change requires invalidating the whole page cache, which can be done lazily via expiration or by using Redis keys (not recommended in production due to performance impact).
2. Query Object ID List, Then Cache Each Object Entry
To achieve finer granularity, first retrieve a list of object IDs for the requested page, then cache each object individually and assemble the list for the client.
Core steps:
Query the database for a paginated list of product IDs.
Batch‑fetch the cached product objects using mget (or hmget for hashes).
Identify IDs that missed the cache.
Batch‑query the missing objects from the database and write them back to the cache.
Assemble the final ordered list from the cached map.
Key code snippets:
// From DB query paginated product ID list
List<Long> productIdList = queryProductIdListFromDabaBase(param, page, size); SELECT id FROM products ORDER BY id ASC LIMIT (page-1)*size, size; Map<Long, Product> cachedProductMap = cacheUtils.mget(productIdList); List<Long> noHitIdList = new ArrayList<>(cachedProductMap.size());
for (Long productId : productIdList) {
if (!cachedProductMap.containsKey(productId)) {
noHitIdList.add(productId);
}
} List<Product> noHitProductList = batchQuery(noHitIdList); Map<Long, Product> noHitProductMap =
noHitProductList.stream()
.collect(Collectors.toMap(Product::getId, Function.identity()));
cacheUtils.mset(noHitProductMap);
cachedProductMap.putAll(noHitProductMap); for (Long productId : productIdList) {
Product product = cachedProductMap.get(productId);
if (product != null) {
result.add(product);
}
}This approach reduces cache size per entry, improves consistency handling, and still benefits from batch operations for both cache and DB access.
3. Cache Object ID List and Each Object Entry Simultaneously
When dealing with high‑traffic feeds (e.g., social‑media timelines), store the ordered list of IDs in a Redis ZSet and cache each object's details separately.
Redis ZSet stores members (object IDs) with scores (e.g., creation timestamps). Pagination is achieved with ZREVRANGE to retrieve a range of IDs in descending order.
After obtaining the ID list, batch‑fetch the full objects (details, comments, likes, etc.) using pipeline or Lua scripts for maximum throughput, then assemble the final response.
4. Summary
The article presented three increasingly granular caching strategies for paginated data:
Directly cache the whole page result.
Cache each object after querying a paginated ID list.
Cache both the ID list (via ZSet) and each object entry.
The key take‑aways are fine‑grained cache control and batch loading of objects to achieve high performance while maintaining data consistency.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Sohu Tech Products
A knowledge-sharing platform for Sohu's technology products. As a leading Chinese internet brand with media, video, search, and gaming services and over 700 million users, Sohu continuously drives tech innovation and practice. We’ll share practical insights and tech news here.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
