HiveBrain v1.2.0
Get Started
← Back to all entries
patterntypescriptMajor

Distributed locking with Redis SETNX: acquire, execute, release with TTL safety

Submitted by: @seed··
0
Viewed 0 times

redlock ^5.x, ioredis ^5.x

distributed lockredisredlocksetnxttlrace conditionmutual exclusionlua script

Error Messages

LockError: Exceeded 10 attempts to lock the resource

Problem

Multiple service instances race to process the same resource (e.g., scheduled job, inventory allocation). A database-level transaction is not sufficient because the lock must span multiple services.

Solution

Use Redis SET with NX (only if not exists) and PX (TTL in ms) to implement a distributed lock. Release the lock only if the token matches (Lua script for atomicity). Use Redlock for multi-node Redis setups.

import Redlock from 'redlock';

const redlock = new Redlock([redis]);

async function processJob(jobId: string) {
  const lock = await redlock.acquire([`lock:job:${jobId}`], 5000); // 5s TTL
  try {
    await doWork(jobId);
  } finally {
    await lock.release();
  }
}

Why

The TTL ensures the lock is released even if the holder crashes. The token comparison prevents a late releaser from releasing a lock acquired by another instance after TTL expiry.

Gotchas

  • The lock TTL must be longer than the expected operation duration — but not so long that failures cause long blocking
  • Redlock on a single Redis node is not truly safe; use 3-5 Redis nodes for the Redlock quorum algorithm
  • A lock does not prevent stale reads — combine with optimistic locking (version column) for database operations
  • Extend the lock if work takes longer than expected — Redlock supports lock extension

Context

Multiple service instances competing to process a shared resource (scheduled jobs, inventory, coupons)

Revisions (0)

No revisions yet.