Skip to content

Compression

django-cachex supports pluggable compression to reduce memory usage. Compression is only applied to values larger than 256 bytes by default.

Configuration

CACHES = {
    "default": {
        "BACKEND": "django_cachex.cache.ValkeyCache",
        "LOCATION": "valkey://127.0.0.1:6379/1",
        "OPTIONS": {
            "compressor": "django_cachex.compressors.zstd.ZstdCompressor",
        },
    }
}

Minimum Size

min_length is a constructor argument of the compressor, not a cache OPTIONS key. It defaults to 256, so payloads at or below 256 bytes are stored uncompressed. Raise the threshold by configuring a compressor instance instead of a dotted path:

from django_cachex.compressors.zstd import ZstdCompressor

CACHES = {
    "default": {
        "BACKEND": "django_cachex.cache.ValkeyCache",
        "LOCATION": "valkey://127.0.0.1:6379/1",
        "OPTIONS": {
            "compressor": ZstdCompressor(min_length=1024),
        },
    }
}

A subclass works too, and stays configurable by dotted path:

class LargeOnlyZstdCompressor(ZstdCompressor):
    min_length = 1024

Available Compressors

Compressor Extra
django_cachex.compressors.zlib.ZlibCompressor (stdlib)
django_cachex.compressors.gzip.GzipCompressor (stdlib)
django_cachex.compressors.lzma.LzmaCompressor (stdlib)
django_cachex.compressors.lz4.Lz4Compressor lz4
django_cachex.compressors.zstd.ZstdCompressor (stdlib on 3.14+)

Install optional dependencies:

uv add django-cachex[lz4]

Performance

Two views; pick whichever matches the decision you're making.

Micro: algorithm in isolation

Pure compress/decompress in a tight loop, no driver, no network. Output size is a percentage of the input (i.e. the no-compression baseline); compress/decompress are absolute MB/s on the benchmark host.

Compressor Output size¹ Compress² Decompress²
zlib 12% ~190 MB/s ~1.3 GB/s
gzip 12% ~150 MB/s ~1.2 GB/s
lzma 11% ~13 MB/s ~490 MB/s
lz4 17% ~3.1 GB/s ~7.7 GB/s
zstd 11% ~820 MB/s ~2.2 GB/s

Macro: end-to-end via Django cache

Same compressors, but measured through cache.get() / cache.set() / cache.get_many() / cache.set_many() against a real Valkey server. Throughput factor is normalized to no compression, so the table reads "this is what enabling each compressor costs you."

Compressor Throughput vs no-compression³
no compression 1.00×
zlib 0.70×
gzip 0.65×
lzma 0.26×
lz4 0.99×
zstd 0.90×

Picking guide:

  • zstd: same ratio as lzma at ~60× the compress speed, and only ~10 % slower end-to-end than no compression at all. Default choice if available.
  • lz4: pick when CPU is the bottleneck and a ~40 % larger payload is acceptable. End-to-end throughput is statistically indistinguishable from no compression while still cutting payload size 6×.
  • lzma: pick only when output size matters more than write latency. Even then, zstd is usually a better trade now (same ratio, ~3× faster end-to-end).
  • zlib / gzip: nearly identical. Pick zlib unless you need gzip's framing for an external consumer.
  • No compression: sets the throughput ceiling but stores ~8× more server memory. Outside narrow latency-critical paths, compression almost always wins.

¹ Compressed size as a percentage of the input (~14 KiB pickled queryset-shaped payload). ² Absolute compress/decompress throughput in a tight loop (200 ops × 20 runs, median, single core). Numbers are hardware-dependent; use the ratios between rows, not the absolute values. Real-world impact also depends on payload compressibility (text/JSON compresses ~10×; already-compressed bytes barely shrink). ³ Geometric mean of get/set/mget/mset ops/sec end-to-end via Django cache → redis-rs adapter → localhost Valkey, normalized to running without a compressor. Reproduce with the benchmarks harness.

Fallback for Migration

Specify a list of compressors to safely migrate between formats. The first is used for writing, all are tried for reading:

"OPTIONS": {
    "compressor": [
        "django_cachex.compressors.zstd.ZstdCompressor",  # Write with new format
        "django_cachex.compressors.gzip.GzipCompressor",  # Read old format
    ],
}