Skip to content

Fix TTL rounding to match Redis behavior#1602

Open
badrishc wants to merge 7 commits intomainfrom
badrishc/fix-ttl-rounding-1389
Open

Fix TTL rounding to match Redis behavior#1602
badrishc wants to merge 7 commits intomainfrom
badrishc/fix-ttl-rounding-1389

Conversation

@badrishc
Copy link
Collaborator

@badrishc badrishc commented Mar 4, 2026

Redis rounds TTL seconds to the nearest integer (equivalent to (ms+500)/1000), while Garnet was truncating (flooring) via a direct (long) cast. This caused SET+EXPIRE 10+TTL to return 9 instead of 10 when called immediately.

Fix: Use Math.Round(MidpointRounding.AwayFromZero) in both SecondsFromDiffUtcNowTicks and MillisecondsFromDiffUtcNowTicks in ConvertUtils.cs.

Added TtlRoundingTest to verify string and object keys return the expected TTL value immediately after EXPIRE.

Fixes #1389

Redis rounds TTL seconds to the nearest integer (equivalent to (ms+500)/1000),
while Garnet was truncating (flooring) via a direct (long) cast. This caused
SET+EXPIRE 10+TTL to return 9 instead of 10 when called immediately.

Fix: Use Math.Round(MidpointRounding.AwayFromZero) in both
SecondsFromDiffUtcNowTicks and MillisecondsFromDiffUtcNowTicks in
ConvertUtils.cs.

Added TtlRoundingTest to verify string and object keys return the expected
TTL value immediately after EXPIRE.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 4, 2026 21:12
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Align Garnet TTL/expiration remaining-time calculations with Redis’ rounding semantics, and add a regression test to prevent TTL off-by-one behavior immediately after setting an expiry.

Changes:

  • Update tick-to-seconds and tick-to-milliseconds conversions to round to nearest integer (AwayFromZero) instead of truncating.
  • Add a new test verifying TTL immediately after EXPIRE matches the requested TTL for both string and sorted set keys.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.

File Description
test/Garnet.test/RespTests.cs Adds a regression test covering TTL rounding behavior right after EXPIRE.
libs/common/ConvertUtils.cs Changes remaining-time conversions to use rounding (vs truncation) to match Redis behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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.

TTL discrepency between redis and garnet

2 participants