-
Notifications
You must be signed in to change notification settings - Fork 0
Compression
CacheWeave supports optional GZip compression of cached values before they are written to the backing store. This reduces memory usage and network bandwidth at the cost of CPU time.
builder.Services.AddCacheWeave(options =>
{
options.EnableCompression = true;
});That is the only change required. The CompressingCacheProvider decorator is wired automatically around ICacheProviderInner.
When EnableCompression = true, ICacheProvider resolves to CompressingCacheProvider, which wraps the registered ICacheProviderInner:
Write path:
object → ICacheSerializer.Serialize → JSON string
→ ICacheCompressor.Compress → byte[]
→ Convert.ToBase64String → stored string
Read path:
stored string → Convert.FromBase64String → byte[]
→ ICacheCompressor.Decompress → JSON string
→ ICacheSerializer.Deserialize → object
When EnableCompression = false, ICacheProvider resolves directly to ICacheProviderInner — no Base64 encoding, no compression overhead.
| Scenario | Recommendation |
|---|---|
| Large JSON payloads (> 1 KB) | Enable — significant size reduction |
| Small payloads (< 200 bytes) | Disable — GZip overhead exceeds savings |
| Redis with memory pressure | Enable |
| InMemory provider | Disable — no network or storage cost |
| High-throughput, CPU-bound workloads | Benchmark first |
Typical compression ratios for JSON:
| Payload | Uncompressed | Compressed | Ratio |
|---|---|---|---|
| Product list (50 items) | ~12 KB | ~1.8 KB | 85% |
| Single product detail | ~800 B | ~420 B | 47% |
| Config object | ~200 B | ~180 B | 10% |
Implement ICacheCompressor and register it before AddCacheWeave:
public interface ICacheCompressor
{
byte[] Compress(string value);
string Decompress(byte[] data);
}using System.IO.Compression;
public class BrotliCacheCompressor : ICacheCompressor
{
public byte[] Compress(string value)
{
var input = Encoding.UTF8.GetBytes(value);
using var output = new MemoryStream();
using (var brotli = new BrotliStream(output, CompressionLevel.Fastest))
brotli.Write(input, 0, input.Length);
return output.ToArray();
}
public string Decompress(byte[] data)
{
using var input = new MemoryStream(data);
using var brotli = new BrotliStream(input, CompressionMode.Decompress);
using var output = new MemoryStream();
brotli.CopyTo(output);
return Encoding.UTF8.GetString(output.ToArray());
}
}Register before AddCacheWeave:
builder.Services.AddSingleton<ICacheCompressor, BrotliCacheCompressor>();
builder.Services.AddCacheWeave(options =>
{
options.EnableCompression = true;
});Enabling or disabling compression changes the stored format. Existing entries written without compression cannot be decompressed, and vice versa. To migrate safely:
- Bump
CacheWeaveOptions.KeyVersion(e.g."v1"→"v2") — all old keys are ignored and new entries are written in the new format. - Old entries expire naturally according to their TTL.
- Remove the old
KeyVersionafter all old entries have expired.