November 7th: Exploring an 80% lower cost hosted Redis alternative - register

Redis Update Value Without Changing TTL in Node.js (Detailed Guide w/ Code Examples)

Use Case(s)

Updating a value in Redis without altering its associated Time To Live (TTL) is useful for maintaining existing expiry policies. Common use cases include:

  • Caching: Updating cached data while preserving the original expiration time.
  • Session management: Maintaining user sessions without extending or resetting their valid period.
  • Temporary key-value storage: Adjusting values stored temporarily without changing their lifespan.

Code Examples

Example 1: Using MULTI/EXEC Transaction

This example shows how to update a value and keep the TTL intact using a transaction.

const redis = require('redis'); const client = redis.createClient(); async function updateValueWithoutChangingTTL(key, newValue) { client.multi() .ttl(key) .set(key, newValue) .ttl(key, function(err, ttl) { if (err) throw err; if (ttl > 0) { this.expire(key, ttl); } }) .exec((err, replies) => { if (err) { console.error('Transaction failed:', err); } else { console.log('Transaction successful:', replies); } client.quit(); }); } updateValueWithoutChangingTTL('myKey', 'newValue');

Explanation:

  1. Start a transaction using multi().
  2. Retrieve the TTL of the key using ttl(key).
  3. Update the value with set(key, newValue).
  4. Set the TTL back to its original value if it was positive using expire(key, ttl).
  5. Execute the transaction with exec().

Example 2: Using Lua Scripting for Atomic Operation

Using a Lua script ensures the operation is atomic, preventing race conditions.

const redis = require('redis'); const client = redis.createClient(); const script = ` local ttl = redis.call("TTL", KEYS[1]) if ttl > 0 then redis.call("SET", KEYS[1], ARGV[1]) redis.call("EXPIRE", KEYS[1], ttl) else redis.call("SET", KEYS[1], ARGV[1]) end return ttl `; async function updateValueWithoutChangingTTL(key, newValue) { client.eval(script, 1, key, newValue, (err, result) => { if (err) { console.error('Script execution failed:', err); } else { console.log(`Updated key '${key}' with TTL:`, result); } client.quit(); }); } updateValueWithoutChangingTTL('myKey', 'newValue');

Explanation:

  1. Define a Lua script that gets the TTL, updates the value, and re-applies the TTL if it's positive.
  2. Execute the script using client.eval.

Best Practices

  • Use Transactions or Lua Scripts: Ensure atomicity to avoid race conditions.
  • Check Key Existence: Handle cases where the key might not exist or has no TTL (-1).

Common Mistakes

  • Forgetting to Reapply TTL: Not setting the TTL back can lead to unintended behavior.
  • Ignoring Errors: Always handle potential errors when dealing with Redis operations.

FAQs

Q: What happens if the key does not have an expiration? A: If the key does not have an expiration (TTL returns -1), these methods will simply update the value without setting any TTL.

Q: Can I use other Redis clients besides node-redis to achieve this? A: Yes, similar logic applies to other Redis clients; you would need to adapt the syntax accordingly.

Was this content helpful?

Switch & save up to 80% 

Dragonfly is fully compatible with the Redis ecosystem and requires no code changes to implement. Instantly experience up to a 25X boost in performance and 80% reduction in cost