Search code examples
c#asp.netasp.net-web-api

MemoryCache SetSize, does it limit cache entry size


I'm planning to use MemoryCache in my asp.net webapi project. Samples I found are using the below:

            var cacheEntryOptions = new MemoryCacheEntryOptions()
                    .SetSlidingExpiration(TimeSpan.FromSeconds(600))
                    .SetAbsoluteExpiration(TimeSpan.FromSeconds(3600))
                    .SetPriority(CacheItemPriority.Normal)
                    .SetSize(1024);

            _cache.Set(myKey, myData, cacheEntryOptions);

I wasn't sure what SetSize does exactly, is that limiting the max size of the above cache entry? Is it in kB, mB? For example, one of the calls we are going to cache shows in chrome dev tools as returning data of size 3.3kB, if I add something which exceeds the above limit (1024) does that then not cache or throw an exception as it's large than the limit allowed?


Solution

  • So it works little bit differently from what you expect.

    As stated in MS IMemoryCache docs, there's no measurement unit to handle cache size. So the developer (you) is responsible for handling all of that.

    So in order to limit size of cache, you need to define it in registration phase:

    builder.Services.AddMemoryCache(setup => setup.SizeLimit = 100);
    

    And thing you have notices: SetSize method - it only assigns the size to the entry, telling cache how much "space" it occupies.

    And if you are adding cache with limited size, if the size is not limited, Set method does not throw exception, the entry simply is not added.

    You can try with this code:

    using Microsoft.Extensions.Caching.Memory;
    
    var builder = WebApplication.CreateBuilder(args);
    builder.Services.AddEndpointsApiExplorer();
    builder.Services.AddSwaggerGen();
    builder.Services.AddMemoryCache(setup => setup.SizeLimit = 100);
    
    var app = builder.Build();
    app.UseSwagger();
    app.UseSwaggerUI();
    app.UseHttpsRedirection();
    
    app.MapGet("/", (IMemoryCache cache) =>
    {
        for (int i = 1; i < 1000; i++)
        {
            _ = cache.Set(Guid.NewGuid(), '*', new MemoryCacheEntryOptions().SetSize(1));
        }
    })
    .WithOpenApi();
    
    app.Run();
    

    After running this code snippet you will see that only 100 items are added to cache, not 1000.