← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

Deadlock, Livelock & Starvation

concurrency Advanced
debt(d7/e5/b5/t7)
d7 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'only careful code review or runtime testing' (d7). The term's detection_hints explicitly state automated=no, and tools listed (mysql-innodb-monitor, datadog) are runtime monitoring tools that detect deadlocks after they occur, not prevent them at code time. Deadlocks manifest as silent hangs in production requiring process restarts.

e5 Effort Remediation debt — work required to fix once spotted

Closest to 'touches multiple files / significant refactor in one component' (e5). The quick_fix mentions 'always acquiring locks in a consistent alphabetical/dependency order' which requires auditing all code paths that acquire locks and ensuring consistent ordering — this spans multiple functions/classes but typically within the data-access layer, not architectural rework.

b5 Burden Structural debt — long-term weight of choosing wrong

Closest to 'persistent productivity tax' (b5). Applies to web, cli, and queue-worker contexts, meaning any part of the system doing concurrent database or resource access must consider lock ordering. Every future feature touching shared resources must follow the locking discipline, creating ongoing overhead for multiple work streams.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap - contradicts how similar concept works elsewhere' (t7). The misconception field explicitly states developers confuse deadlock and livelock as the same thing. Common mistakes show devs intuitively retry failed locks without backoff (creating livelock) or don't realise different code paths acquiring locks in different orders guarantees eventual deadlock — these are non-obvious behaviours that contradict the 'just retry it' instinct.

About DEBT scoring →

Also Known As

deadlock livelock starvation Coffman conditions

TL;DR

Deadlock: processes wait for each other indefinitely. Livelock: processes keep changing state but make no progress. Starvation: a process is perpetually denied resources.

Explanation

Deadlock requires four conditions (Coffman conditions): mutual exclusion, hold and wait, no preemption, circular wait. Prevention: break any one condition — typically consistent lock ordering. Livelock: processes respond to each other but make no progress (e.g. two people stepping the same way in a corridor). Starvation: low-priority processes never get scheduled — prevent with fair scheduling or priority aging. Database deadlocks are automatically detected and one transaction is rolled back.

Diagram

sequenceDiagram
    participant T1 as Thread 1
    participant T2 as Thread 2
    Note over T1,T2: Deadlock
    T1->>T1: Lock resource A
    T2->>T2: Lock resource B
    T1->>T1: Wait for B - blocked
    T2->>T2: Wait for A - blocked
    Note over T1,T2: Both wait forever
    Note over T1,T2: Livelock
    T1->>T1: Acquire A, detect conflict
    T1->>T1: Release A, retry
    T2->>T2: Acquire A, detect conflict
    T2->>T2: Release A, retry
    Note over T1,T2: Both keep retrying - no progress

Common Misconception

Deadlock and livelock are the same — deadlock is complete standstill (no activity); livelock is busy activity with no net progress.

Why It Matters

Deadlocks cause silent hangs that require manual intervention — in PHP this means hung queue workers or web requests that never return, requiring process restarts.

Common Mistakes

  • Acquiring locks in different orders in different code paths — guaranteed eventual deadlock.
  • Not setting lock timeouts — a deadlock with infinite timeout hangs the process forever.
  • Retrying a locked resource with no backoff — creates livelock where both processes keep retrying simultaneously.
  • Holding a lock while doing slow I/O — extends the deadlock window unnecessarily.

Code Examples

✗ Vulnerable
// Inconsistent lock order — deadlock risk:
// Thread 1:           Thread 2:
lock('account:1');    lock('account:2');
lock('account:2');    lock('account:1'); // Both block — deadlock!
debit(1, 100);        debit(2, 100);
credit(2, 100);       credit(1, 100);
unlock('account:2');  unlock('account:1');
unlock('account:1');  unlock('account:2');
✓ Fixed
// Consistent lock order — no deadlock possible:
function transfer(int $from, int $to, float $amount): void {
    // Always lock lower ID first — consistent ordering prevents deadlock:
    $first  = min($from, $to);
    $second = max($from, $to);
    $lock1 = acquireLock("account:$first",  timeout: 5);
    $lock2 = acquireLock("account:$second", timeout: 5);
    // ... debit/credit ...
    releaseLock($lock2);
    releaseLock($lock1);
}

Added 15 Mar 2026
Edited 22 Mar 2026
Views 25
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 1 ping S 0 pings M 0 pings T 1 ping W 3 pings T 0 pings F 2 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 1 ping S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S
No pings yet today
No pings yesterday
Amazonbot 7 Perplexity 5 Google 4 Ahrefs 2 Unknown AI 2 ChatGPT 2
crawler 18 crawler_json 4
DEV INTEL Tools & Severity
🟠 High ⚙ Fix effort: High
⚡ Quick Fix
Prevent deadlocks by always acquiring locks in a consistent alphabetical/dependency order; prevent livelocks by adding randomised backoff in retry loops
📦 Applies To
any web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
Two transactions acquiring same locks in different order; retry loop retrying at exactly the same interval as competing process
Auto-detectable: ✗ No mysql-innodb-monitor datadog
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: Medium ✗ Manual fix Fix: High Context: File Tests: Update
CWE-833 CWE-820

✓ schema.org compliant