Skip to content

perf: replace JSON+base64 cache envelope with compact binary framing #37

Description

@matthewdevenny

Problem

Every cached value is wrapped in a JSON CacheEntry (src/NatsDistributedCache/NatsCache.cs), whose Data is a byte[]. System.Text.Json serializes byte[] as base64 — roughly 33% size inflation — plus a JSON serialize/parse on every Set/Get.

Investigation

The natural "store raw bytes + put expiration in NATS message headers" approach is blocked on the read path: NatsKVEntry<T> exposes no Headers (only Bucket/Created/Delta/Error/Key/Operation/Revision/Value), so header metadata can't be recovered through the standard KV read API without dropping to raw JetStream.

Proposal

Replace the JSON envelope with a custom INatsSerialize<CacheEntry> / INatsDeserialize<CacheEntry> using compact binary framing, e.g.:

[version:1][flags:1][absExpTicks:8][slidingExpTicks:8][raw payload …]

No base64, no JSON; metadata stays in the value (no dependency on header reads). A leading version byte allows future format evolution.

Acceptance criteria

  • Stored size ≈ payload + small fixed header (no base64).
  • Absolute + sliding expiration round-trip correctly.
  • version byte present and checked on read.
  • Benchmark demonstrates reduced bytes and allocations vs. the current JSON path.

Notes / risk

Breaking on-wire format change. Bump the format version and document that pre-existing entries should be treated as misses (or add a one-version read shim for a transition window). This is the biggest single efficiency lever and deserves its own design pass.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions