Skip to content

Skip tracked Redis refills that remain behind the observed watermark #141

Description

@lan17

Summary

Avoid serializing and writing a tracked Redis refill when its exact client-clock timestamp is still at or behind the watermark observed by the authoritative read.

This is a conditional optimization, not a rule to skip every watermark miss.

Follow-up to #140 and #139.

Problem

A tracked semantic miss currently falls back to the source and attempts a complete-frame SET. When the read observed watermark W and the refill would be stamped N <= W, that frame is known to remain unreadable. The work is wasted:

  • serializer and compression CPU;
  • frame allocation and client bookkeeping;
  • payload network transfer;
  • Redis command processing; and
  • replication and AOF traffic.

This matters during future-buffer and clock-skew windows, especially for high-write caches with large values.

We must not skip unconditionally. A miss proves only that the old frame is fenced. For example, an old frame at 90 misses against watermark 100, but a refill stamped 105 is valid and should replace it. Always skipping could force source fallbacks until the old frame's physical TTL expires.

Proposed behavior

Carry the valid numeric watermark observed by the tracked MGET through the semantic read result. After fallback, sample one candidate createdAtMs and apply:

candidateCreatedAtMs <= observedWatermarkMs  => skip refill
candidateCreatedAtMs >  observedWatermarkMs  => write using that exact timestamp

The skip should happen before serializer dump, compression, frame allocation, and adapter dispatch. When writing, pass the same sampled timestamp through the Redis write request so the eligibility decision and stored frame cannot diverge.

Apply the same rule to caller-path and shadow fills. A skipped shadow fill must have an honest bounded outcome such as fill_fenced; it must not report filled.

Constraints

  • No Redis TIME.
  • No Lua, transaction, conditional server-side payload write, or additional Redis round trip.
  • No value-envelope, key, or watermark-encoding change.
  • Preserve the existing tracked local-publication suppression behavior.
  • Missing or malformed watermark metadata retains current refill behavior unless there is a separately justified safe rule.
  • A later concurrent invalidation may still fence a dispatched write. Avoiding that race would require server-side coordination and is out of scope.

Adapter design

The current adapter contract collapses absent, malformed, unsupported, and watermark-fenced reads to null, so core cannot make this decision. Introduce the smallest typed read-result extension that can carry an observed numeric write fence.

Existing custom adapters that return null should remain correct and simply miss the optimization where practical. Document any source-compatibility impact if the read result or RedisWriteRequest changes. The stored protocol remains unchanged.

Acceptance criteria

  • Old frame 90, watermark 100, candidate 105: write and produce a subsequent tracked hit.
  • Old frame 90, watermark 110, candidate 105: skip before serialization and Redis dispatch.
  • Candidate equal to the watermark: skip.
  • Non-watermark misses preserve their existing refill behavior.
  • Caller-path and shadow fills follow the same fence decision; shadow metrics do not report a skipped write as filled.
  • Node-redis and GLIDE have identical command and timestamp behavior.
  • A concurrent later invalidation remains safe even if it fences a write admitted against the earlier snapshot.
  • Tests cover custom-adapter compatibility, serializer/compression avoidance, large payloads, and real Redis/Valkey behavior.
  • Benchmarks or command assertions demonstrate zero SET calls for known-fenced refills and no added commands for valid refills.
  • README and adapter-contract documentation explain the conditional rule and compatibility impact.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions