Skip to content

perf: store Redis buffers without base64#10

Merged
lan17 merged 2 commits into
mainfrom
codex/binary-redis-payloads
Jul 13, 2026
Merged

perf: store Redis buffers without base64#10
lan17 merged 2 commits into
mainfrom
codex/binary-redis-payloads

Conversation

@lan17

@lan17 lan17 commented Jul 12, 2026

Copy link
Copy Markdown
Owner

Summary

DialCache serializers already support string | Buffer, but the Redis path converted every Buffer to base64 before invoking Lua and decoded it after reads. That expanded binary payloads by roughly one third and added avoidable allocations on both sides of Redis.

This change stores Buffer serializer output byte-for-byte while keeping the existing one-round-trip, Lua-backed cache protocol.

Closes #6.

Design

Semantic Redis client boundary

DialCacheRedisClient now exchanges serialized cache payloads directly as string | Buffer.

Core DialCache no longer exposes or interprets Redis wire encodings. It passes serializer output unchanged to the configured semantic client and passes the client's decoded payload directly to serializer.load.

This keeps the boundary independent of node-redis. A future Valkey GLIDE adapter can use GLIDE's own script lifecycle, cluster routing, and byte decoder while implementing the same semantic interface.

Wire protocol

The existing frame version and key suffix remain unchanged because DialCache is new and has no deployed compatibility requirement:

byte 1      format version = 1
bytes 2-9   Redis-created timestamp in milliseconds
byte 10     payload encoding: 0 = UTF-8, 1 = raw binary
bytes 11... serialized payload

Encoding 1 previously identified base64 text. It now identifies raw binary. No migration or mixed-version compatibility layer is included.

Lua continues to:

  • create timestamps from Redis server time;
  • atomically validate tracked writes against invalidation watermarks;
  • preserve one Redis round trip per read or write;
  • operate on binary-safe Redis/Lua strings.

node-redis adapter

The node-redis adapter now:

  • passes Buffer script arguments directly instead of converting to base64;
  • requests Buffer replies so arbitrary bytes never pass through UTF-8 decoding;
  • decodes encoding 0 to a string and returns encoding 1 as a Buffer;
  • keeps node-redis-specific command options and script registration outside core DialCache.

The public protocol export renames REDIS_ENCODING_BASE64 to REDIS_ENCODING_BINARY.

Behavior and compatibility

  • JSON and other string serializers retain their existing UTF-8 behavior.
  • Buffer serializers receive byte-identical Buffer values on cache reads.
  • Empty buffers remain distinguishable from cache misses.
  • Malformed encoding values retain the dedicated DialCacheRedisPayloadEncodingError path and metrics label.
  • Existing experimental Redis entries should be flushed; no compatibility behavior is needed for this pre-release, unused library.

Performance

A directional sequential write/read benchmark against local Redis 6.2 showed:

Payload Raw stored bytes Base64 stored bytes Raw p50 / p99 Base64 p50 / p99
1 KiB 1,034 1,378 0.53 / 0.73 ms 0.51 / 0.61 ms
64 KiB 65,546 87,394 1.02 / 2.73 ms 1.20 / 2.92 ms
1 MiB 1,048,586 1,398,114 8.29 / 9.46 ms 11.69 / 14.77 ms

These local Docker results are directional rather than production latency predictions. Stored size is deterministically the payload plus the 10-byte frame header.

Validation

  • corepack pnpm typecheck
  • corepack pnpm test — 90 unit tests with coverage thresholds
  • corepack pnpm build
  • corepack pnpm test:package
  • packaged consumer under Node 18.20.8
  • corepack pnpm test:integration — 35 tests across:
    • Redis 6.2
    • Valkey 8
    • three-node Redis 7 Cluster
  • raw binary cases:
    • empty Buffer
    • all 256 byte values
    • invalid UTF-8 sequences
    • 2 MiB Buffer
    • tracked and untracked operations
    • node-redis cluster Buffer arguments, replies, and frame storage
  • corepack pnpm audit --prod — no known vulnerabilities
  • git diff --check

@lan17 lan17 marked this pull request as ready for review July 13, 2026 01:28
@lan17 lan17 merged commit dfbd453 into main Jul 13, 2026
3 checks passed
@lan17 lan17 deleted the codex/binary-redis-payloads branch July 13, 2026 01:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Explore binary-safe Redis payloads without base64 expansion

1 participant