{"id":46106,"library":"redis-expiry","title":"redis-expiry","description":"A Redis-based key expiration and event scheduling library for Node.js (v1.1.8). It allows scheduling key expiration via timeout, absolute date, cron pattern, or immediate expiry, and provides event handlers that fire when keys expire, including regex pattern matching. Unlike simple Redis TTL, redis-expiry persists scheduled expirations across application restarts by storing metadata in Redis. Supports CRUD operations and rescheduling. Suitable for timed tasks, cron jobs, and cache invalidation with guaranteed execution after restart. Release cadence is sporadic; last update was 2020.","status":"active","version":"1.1.8","language":"javascript","source_language":"en","source_url":"https://github.com/dobobaie/redis-expiry","tags":["javascript","redis","expire","handling","value","keys","trigger","timed","scheduler"],"install":[{"cmd":"npm install redis-expiry","lang":"bash","label":"npm"},{"cmd":"yarn add redis-expiry","lang":"bash","label":"yarn"},{"cmd":"pnpm add redis-expiry","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Required for Redis client instances passed during initialization","package":"redis","optional":false},{"reason":"Used internally for cron expression parsing when using the .cron() method","package":"cron-parser","optional":true}],"imports":[{"note":"This package is CommonJS only; ESM import will fail.","wrong":"import redisExpiry from 'redis-expiry';","symbol":"default","correct":"const redisExpiry = require('redis-expiry');"},{"note":"Since v1.0.4, the second argument must be a Redis client (getter), not a URL. The URL overload is deprecated.","wrong":"const rexp = redisExpiry(redisSetter, process.env.REDIS_URL);","symbol":"function redisExpiry(setterClient, getterClient)","correct":"const rexp = redisExpiry(redisSetter, redisGetter);"},{"note":"The callback receives (value, key, stop). When using regex pattern, the callback is invoked per matching key.","wrong":"rexp.on(/pattern/, function(value) { /* ... */ });","symbol":"rexp.on(event, callback, options)","correct":"rexp.on(/pattern/, (value, key) => { /* ... */ });"},{"note":"All scheduling methods return a Promise; you must await or handle .then() to ensure the key is set before expiration.","wrong":"rexp.set('key', 'val').timeout(60000);","symbol":"rexp.set(key, value).timeout(ms)","correct":"await rexp.set('key', 'val').timeout(60000);"}],"quickstart":{"code":"const Redis = require('redis');\nconst redisExpiry = require('redis-expiry');\n\nconst redisSetter = Redis.createClient(process.env.REDIS_URL ?? 'redis://localhost:6379');\nconst redisGetter = Redis.createClient(process.env.REDIS_URL ?? 'redis://localhost:6379');\n\nconst rexp = redisExpiry(redisSetter, redisGetter);\n\n// Schedule a key to expire in 10 seconds\nawait rexp.set('myKey', 'myValue').timeout(10000);\n\n// Listen for expiration\nrexp.on('myKey', (value, key) => {\n  console.log(`Key ${key} expired with value: ${value}`);\n});\n\n// Cancel the scheduled expiration\nawait rexp.del('myKey');","lang":"javascript","description":"Initializes redis-expiry with two Redis clients, schedules a key to expire in 10 seconds, attaches an expiration handler, then removes the scheduler."},"warnings":[{"fix":"Pass a second Redis client instance instead: redisExpiry(setterClient, getterClient).","message":"Passing a Redis URL as second argument to redisExpiry() is deprecated since v1.0.4.","severity":"deprecated","affected_versions":">=1.0.4"},{"fix":"Always await the result of rexp.set(...).timeout(...) or chain .then() to ensure scheduling completes.","message":"The set() method returns an object with scheduling methods (.timeout, .at, .cron, etc.) that are not executed until awaited. Forgetting await may cause the key to never expire.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Implement your own reconnection logic on the Redis clients, or use a single client and pass it twice (though this may risk blocking).","message":"The package uses two separate Redis connections (setter and getter) but does not handle disconnection or reconnection. If a connection drops, events may be lost or the library may hang.","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"In your handler callback, accept the third argument 'stop' and call stop() when you want to halt the cron repetition.","message":"Cron-based expiration with .cron() reschedules after each expiration. To stop it, the handler must call the provided stop() function; otherwise, the cron continues indefinitely.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Set the 'maxConcurrent' option in rexp.on(pattern, callback, { maxConcurrent: 1 }) to serialize callbacks for the same pattern.","message":"Event handlers registered with regex patterns (e.g., /myKeyBy(.)/) listen to all keys matching the pattern. If multiple keys match, the handler is invoked for each expiration concurrently unless maxConcurrent is specified.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"search_vec":"'2020':88 'absolut':24 'across':54 'allow':18 'applic':55 'base':7 'cach':74 'cadenc':82 'cron':26,71 'crud':63 'date':25 'event':11,33 'execut':78 'expir':9,21,39,53,91 'expiri':3,30,50 'fire':36 'guarante':77 'handl':92 'handler':34 'immedi':29 'includ':40 'invalid':75 'javascript':89 'job':72 'key':8,20,38,94 'last':85 'librari':13 'match':43 'metadata':59 'node.js':15 'oper':64 'pattern':27,42 'persist':51 'provid':32 'redi':2,6,46,49,61,90 'redis-bas':5 'redis-expiri':1,48 'regex':41 'releas':81 'reschedul':66 'restart':56,80 'schedul':12,19,52,97 'simpl':45 'sporad':84 'store':58 'suitabl':67 'support':62 'task':70 'time':69,96 'timeout':23 'trigger':95 'ttl':47 'unlik':44 'updat':86 'v1.1.8':16 'valu':93 'via':22","created_at":"2026-06-07T12:58:18.643274+00:00","updated_at":"2026-06-07T12:58:18.643274+00:00","problems":[{"fix":"Use require('redis-expiry') instead, or use dynamic import if you must use ESM: const redisExpiry = (await import('redis-expiry')).default;","cause":"Using ESM import 'import redisExpiry from 'redis-expiry'' on a CommonJS-only package.","error":"TypeError: redisExpiry is not a function"},{"fix":"Create a second Redis client and pass it: redisExpiry(setterClient, getterClient).","cause":"Passing a Redis URL string as the second argument instead of a client instance (changed in v1.0.4).","error":"Error: The second argument must be a redis client"},{"fix":"Ensure both Redis clients are connected before initializing redis-expiry. Use Redis client's 'ready' event or connect() method.","cause":"The Redis client connection is not ready or disconnected.","error":"UnhandledPromiseRejectionWarning: TimeoutError: The set operation timed out"},{"fix":"Verify the cron expression format (e.g., '*/4 * * * * *' for every 4 seconds). Refer to https://www.npmjs.com/package/cron-parser for valid syntax.","cause":"Cron expression passed to .cron() is invalid or incompatible with cron-parser.","error":"AssertionError [ERR_ASSERTION]: Invalid cron expression"}],"ecosystem":"npm","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":null,"cli_version":null,"type":"library","homepage":"https://github.com/dobobaie/redis-expiry#readme","github":"https://github.com/dobobaie/redis-expiry","docs":null,"changelog":null,"pypi":null,"npm":"redis-expiry","openapi_spec":null,"status_page":null,"smithery":null,"categories":["database","devops"],"base_url":null,"auth_type":null,"provenance":{"verified_status":null,"verified_at":null,"last_verified":"2026-06-07","next_check":"2026-09-05","install_tag":null}}