WordPress Transients – An Efficient Way to Avoid Race Conditions

WordPress transients provide an efficient way to temporarily store data in the database or memory, reducing server load and preventing race conditions. Learn how to use them properly to optimize your WordPress site's performance.

When integrating external systems with WordPress, handling real-time data synchronization can lead to race conditions – causing duplicate entries or inconsistent updates. This article explores how we leveraged WordPress transients to effectively prevent such issues.

One of our clients uses GoHighLevel CRM for managing his business. We received a request to enable real-time data synchronization between that CRM and his WordPress website. To achieve this, we leveraged the GoHighLevel’s webhooks to notify the website whenever data was created, updated, or deleted. We then handled these webhooks in our custom WordPress plugin, processing the events accordingly to create, update, or delete posts.

Here’s a simplified version of our webhook listener logic:

if ($data['type'] == 'update') {
    if ($customPost->existsInWp()) {
        $customPost->update();
    } else {
        $customPost->create();
    }
} elseif ($data['type'] == 'create') {
    $customPost->create();
} elseif ($data['type'] == 'delete') {
    $customPost->delete();
}

The Problem: Race Conditions

While this worked in theory, we soon encountered unexpected behavior from the CRM when creating or updating data. For example, when modifying a record, we observed the following sequence:

2025-03-15 14:20:44 :: INFO: Action: Create
2025-03-15 14:20:44 :: INFO: Action: Update

Here, the “update” event was triggered almost immediately after the “create” event.

Similarly, when updating data, we sometimes received multiple update events within a short timeframe:

2025-03-15 15:36:12 :: INFO: Action: Update
2025-03-15 15:36:12 :: INFO: Action: Update

Even more confusingly, we occasionally observed cases where an update event arrived before the corresponding create event:

2025-03-15 17:48:03 :: INFO: Action: Update
2025-03-15 17:48:03 :: INFO: Action: Create

Our initial logic did not handle these situations well. If an “update” event triggered a post creation and another “update” event arrived before the first operation was completed, we ended up with duplicate data – a classic race condition scenario.

The Solution: Using WordPress Transients as a Lock Mechanism

A lesser-known yet highly useful feature of WordPress is the Transients API. Transients function similarly to the Options API, but they are much faster – making them ideal for our use case.

Transients temporarily store cached data in the WordPress database with an expiration time, after which they are automatically deleted. We decided to use transients as a locking mechanism to prevent concurrent operations on the same post.

We implemented the following approach:

  • set_transient(): Set a lock before starting an operation.
  • get_transient(): Check if a lock exists before proceeding.
  • delete_transient(): Remove the lock after completing the operation.

Updated Code with Transients:

if ($data['type'] == 'update') {
    $lockKey = $data['name'];
    if (get_transient($lockKey)) {       // if the lock is set
        sleep(4);                   // sleep a while for pending operations to finish
    }
    set_transient($lockKey, true, 2);    // set a Lock for 2 seconds
    if ($customPost->existsInWp()) {
        $customPost->update();
    } else {
        $customPost->create();
    }
    delete_transient($lockKey);          // remove the lock if exists
} elseif ($data['type'] == 'create') {
    $lockKey = $data['name'];
    if (get_transient($lockKey)) {       // if the lock is set
        return;                          // exit - we don't want to create another post
    }
    set_transient($lockKey, true, 2);   // Lock for 2 seconds
    $listing->create();
    delete_transient($lockKey);         // remove the lock
} elseif ($data['type'] == 'delete') {
    $customPost->delete();
}

How This Works:

  1. Locking before processing: Before updating or creating a post, we check if another operation is in progress.
  2. Preventing duplicate creations: Before creating a post, we ensure no other process is already handling the same post.
  3. Releasing the lock after processing: Once the operation is complete, we remove the lock.

Conclusion

By using WordPress transients as a locking mechanism, we effectively mitigated race conditions in our webhook processing logic. This approach ensures data integrity and prevents duplicate entries, providing a simple yet powerful solution to a common problem in real-time data synchronization.

If you’re dealing with race conditions in your WordPress applications, transients can be an invaluable tool to maintain consistency and improve performance.

Need Help Optimizing Your WordPress Site?

Struggling with performance issues or race conditions in your WordPress application? Our team can help you implement efficient solutions like transients to improve speed, reliability, and data integrity.

Contact Us Today and let’s optimize your site together!

elevating your brand to new horizons in the digital sphere

Our services