{"id":4730,"library":"python-redis-lock","title":"Python Redis Lock","description":"python-redis-lock is a Python library that provides a distributed lock context manager, implemented using Redis's `SETNX` (SET if Not eXists) and `BLPOP` operations. It aims to offer an interface similar to Python's built-in `threading.Lock`. The current version is 4.0.1, and it maintains an active release cadence, with its latest major update in late 2022.","status":"active","version":"4.0.1","language":"en","source_language":"en","source_url":"https://github.com/ionelmc/python-redis-lock","tags":["redis","lock","concurrency","distributed-lock","context-manager"],"install":[{"cmd":"pip install python-redis-lock","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Required for Redis client interaction, as the library builds on top of `redis-py`.","package":"redis"}],"imports":[{"note":"The `redis` (redis-py) library also has a `Lock` class under `redis.lock`. Ensure you import from `redis_lock` for this specific library's implementation.","wrong":"from redis.lock import Lock","symbol":"Lock","correct":"from redis_lock import Lock"}],"quickstart":{"code":"import redis\nimport time\nimport os\nfrom redis_lock import Lock\n\nREDIS_HOST = os.environ.get('REDIS_HOST', 'localhost')\nREDIS_PORT = int(os.environ.get('REDIS_PORT', 6379))\n\n# Connect to Redis\nclient = redis.Redis(host=REDIS_HOST, port=REDIS_PORT, db=0)\n\nlock_name = \"my-distributed-lock\"\n\n# Acquire a lock using a context manager, with a 10-second expiration\n# and automatic renewal while the 'with' block is active.\nprint(f\"Attempting to acquire lock '{lock_name}'...\")\nwith Lock(client, lock_name, expire=10, auto_renewal=True, blocking_timeout=5) as lock:\n    if lock.acquired:\n        print(f\"Lock '{lock_name}' acquired! Doing some critical work...\")\n        # Simulate work that takes longer than the expire time\n        # auto_renewal will keep the lock alive.\n        time.sleep(15)\n        print(f\"Work finished. Lock '{lock_name}' will be automatically released.\")\n    else:\n        print(f\"Failed to acquire lock '{lock_name}'. Another process holds it.\")\n\n# You can also check if a lock is currently held (by anyone)\nif Lock(client, lock_name).locked():\n    print(f\"Lock '{lock_name}' is currently held by someone else (or was not properly released).\")\nelse:\n    print(f\"Lock '{lock_name}' is not currently held.\")\n\nclient.close()","lang":"python","description":"This quickstart demonstrates how to acquire and use a distributed lock with `python-redis-lock` using a context manager. It highlights setting an expiration (`expire`) and enabling automatic renewal (`auto_renewal`) to prevent locks from being held indefinitely if the application crashes. It also shows checking the lock status."},"warnings":[{"fix":"Upgrade to Python 3.7+ or pin `python-redis-lock` to a version prior to 4.0.0.","message":"Version 4.0.0 dropped support for Python 2.7 and Python 3.6. Users on these older Python versions must use `python-redis-lock < 4.0.0`.","severity":"breaking","affected_versions":">=4.0.0"},{"fix":"Always use the `auto_renewal=True` parameter in conjunction with `expire` when creating a `Lock` instance. This ensures the lock is automatically renewed as long as the Python process is running within the `with` block, and will expire cleanly if the process terminates unexpectedly. Example: `Lock(client, 'my-lock', expire=60, auto_renewal=True)`.","message":"If an application crashes while holding a lock and `expire` (timeout) is not set, the lock may remain in Redis indefinitely, causing permanent deadlocks. Setting `expire` alone will release the lock after a fixed duration, but if the critical section takes longer, the lock might be released prematurely.","severity":"gotcha","affected_versions":"<4.0.1"},{"fix":"Review your code and remove any usage of `lock.release(force=True)`. Ensure proper lock acquisition and release logic without relying on force-releasing locks, which can lead to race conditions.","message":"The `force` parameter on the `release()` method was removed in version 3.0.0. This option was considered to encourage sloppy programming and is no longer available.","severity":"deprecated","affected_versions":">=3.0.0"},{"fix":"Understand that this library is suitable for single-instance Redis distributed locking. If your application requires the guarantees of the Redlock algorithm (e.g., across multiple Redis masters), you will need to use a different library (e.g., `redlock-py`) or implement Redlock logic yourself. Do not confuse `redis_lock.Lock` with `redis.lock.Lock` (from `redis-py`), as they are separate implementations.","message":"`python-redis-lock` implements a distributed lock based on Redis's `SETNX` and `BLPOP`. It is *not* an implementation of the more complex Redlock algorithm (which involves multiple independent Redis instances for higher fault tolerance).","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-12T00:00:00.000Z","next_check":"2026-07-11T00:00:00.000Z"}