Skip to content

Serializers

django-cachex supports pluggable serializers for data before sending to Valkey/Redis.

Configuration

CACHES = {
    "default": {
        "BACKEND": "django_cachex.cache.ValkeyCache",
        "LOCATION": "valkey://127.0.0.1:6379/1",
        "OPTIONS": {
            "serializer": "django_cachex.serializers.json.JsonSerializer",
        },
    }
}

Available Serializers

Serializer Description Extra
django_cachex.serializers.pickle.PickleSerializer Python pickle (default); supports nearly all Python types (stdlib)
django_cachex.serializers.json.JsonSerializer JSON via Django's DjangoJSONEncoder (broadest Django type coverage of the JSON family) (stdlib)
django_cachex.serializers.msgpack.MsgpackSerializer Pure-Python MessagePack; compact binary format msgpack
django_cachex.serializers.orjson.OrjsonSerializer Rust-backed JSON; fewer types than DjangoJSONEncoder orjson
django_cachex.serializers.ormsgpack.OrmsgpackSerializer Rust-backed MessagePack ormsgpack

Install optional serializers via the matching extra:

uv add django-cachex[msgpack]
uv add django-cachex[orjson]
uv add django-cachex[ormsgpack]

Type compatibility

Round-trip behaviour for common Python types. Legend: preserved (same type back), ~ encoded but returns as a different type (caller must convert on read), raises SerializerError on dumps.

Type pickle json (Django) msgpack orjson ormsgpack
Throughput vs pickle¹ 1.00× 0.72× 1.06× 1.10× 1.13×
JSON primitives (str, int, float, bool, None, list, dict)
bytes
tuple ~ list ~ list ~ list ~ list
set / frozenset
datetime / date / time ~ str ~ str ~ str
timedelta ~ str
Decimal ~ str
UUID ~ str ~ str ~ str
complex
dataclass instance ~ dict ~ dict
Enum ~ value ~ value

¹ End-to-end Django cache → redis-rs adapter → localhost Valkey, ~150 B payload, geometric mean of get/set/mget/mset ops/sec. Real network or larger payloads dampen the spread. Reproduce with the benchmarks harness.

Notes:

  • The "~" cells are not bugs; they reflect what the underlying format can represent. Decimal("1.99") round-trips through DjangoJSONEncoder as the string "1.99"; if you need a Decimal back, convert on read.
  • orjson natively encodes dataclass and Enum values, but loses the original type on the way back (becomes a dict or the underlying value).
  • For arbitrary Django model instances or types not listed above, prefer pickle or write a custom serializer.
  • If you need maximum speed and your values are JSON-compatible (or you pre-convert Decimal/datetime to strings), orjson and ormsgpack are significantly faster than the pure-Python equivalents.

Fallback for Migration

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

"OPTIONS": {
    "serializer": [
        "django_cachex.serializers.json.JsonSerializer",     # Write with new format
        "django_cachex.serializers.pickle.PickleSerializer", # Read old format
    ],
}

Custom Serializers

Subclass BaseSerializer and implement _dumps and _loads. The base class wraps any exception they raise in SerializerError (which triggers the fallback chain) and passes plain ints through loads unchanged, so incr() results don't need re-decoding:

from django_cachex.serializers.base import BaseSerializer


class MySerializer(BaseSerializer):
    def _dumps(self, obj):
        return my_encode(obj)  # must return bytes

    def _loads(self, data):
        return my_decode(data)