LazyLayersv0.5.3
Concepts

Serialization

Understand encoded values, default compression, and independent L1 and L2 write policies.

Built-in L1 and Redis L2 retain encoded values. This makes payload retention measurable and prevents a later L1 hit from sharing the original mutable object. Encoding and decoding cost CPU, so choose a policy using your payload sizes and latency budget.

Default encoding

Values use MessagePack. Compression is selected from the packed size:

Packed sizeCodec attempted
Below 256 bytesNone
256 bytes to below 4 KiBLZ4
4 KiB or moreZstd when available in node:zlib, otherwise LZ4

The compressed payload is kept only when it saves at least 15% compared with packed MessagePack. Otherwise the value stays uncompressed. auto selects these same default tiers.

Compression is lossless. Selecting JSON changes value semantics: use JSON-compatible records, because Date, Map, and typed arrays do not retain their JavaScript types through JSON serialization.

Choose codecs per layer

L1 and L2 can use different write policies in 0.5.3. For example, you can avoid compression CPU for L1 writes while retaining the default size tiers for Redis:

src/cache/index.js
import { setupCache } from 'lazy-layers-cache'

export const cache = await setupCache({
  namespace: 'catalog-api',
  redis: { required: true },
  levels: {
    L1: { codec: { format: 'msgpack', compression: 'none' } },
    L2: { codec: { format: 'msgpack', compression: 'auto' } },
  },
})

Measure before choosing this override. Uncompressed L1 uses more of the byte budget. Matching L1 and L2 policies let the cache reuse encoded bytes during promotion, while differing policies require re-encoding.

The configuration reference lists formats, compression shorthands, custom tiers, and process-wide defaults.

Read compatibility

Every encoded value identifies its format with a four-byte tag:

TagStored representation
HC1MMessagePack
HC1LLZ4-compressed MessagePack
HC1ZZstd-compressed MessagePack
HC1GGzip-compressed MessagePack
HC1SSnappy-compressed MessagePack
HC1JJSON

Changing a write policy does not rewrite existing entries. Readers choose the decoder from the tag, independently of their write policy. The LZ4 and Snappy modules ship as dependencies. Zstd support depends on the Node.js runtime.

An unknown tag, unavailable decoder, or corrupt payload decodes to null, which built-in stores treat as a miss. That can increase origin traffic. Before changing a fleet's write codec, verify every reader supports it. See the Redis key-layout migration separately when upgrading the storage layout.

Measure your values

Use a representative application value and an explicit policy when comparing encodings:

inspect-codec.mjs
import { serializeWithStats } from 'lazy-layers-cache'

const value = { id: '42', name: 'Ada', plan: 'pro' }
const stats = serializeWithStats(value, {
  format: 'msgpack',
  compression: 'auto',
})

console.log({
  encoding: stats.encoding,
  originalBytes: stats.originalBytes,
  storedBytes: stats.storedBytes,
  compressionRatio: stats.compressionRatio,
})

storedBytes includes the wire tag. For MessagePack, originalBytes is the packed size and compressionRatio is the fraction saved by compression. These are payload measurements, not total Node.js or Redis memory usage.

Use the benchmark harness for repeatable comparisons on your runtime. Use observability to inspect stored encodings and sizes in a running cache.

Where to next

On this page