{"id":46074,"library":"redfour","title":"redfour","description":"A Redis-based binary semaphore implementation using pub/sub for fast async wait, unlike polling-based alternatives. Version 2.2.2 is the latest stable release. Key differentiator: uses Redis pub/sub to notify waiters when a lock is released, making it much faster than polling-based locks. Supports Node >=7.6.0. Ideal for coordinating access to shared resources (e.g., token refresh) across multiple processes or servers.","status":"active","version":"2.2.2","language":"javascript","source_language":"en","source_url":"https://github.com/mixmaxhq/redfour","tags":["javascript","redis","semaphore","mutex","node"],"install":[{"cmd":"npm install redfour","lang":"bash","label":"npm"},{"cmd":"yarn add redfour","lang":"bash","label":"yarn"},{"cmd":"pnpm add redfour","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Required to connect to Redis and create client(s) for pub/sub and lock operations.","package":"redis","optional":false}],"imports":[{"note":"Default export is the Lock class. Named export does not exist.","wrong":"const { Lock } = require('redfour')","symbol":"Lock","correct":"import Lock from 'redfour'"},{"note":"CommonJS require gets the default export directly.","wrong":"const redfour = require('redfour').default","symbol":"Lock (CommonJS)","correct":"const Lock = require('redfour')"},{"note":"acquireLock and waitAcquireLock return an object with success, id, index, ttl. releaseLock expects that object.","wrong":null,"symbol":"Lock instance methods","correct":"const lock = new Lock({ redis: '...', namespace: 'test' });\nawait lock.acquireLock(id, ttl);\nawait lock.waitAcquireLock(id, ttl, timeout);\nawait lock.releaseLock(lockObj);"}],"quickstart":{"code":"import Lock from 'redfour';\n\nconst lock = new Lock({\n  redis: process.env.REDIS_URL ?? 'redis://localhost:6379',\n  namespace: 'mylock'\n});\n\nconst id = Math.random().toString();\n\ntry {\n  const acquired = await lock.acquireLock(id, 60 * 1000);\n  if (acquired.success) {\n    console.log('Lock acquired');\n    // Do critical section work...\n    await lock.releaseLock(acquired);\n  } else {\n    console.log('Could not acquire lock');\n  }\n} catch (err) {\n  console.error('Error:', err);\n}","lang":"javascript","description":"Shows how to create a Lock instance, acquire a lock with a TTL, perform work, and release it."},"warnings":[{"fix":"Reuse an existing Redis client instance by passing it to the constructor.","message":"The module creates two Redis connections if an existing client is not provided. Be aware of connection overhead.","severity":"gotcha","affected_versions":">=2.0.0"},{"fix":"Ensure TTL is in milliseconds (e.g., 60000 for 60 seconds).","message":"Lock TTL must be provided as milliseconds (not seconds). Common mistake: passing seconds results in unintended short TTL.","severity":"gotcha","affected_versions":">=2.0.0"},{"fix":"Pass timeout in milliseconds. For 10 seconds, use 10000.","message":"waitAcquireLock timeout is also in milliseconds. Mistaking it for seconds causes premature timeout.","severity":"gotcha","affected_versions":">=2.0.0"},{"fix":"Upgrade Node.js to >=7.6.0.","message":"Node.js <7.6.0 is not supported due to async/await usage.","severity":"deprecated","affected_versions":">=2.0.0"},{"fix":"Implement application-level timeouts or use Redis connection retry strategies.","message":"If the Redis server goes down, acquireLock and waitAcquireLock may hang indefinitely without timeout.","severity":"gotcha","affected_versions":">=2.0.0"}],"env_vars":null,"search_vec":"'2.2.2':21 '7.6.0':51 'access':55 'across':62 'altern':19 'async':13 'base':5,18,47 'binari':6 'coordin':54 'differenti':28 'e.g':59 'fast':12 'faster':43 'ideal':52 'implement':8 'javascript':67 'key':27 'latest':24 'lock':37,48 'make':40 'much':42 'multipl':63 'mutex':70 'node':50,71 'notifi':33 'poll':17,46 'polling-bas':16,45 'process':64 'pub/sub':10,31 'redfour':1 'redi':4,30,68 'redis-bas':3 'refresh':61 'releas':26,39 'resourc':58 'semaphor':7,69 'server':66 'share':57 'stabl':25 'support':49 'token':60 'unlik':15 'use':9,29 'version':20 'wait':14 'waiter':34","created_at":"2026-06-07T12:58:09.325825+00:00","updated_at":"2026-06-07T12:58:09.325825+00:00","problems":[{"fix":"const lock = new Lock({ redis: '...', namespace: 'myapp' });","cause":"Missing 'namespace' option when creating Lock instance.","error":"Error: The namespace option is required"},{"fix":"Use import Lock from 'redfour'; (default import) or const Lock = require('redfour') in CommonJS.","cause":"Importing named export { Lock } instead of default import when using ES modules.","error":"TypeError: lock.acquireLock is not a function"},{"fix":"Ensure lock is still valid before releasing, or handle the error gracefully.","cause":"Trying to release a lock that has expired or was already released.","error":"Error: The lock does not exist"},{"fix":"Increase timeout value or ensure locks are released promptly.","cause":"The timeout in waitAcquireLock expired before the lock was acquired.","error":"Error: Lock wait timed out"}],"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/mixmaxhq/redfour#readme","github":"https://github.com/mixmaxhq/redfour","docs":null,"changelog":null,"pypi":null,"npm":"redfour","openapi_spec":null,"status_page":null,"smithery":null,"categories":["storage"],"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}}