.NET
Caching
Sliding Expiration
Software Development
ASP.NET

.NET Caching how does Sliding Expiration work?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Sliding expiration means a cache entry stays alive as long as it keeps getting used within a configured time window. Every successful access pushes the expiration deadline forward, so frequently used items remain cached while inactive ones age out automatically.

The Basic Idea

Suppose an entry has a sliding expiration of 10 minutes. If nobody reads it for 10 minutes, it expires. If code reads it after 6 minutes, the timer resets, and the new expiration point becomes 10 minutes from that read.

That makes sliding expiration very different from absolute expiration:

  • absolute expiration removes the item at a fixed time
  • sliding expiration removes the item after a period of inactivity

Sliding expiration is useful for session-like data, frequently reused lookup results, and other values that should stay warm only while they are actively needed.

Example with IMemoryCache

In ASP.NET Core, a common implementation uses IMemoryCache and MemoryCacheEntryOptions.

csharp
1using Microsoft.Extensions.Caching.Memory;
2
3public sealed class ProductService
4{
5    private readonly IMemoryCache _cache;
6
7    public ProductService(IMemoryCache cache)
8    {
9        _cache = cache;
10    }
11
12    public string GetProductName(int id)
13    {
14        return _cache.GetOrCreate($"product:{id}", entry =>
15        {
16            entry.SlidingExpiration = TimeSpan.FromMinutes(10);
17            return $"Product {id}";
18        })!;
19    }
20}

Every cache hit on product:42 refreshes the inactivity window. If the key is not touched for 10 minutes, it becomes eligible for removal.

Combine Sliding and Absolute Expiration

A very common production pattern is to combine sliding expiration with an absolute upper bound. That prevents a hot item from living forever.

csharp
1var options = new MemoryCacheEntryOptions
2{
3    SlidingExpiration = TimeSpan.FromMinutes(10),
4    AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1)
5};
6
7_cache.Set("settings", "cached value", options);

With this configuration:

  • each access keeps the item alive within the 10-minute inactivity window
  • the item still expires after one hour total, no matter how often it is used

That pattern is safer for data that should eventually refresh even under steady traffic.

Important Behavior Detail

Sliding expiration is refreshed by cache access, not by the mere existence of the item. If the key sits in memory and nothing calls Get, TryGetValue, or equivalent access paths, the sliding timer is not extended.

Also remember that expiration is not always enforced by a literal timer firing at the exact millisecond. Many cache implementations remove expired items during normal cache activity or cleanup cycles. So think in terms of expiration eligibility, not precise stopwatch behavior.

Older MemoryCache Style

The same concept exists in older .NET caching APIs as well:

csharp
1using System;
2using System.Runtime.Caching;
3
4ObjectCache cache = MemoryCache.Default;
5var policy = new CacheItemPolicy
6{
7    SlidingExpiration = TimeSpan.FromMinutes(5)
8};
9
10cache.Set("user:1", "Alice", policy);

The API shape changes, but the rule stays the same: each successful access resets the inactivity window.

Common Pitfalls

  • Assuming sliding expiration is the same as absolute expiration.
  • Forgetting that frequently accessed items can remain cached indefinitely unless you add an absolute cap.
  • Expecting expiration to happen at an exact instant rather than during cache maintenance and access flow.
  • Using sliding expiration for data that must refresh on a strict schedule.
  • Believing writes or background existence alone refresh the sliding timer when the real trigger is cache access.

Summary

  • Sliding expiration removes cache entries after a period of inactivity.
  • Each successful access resets the inactivity window.
  • It is useful for data that should stay cached only while it remains active.
  • Combine it with absolute expiration when you need a maximum lifetime.
  • Use it for access-driven freshness, not for strict time-based refresh guarantees.

Course illustration
Course illustration

All Rights Reserved.