filelock is a platform-independent file locking library for Python that provides inter-process synchronization via OS-level primitives (fcntl on Unix, msvcrt on Windows) with automatic fallback to soft (file-existence) locking. It supports exclusive locks (FileLock, SoftFileLock), SQLite-backed read-write locks (ReadWriteLock, added in 3.21.0), and async variants (AsyncFileLock, AsyncReadWriteLock, added in 3.25.0). The current stable version is 3.25.2, released March 2026; the project ships multiple releases per month and requires Python ≥ 3.10.
Install & Compatibility
Where this runs
tested against v3.29.1 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.925 runs
installs and imports cleanly · install 0.0s · import 0.265s · 18.1MB
glibcpy 3.10–3.925 runs
installs and imports cleanly · install 1.5s · import 0.233s · 19MB
16MB installed
● package 16MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
FileLock
✓ from filelock import FileLock
✗ import filelock; filelock.FileLock(...)
Named import is idiomatic; module-level access still works but is verbose and was the old py-filelock style.
Timeout
✓ from filelock import Timeout
Always catch filelock.Timeout (not built-in TimeoutError) when using acquire(timeout=N).
SoftFileLock
✓ from filelock import SoftFileLock
Use instead of FileLock on network/FUSE mounts where fcntl is unavailable; since 3.24.0 FileLock auto-falls back on ENOSYS.
ReadWriteLock
✓ from filelock import ReadWriteLock
SQLite-backed multi-reader/single-writer lock added in 3.21.0. Lock file must use a .db extension.
AsyncFileLock
✓ from filelock import AsyncFileLock
Async variant; runs blocking I/O in a thread-pool executor. Use 'async with lock:' not 'with lock:'.
AsyncReadWriteLock
✓ from filelock import AsyncReadWriteLock
Added in 3.25.0. Wraps ReadWriteLock for asyncio; all SQLite ops dispatched to loop.run_in_executor().
Exclusive file lock with timeout; catch Timeout on contention.
from filelock import FileLock, Timeout
# Always lock a *separate* .lock file, not the file you intend to write.
lock = FileLock("data.txt.lock", timeout=10)
try:
with lock:
with open("data.txt", "a") as f:
f.write("safe write\n")
except Timeout:
print("Could not acquire lock within 10 seconds")
# Reentrant: acquiring the same lock object again inside the block is safe.
with lock:
with lock: # internal counter incremented; no deadlock
pass
Debug
Known issues
breakingPython < 3.10 is no longer supported as of filelock 3.x modern releases. The requires-python constraint is >=3.10.fixUpgrade to Python 3.10+. Pin filelock<3.12 only if you must stay on Python 3.8/3.9 (unsupported path).
affects: <3.10 (Python runtime)
gotchaNever lock the file you intend to write; create a separate companion .lock file. Locking the target file directly causes undefined behaviour because filelock may truncate or interfere with it.fixUse a path like 'myfile.txt.lock' and open 'myfile.txt' only inside the lock context.
affects: all
gotchaTimeout=None (the default) and timeout=-1 both mean 'block forever'. A timeout of 0 means exactly one non-blocking attempt. Passing timeout=0 does NOT mean 'no timeout'.fixPass timeout=-1 explicitly for infinite wait; pass a positive float for a real deadline; catch filelock.Timeout, not TimeoutError.
affects: all
gotchaSoftFileLock can leave stale lock files if a process crashes. On network/FUSE mounts where fcntl is unsupported, FileLock silently falls back to SoftFileLock (since 3.24.0), which is only stale-safe on same-host contention.fixFor cross-host NFS/FUSE use-cases, rely on SoftFileLock's built-in PID+hostname stale detection (>=3.22.0) and set a sensible timeout.
affects: all (stale detection: >=3.22.0 on Unix, not Windows)
breakingReadWriteLock requires the lock file path to use a .db extension (it is backed by SQLite). Passing a plain .lock path raises an error.fixUse: ReadWriteLock('myresource.db') not ReadWriteLock('myresource.lock'). affects: >=3.21.0
gotchaReadWriteLock upgrading or downgrading lock mode (read→write or write→read) within the same thread raises RuntimeError. The lock is reentrant only within the same mode.fixRelease the lock fully before re-acquiring in a different mode.
affects: >=3.21.0
deprecatedThe poll_intervall parameter (double-l spelling) in acquire() is deprecated in favour of poll_interval (single-l). Both are accepted for backward compatibility but the old spelling will eventually be removed.fixUse poll_interval=0.05 (or your preferred float) in acquire() calls.
affects: >=3.x
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'filelock'
The `filelock` package is not installed in the Python environment being used.
fixInstall the `filelock` library using pip: `pip install filelock`
AttributeError: 'FileLock' object has no attribute '_thread_lock'
This error often occurs due to a breaking change in the `filelock` library's internal API between versions, where an internal attribute like `_thread_lock` or `_lock_file` was removed or renamed.
fixUpgrade `filelock` to the latest version (`pip install --upgrade filelock`) or, if the problem persists, try downgrading to a known stable version that is compatible with your other dependencies (e.g., `pip install filelock==3.19.1` if a newer version is causing the issue). Ensure all related packages are also up to date.
filelock.Timeout
The lock could not be acquired within the specified `timeout` period, meaning another process held the lock for too long.
fixIncrease the `timeout` value when creating the `FileLock` object or implement retry logic with a backoff strategy. Alternatively, ensure that processes holding the lock release it promptly.
NotImplementedError: FileSystem does not appear to support flock; user SoftFileLock instead
The underlying operating system or filesystem (e.g., some network file systems) does not support the `fcntl.flock` system call used by the default `FileLock` for hard locking.
fixUse `SoftFileLock` instead of `FileLock`, as `SoftFileLock` relies on file existence (a soft lock) which is more portable across various filesystems, including network mounts: `from filelock import SoftFileLock; lock = SoftFileLock('my_file.lock')` Audit
Dependencies
No dependency data recorded yet.