{"id":46165,"library":"redis-sp","title":"redis-sp","description":"redis-sp (Synchronization Primitives) is a TypeScript library providing distributed mutex and counting semaphore implementations based on the Redlock algorithm. Version 1.3.2, released in 2021, is the latest stable release with no active development observed. It relies on ioredis clients and uses Redis Lua scripts for atomicity, avoiding race conditions common in other implementations. Differentiates from alternatives like 'redlock' by offering both mutex and semaphore primitives with TypeScript support.","status":"active","version":"1.3.2","language":"javascript","source_language":"en","source_url":"https://github.com/lad-tech/redis-sp","tags":["javascript","redis","redlock","mutex","semaphore","typescript"],"install":[{"cmd":"npm install redis-sp","lang":"bash","label":"npm"},{"cmd":"yarn add redis-sp","lang":"bash","label":"yarn"},{"cmd":"pnpm add redis-sp","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Required to provide Redis clients for lock/semaphore operations.","package":"ioredis","optional":false}],"imports":[{"note":"Library is ESM-native since v1; require() works in CommonJS but TypeScript users should use import.","wrong":"const RedisMutex = require('redis-sp').RedisMutex","symbol":"RedisMutex","correct":"import { RedisMutex } from 'redis-sp'"},{"note":"Only named export; no default export exists.","wrong":"import RedisCountingSemaphore from 'redis-sp'","symbol":"RedisCountingSemaphore","correct":"import { RedisCountingSemaphore } from 'redis-sp'"},{"note":"Error class is named LockAcquisitionError, not LockError.","wrong":"import { LockError } from 'redis-sp'","symbol":"LockAcquisitionError","correct":"import { LockAcquisitionError } from 'redis-sp'"}],"quickstart":{"code":"import RedisClient from 'ioredis';\nimport { RedisMutex, LockAcquisitionError } from 'redis-sp';\n\nasync function main() {\n  const client = new RedisClient({\n    host: process.env.REDIS_HOST ?? 'localhost',\n    port: parseInt(process.env.REDIS_PORT ?? '6379'),\n  });\n\n  const mutex = new RedisMutex([client], 'resource-lock-key');\n  try {\n    await mutex.lock();\n    // critical section\n    await new Promise(resolve => setTimeout(resolve, 1000));\n  } catch (err) {\n    if (err instanceof LockAcquisitionError) {\n      console.error('Could not acquire lock');\n    } else {\n      throw err;\n    }\n  } finally {\n    await mutex.unlock();\n  }\n  client.quit();\n}\n\nmain().catch(console.error);","lang":"typescript","description":"Demonstrates creating a RedisMutex, acquiring a lock, executing critical code, and releasing the lock with proper error handling."},"warnings":[{"fix":"Wrap lock() in try-catch and handle LockAcquisitionError explicitly; do not assume immediate success.","message":"The lock() method can throw LockAcquisitionError if lock acquisition fails (e.g., resource already locked).","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"Consider alternative actively maintained libraries like 'redlock' for Redlock algorithm.","message":"No new releases since 2021; library may not be actively maintained for newer Redis or Node.js versions.","severity":"deprecated","affected_versions":">=1.0.0"},{"fix":"Ensure each critical section uses a distinct, namespaced resource identifier.","message":"The mutex key must be unique per resource; reusing keys across unrelated sections leads to unintended contention.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Always pass clients as an array: new RedisMutex([client], key).","message":"RedisMutex requires an array of Redis clients even if using a single instance; passing a single client without array wrapper causes runtime error.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"search_vec":"'1.3.2':26 '2021':29 'activ':37 'algorithm':24 'altern':61 'atom':51 'avoid':52 'base':20 'client':44 'common':55 'condit':54 'count':17 'develop':38 'differenti':59 'distribut':14 'implement':19,58 'ioredi':43 'javascript':74 'latest':32 'librari':12 'like':62 'lua':48 'mutex':15,67,77 'observ':39 'offer':65 'primit':8,70 'provid':13 'race':53 'redi':2,5,47,75 'redis-sp':1,4 'redlock':23,63,76 'releas':27,34 'reli':41 'script':49 'semaphor':18,69,78 'sp':3,6 'stabl':33 'support':73 'synchron':7 'typescript':11,72,79 'use':46 'version':25","created_at":"2026-06-07T12:58:36.834135+00:00","updated_at":"2026-06-07T12:58:36.834135+00:00","problems":[{"fix":"Use ioredis client only; the library is not compatible with 'redis' v4+ client.","cause":"Passed a non-ioredis client (e.g., redis v4 client) which does not have sendCommand method.","error":"TypeError: client.sendCommand is not a function"},{"fix":"Increase retry options or ensure previous lock is released; use tryLock() with timeout.","cause":"Cannot acquire lock within default retry attempts; resource held by another process.","error":"Error: LockAcquisitionError: lock not acquired"},{"fix":"Update to v1.3.2 and use import { RedisMutex } from 'redis-sp'.","cause":"Trying to use an older version (<1.0.0) where API was different, or using require() incorrectly.","error":"TypeError: mutex.lock is not a function"}],"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/lad-tech/redis-sp#readme","github":"https://github.com/lad-tech/redis-sp","docs":null,"changelog":null,"pypi":null,"npm":"redis-sp","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}}