Skip to content

Compression

Aghogho Bernard edited this page May 6, 2026 · 1 revision

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.

Enabling Compression

builder.Services.AddCacheWeave(options =>
{
    options.EnableCompression = true;
});

That is the only change required. The CompressingCacheProvider decorator is wired automatically around ICacheProviderInner.

How It Works

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.

When to Use Compression

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%

Custom Compressor

Implement ICacheCompressor and register it before AddCacheWeave:

public interface ICacheCompressor
{
    byte[] Compress(string value);
    string Decompress(byte[] data);
}

Example — Brotli Compressor

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;
});

Migrating Existing Entries

Enabling or disabling compression changes the stored format. Existing entries written without compression cannot be decompressed, and vice versa. To migrate safely:

  1. Bump CacheWeaveOptions.KeyVersion (e.g. "v1""v2") — all old keys are ignored and new entries are written in the new format.
  2. Old entries expire naturally according to their TTL.
  3. Remove the old KeyVersion after all old entries have expired.

Clone this wiki locally