Redis TTL Converter

Paste TTL values, either bare numbers or durations like 3d, and get milliseconds, seconds, a human reading and the commands that set them. The two sentinel replies are called out rather than converted.

TTL returns seconds, PTTL returns milliseconds. A duration like 3d or 90m is understood whichever is selected.

Paste below, or drop a file anywhere on this panel

Or drop a file anywhere on this panel. Nothing is uploaded: the analysis runs in this tab.

The answer appears here

Paste on the left and press Convert. Nothing leaves this tab.

Examples

Real input you can load into the tool above. Each one shows a different thing going wrong, because that is what the tool is for.

The two sentinels

-1 and -2 are replies, not durations, and mean very different things

3600
-1
-2

Human durations

A duration converted to the EXPIRE and PEXPIRE calls that set it

3d
90m
12h

Common mistakes

These are the ones that fail silently. The config is accepted, nothing raises an error, and the consequence arrives later.

  1. Treating -1 and -2 as durations

    They are sentinels. -1 means the key exists with no expiry and -2 means it does not exist, so a dashboard averaging TTLs quietly folds negative numbers into the mean.

    Instead:Filter them out and count them separately. They answer a different question from a remaining lifetime.

  2. Refreshing a value with a plain SET

    SET clears an existing expiry. A refresh path written this way silently makes keys permanent, which shows up as a cache that stops evicting and grows.

    Instead:SET ... KEEPTTL to preserve it, or SET ... EX to set both atomically.

  3. Setting the key and its expiry in two commands

    If the process dies between them the key exists with no TTL, forever. It is also two round trips.

    Instead:SET key value EX seconds does both atomically in one call.

TTL answers three different questions with one number

A positive reply is a remaining lifetime. The two negative replies are not lifetimes at all, and treating them as numbers is how a monitoring dashboard ends up with a negative average TTL.

-1 means the key exists and will never expire

Usually this is intentional. When it is not, the cause is almost always a plain SET: SET overwrites a key's expiry, so a code path that refreshes a value with SET rather than SET ... KEEPTTL silently makes it permanent. PERSIST does the same thing deliberately.

-2 means the key does not exist

It may have expired, it may have been evicted under maxmemory pressure, or it may never have been written. TTL cannot distinguish those, and neither can EXISTS. Eviction and expiry look identical from the outside, which is why an unexplained -2 usually needs the INFO stats for evicted_keys and expired_keys to resolve.

EXPIRE takes whole seconds

Sub-second lifetimes need PEXPIRE. EXPIRE rounds, so a value under a second becomes zero or one rather than what you meant. Setting a key and its expiry in one call with SET key value EX or PX is both fewer round trips and atomic, which matters because a SET followed by a separate EXPIRE can leave a permanent key if the process dies between them.

Expiry is lazy plus sampled

A key with a past expiry is not deleted at that instant. Redis removes it when something touches it, and separately samples random keys twenty times a second to expire a fraction of those found dead. So a key can be logically gone while still occupying memory, which is why memory does not drop the moment a large batch of TTLs passes.

What this cannot see

It converts numbers. It does not know when a key was written, so it cannot tell you the absolute time a key expires, and it cannot tell you whether a TTL you are about to set is longer than the key will survive under your eviction policy.