← Home ← Codex ← DEBT ← Engine
Browse by Category
+ added · updated 7d
← Back to glossary

Atomic Operations

Concurrency Intermediate
debt(d7/e3/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 detection_hints explicitly state automated detection is 'no'. The code pattern (Cache::get followed by increment then set) is a heuristic but no standard linter, SAST tool, or static analyzer reliably catches non-atomic read-modify-write patterns in PHP. These race conditions typically surface only under concurrent load during runtime testing or careful code review.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3). The quick_fix states replacing read-modify-write with DB atomic increment (SET col = col + 1) or Redis INCR. For simple counters this is essentially a one-line swap (e1-e3), but for multi-step sequences requiring Redis Lua scripts or DB transactions, it touches more logic. Averaging across the common cases, e3 fits — it's a patterned replacement but may require understanding the atomicity boundary.

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

Closest to 'persistent productivity tax' (b5). Atomic operations apply across web, cli, and queue-worker contexts (all three listed in applies_to). Once a codebase has non-atomic patterns scattered through counters, rate limiters, and distributed coordination points, every future feature touching shared mutable state must consider atomicity. It's not architecture-defining (b7-b9), but it's a persistent tax that affects many work streams — especially in high-throughput systems.

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

Closest to 'serious trap — contradicts how a similar concept works elsewhere' (t7). The misconception is that $counter++ is atomic in PHP — developers from single-threaded mental models or languages where increment is atomic will assume this works. PHP's process-per-request model makes it non-obvious that file-backed or cache-backed counters race across PHP-FPM workers. The 'obvious' approach (read, increment, write) is exactly the wrong one, and the common_mistakes reinforce that developers routinely assume PHP assignment is atomic across processes.

About DEBT scoring →

TL;DR

Atomic operations complete indivisibly — no other thread can observe an intermediate state. The foundation for lock-free concurrency and database counters.

Explanation

An atomic operation is guaranteed to complete as a single indivisible unit — no interruption, no partial state. CPU-level: compare-and-swap (CAS), fetch-and-add. Database: UPDATE SET col = col + 1 (atomic in InnoDB). Redis: INCR, SETNX, all single commands are atomic; MULTI/EXEC transactions are atomic; Lua scripts are atomic. PHP: no native atomic primitives (single-threaded process model), but DB and Redis operations are atomic at the storage layer. Lock-free patterns use CAS: read current value → compute new → CAS(expected, new) → retry if failed. SQL INSERT … ON DUPLICATE KEY UPDATE is an atomic upsert.

Common Misconception

$counter++ is atomic in PHP — it's three operations (read, increment, write). In PHP-FPM with file-backed counters, it's a race condition without locking.

Why It Matters

Atomic operations eliminate race conditions without locking overhead — critical for high-throughput counters, rate limiters, and distributed coordination.

Common Mistakes

  • Using non-atomic read-modify-write for counters — use DB atomic increment or Redis INCR.
  • Assuming PHP assignment is atomic — it's not across processes.
  • Not using Redis MULTI/EXEC or Lua for multi-step atomic sequences.

Code Examples

✗ Vulnerable
// Non-atomic counter — race condition:
$views = Cache::get('views') + 1;
Cache::set('views', $views);
✓ Fixed
// Atomic Redis increment:
$views = $redis->incr('page:views');

// Atomic DB increment:
$pdo->exec('UPDATE pages SET views = views + 1 WHERE id = ?', [$pageId]);

// Atomic upsert:
$pdo->exec(
    'INSERT INTO stats (page, views) VALUES (?, 1)
     ON DUPLICATE KEY UPDATE views = views + 1', [$page]
);

Added 23 Mar 2026
Views 179
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
2 pings S 0 pings M 1 ping T 1 ping W 0 pings T 0 pings F 1 ping S 2 pings S 0 pings M 1 ping T 0 pings W 0 pings T 0 pings F 0 pings S 1 ping S 0 pings M 0 pings T 0 pings W 0 pings T 1 ping F 0 pings S 1 ping S 1 ping M 1 ping T 1 ping W 0 pings T 2 pings F 3 pings S 0 pings S 0 pings M
No pings yet today
No pings yesterday
Amazonbot 23 Meta AI 20 Perplexity 12 Google 10 SEMrush 10 PetalBot 10 Ahrefs 9 Scrapy 9 ChatGPT 7 Unknown AI 5 Bing 3 Applebot 3 Brave Search 2 Majestic 1 Twitter/X 1 Baidu 1
crawler 121 crawler_json 4 your_contextpost 1
DEV INTEL Tools & Severity
🟠 High ⚙ Fix effort: Low
⚡ Quick Fix
Replace read-modify-write with DB atomic increment (SET col = col + 1) or Redis INCR. For complex sequences, use Redis Lua scripts or DB transactions.
📦 Applies To
web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
Cache::get.*\+|get.*\+.*set
Auto-detectable: ✗ No
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: Medium ✓ Auto-fixable Fix: Medium Context: Function Tests: Update
CWE-362 CWE-366


✓ schema.org compliant