← All projects
Distributed Systems· Production & Systems· Built· Mar 2026

LockForge

A distributed lock service over HTTP. When several servers try to touch the same resource, exactly one gets the lock.

POST /lock/contested-resource · 5 requests at onceserver-1200 · acquiredserver-2409 · heldserver-3409 · heldserver-4409 · heldserver-5409 · heldREDIS · single-threadedlock:contested-resourceSET … NX PX 30000owner = server-1release / extend → Lua: if GET == owner then DEL / PEXPIRE

Overview

A small REST API for acquiring, releasing, extending, checking and listing named locks, backed by Redis. I built it to properly understand atomic operations. It's the kind of thing you need when two servers might process the same order at the same time.

Problem

A lock across machines has to be atomic (two servers can't both win), owner-safe (you can't release someone else's lock), and it can't stay stuck forever if the holder crashes.

Approach

Acquiring is a single SET key owner NX PX ttl, and since Redis runs commands one at a time only one caller can win. Release and extend have to check the owner and then act, so I wrote them as Lua scripts that run inside Redis and can't be interrupted halfway. The TTL handles crashed holders.

Architecture / how it works

  • acquireLock() is one SET … NX PX call. null means the lock is taken, and the API answers 409 with the current owner and retry_after_ms.
  • releaseLock() runs a Lua script: GET == owner then DEL. That closes the gap where another process grabs the lock between my check and my delete.
  • extendLock() does the same thing with PEXPIRE: only the owner can extend.
  • listLocks() walks keys with SCAN … MATCH lock:* COUNT 100 instead of KEYS, which would block Redis.
  • Release returns 403 for "not your lock" and 404 for "not locked". A GET after the script tells the two apart.
  • The default TTL is 30s, and it runs next to redis:7-alpine in Docker Compose.

Tech stack

TypeScriptNode.jsExpress 5RedisioredisLuaDocker

Outcomes

All five operations (acquire, release, check, extend, list) work. scripts/test-concurrent.sh fires 5 acquire requests at the same moment to check that only one gets a 200.

Resume

Want my resume?

I share it on request, so you always get the latest version. Drop me an email with a line about the role or why you're asking, and I'll send it over.

devanshpandeyji4321@gmail.com
Write the email →