PHPackages                             hokoo/wp-lock - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. hokoo/wp-lock

ActiveLibrary

hokoo/wp-lock
=============

A library for locking and mutexes for the WordPress Core

v1.1(2y ago)163MITPHPPHP &gt;=7.4

Since Apr 18Pushed 1y ago1 watchersCompare

[ Source](https://github.com/hokoo/wp-lock)[ Packagist](https://packagist.org/packages/hokoo/wp-lock)[ Docs](https://github.com/hokoo/wp-lock)[ RSS](/packages/hokoo-wp-lock/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (2)Dependencies (2)Versions (6)Used By (0)

`WP Lock`
=========

[](#wp-lock)

[![PHPUnit Tests](https://github.com/hokoo/wp-lock/actions/workflows/phpunit.yml/badge.svg)](https://github.com/hokoo/wp-lock/actions/workflows/phpunit.yml)

> This was previously a fork from original repo [soulseekah/wp-lock](https://github.com/soulseekah/wp-lock) by Gennady Kovshenin. Now here is the standalone repo with such changes as:
>
> - Custom database table is used as the WPDB locks' storage that allows to manage locks in simple and convenient way.
> - Fast: making one lock takes up to one single query instead of 11 and more.
> - Readable: the code is well documented and easy to understand.

WP Lock's Preconditions
-----------------------

[](#wp-locks-preconditions)

Consider the following user balance topup function that is susceptible to a race condition:

```
// Top-up function that is not thread-safe
public function topup_user_balance( $user_id, $topup ) {
	$balance = get_user_meta( $user_id, 'balance', true );
	$balance = $balance + $topup;
	update_user_meta( $user_id, 'balance', $balance );
	return $balance;
}
```

Try to call the above code 100 times in 16 threads. The balance will be less than it is supposed to be.

The code below is thread safe.

```
// A thread-safe version of the above topup function.
public function topup_user_balance( $user_id, $topup ) {
	$user_balance_lock = new WP_Lock( "$user_id:meta:balance" );
	$user_balance_lock->acquire( WP_Lock::WRITE );

	$balance = get_user_meta( $user_id, 'balance', true );
	$balance = $balance + $topup;
	update_user_meta( $user_id, 'balance', $balance );

	$user_balance_lock->release();

	return $balance;
}
```

Usage
-----

[](#usage)

Require via Composer `composer require hokoo/wp-lock` in your plugin.

Don't forget to include the Composer autoloader in your plugin and declare using of the `WP_Lock` class.

```
use iTRON\WP_Lock;
require 'vendor/autoload.php';
```

Acquire a read blocking lock without a timeout.

```
$lock = new WP_Lock\WP_Lock( 'my-lock' );

$lock->acquire( WP_Lock::READ, true, 0 );
// do something, and then
$lock->release();
```

```
public function acquire( $level = self::WRITE, $blocking = true, $expiration = 30 )
```

### Lock levels

[](#lock-levels)

- `WP_Lock::READ` - other processes can acquire READ but not WRITE until the original lock is released. A shared read lock.
- `WP_Lock::WRITE` (default) - other processes can't acquire READ or WRITE locks until the original lock is released. An exclusive read-write lock

### Blocking policy

[](#blocking-policy)

- Blocking means that the process will wait here until the lock is obtained (5 microseconds spinlock).
- Non-blocking lock acquisition does not wait for the other locks to be released, but returns false immediately if the lock is already acquired by another process. So, it should be checked for success.

```
if ( $lock->acquire( WP_Lock::READ, false, 0 ) ) {
    // do something, and then
    $lock->release();
}
```

### Timeout policy

[](#timeout-policy)

- 0-second timeout means that the lock should be released, otherwise it will be released automatically after the php process is finished.
- Non-zero timeout means that the lock might not be released manually, and then it will be done automatically after the specified number of seconds.

Lock Existence Check
--------------------

[](#lock-existence-check)

You may also want to check if a lock is acquired by another process without actually trying to acquire it.

```
$another_lock = new WP_Lock\WP_Lock( 'my-lock' );

if ( $another_lock->acquire( WP_Lock::READ, false, 0 ) ) {
    $lock->lock_exists( WP_Lock::READ ); // true
    $lock->lock_exists( WP_Lock::WRITE ); // false

    $another_lock->release();
}

if ( $another_lock->acquire( WP_Lock::WRITE, false, 0 ) ) {
    $lock->lock_exists( WP_Lock::READ ); // true
    $lock->lock_exists( WP_Lock::WRITE ); // true

    $another_lock->release();
}
```

Caveats
-------

[](#caveats)

In highly concurrent setups you may get Deadlock errors from MySQL. This is normal. The library handles these gracefully and retries the query as needed.

###  Health Score

27

—

LowBetter than 49% of packages

Maintenance28

Infrequent updates — may be unmaintained

Popularity13

Limited adoption so far

Community12

Small or concentrated contributor base

Maturity48

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 57.5% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~3 days

Total

2

Last Release

742d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/3988fe121d93b3ce7fb819c278cf7f19bf40411db2a1a57bbd4ae6ea4ca3eedc?d=identicon)[hokoo](/maintainers/hokoo)

---

Top Contributors

[![soulseekah](https://avatars.githubusercontent.com/u/685880?v=4)](https://github.com/soulseekah "soulseekah (50 commits)")[![hokoo](https://avatars.githubusercontent.com/u/16269260?v=4)](https://github.com/hokoo "hokoo (34 commits)")[![andriibieriezhnoi](https://avatars.githubusercontent.com/u/13201155?v=4)](https://github.com/andriibieriezhnoi "andriibieriezhnoi (1 commits)")[![verne-wv](https://avatars.githubusercontent.com/u/25538462?v=4)](https://github.com/verne-wv "verne-wv (1 commits)")[![versusbassz](https://avatars.githubusercontent.com/u/2342074?v=4)](https://github.com/versusbassz "versusbassz (1 commits)")

---

Tags

rece-conditionthreadswordpresswp-lock

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/hokoo-wp-lock/health.svg)

```
[![Health](https://phpackages.com/badges/hokoo-wp-lock/health.svg)](https://phpackages.com/packages/hokoo-wp-lock)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
