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

Compare-and-Swap (CAS)

Concurrency PHP 7.0+ 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 detection_hints indicate automated detection is 'no' and semgrep is listed but catching race conditions from missing CAS/version checks requires semantic understanding of concurrent access patterns. Code patterns like 'read-modify-write without atomic operation' are difficult to detect statically — typically only manifests under concurrent load testing or production race conditions.

e5 Effort Remediation debt — work required to fix once spotted

Closest to 'touches multiple files / significant refactor in one component' (e5). The quick_fix shows a database-level solution with optimistic locking (version column), which requires schema changes, updating all write queries to include version checks, and adding retry logic. While a single CAS call is simple, properly implementing CAS patterns across a component involves retry loops, backoff strategies, and potentially restructuring how concurrent updates are handled.

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

Closest to 'persistent productivity tax' (b5). CAS applies across web/cli/queue-worker contexts and once chosen as a concurrency strategy, it imposes ongoing maintenance burden — every concurrent update path must correctly implement CAS patterns, handle failures, implement backoff, and avoid the ABA problem. Teams must understand the tradeoffs versus mutex-based approaches, creating a persistent knowledge tax.

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

Closest to 'serious trap' (t7). The misconception explicitly states developers wrongly believe 'Mutex locks and CAS are interchangeable' when they behave very differently — CAS retries without blocking, making it efficient under low contention but wasteful under high contention. This contradicts intuition from lock-based concurrency. Common mistakes include infinite retry loops without backoff and ignoring the ABA problem, both stemming from misunderstanding CAS semantics.

About DEBT scoring →

Also Known As

CAS compare and swap atomic operation optimistic locking

TL;DR

An atomic CPU instruction that updates a memory location only if it contains an expected value — the foundation of lock-free data structures and optimistic concurrency control.

Explanation

CAS (Compare-And-Swap) is an atomic operation: atomically read a value, compare to expected, and write a new value only if it matches. If another thread changed the value between the read and write, CAS fails and the operation retries. This is the foundation of: lock-free programming, optimistic locking in databases (UPDATE WHERE version=expected), Redis WATCH/MULTI/EXEC transactions, and atomic counters. PHP: apcu_cas() provides CAS for APCu cache. The ABA problem: CAS can succeed incorrectly if a value changes A→B→A between operations — use versioned counters to prevent.

Common Misconception

Mutex locks and CAS are interchangeable — locks block waiting threads; CAS retries without blocking, making it more efficient under low contention but wasteful under high contention.

Why It Matters

A rate limiter using apcu_cas() can atomically increment a counter without a mutex — under high concurrency, lock-free CAS outperforms mutex-based counters significantly.

Common Mistakes

  • Infinite retry loop without backoff — under high contention, CAS spins and wastes CPU.
  • Not handling CAS failure — apcu_cas() returns false if the value changed; must retry.
  • ABA problem in long-lived CAS loops — include a version counter alongside the value.
  • Using CAS for complex multi-step operations — CAS is for single-value atomic updates; use transactions for multiple.

Code Examples

✗ Vulnerable
// Non-atomic rate limiter — race condition:
$count = apcu_fetch('rate:' . $ip);  // Read
$count++;                              // Increment
apcu_store('rate:' . $ip, $count);   // Write
// Two concurrent requests both read 0, both write 1
// Counter never exceeds 1 regardless of requests
✓ Fixed
// Atomic CAS rate limiter:
function atomicIncrement(string $key, int $max): bool {
    for ($attempts = 0; $attempts < 10; $attempts++) {
        $current = apcu_fetch($key);
        if ($current === false) {
            apcu_add($key, 1, 60); // Set to 1 with 60s TTL
            return true;
        }
        if ($current >= $max) return false; // Rate limited
        if (apcu_cas($key, $current, $current + 1)) return true; // Atomic!
        usleep(100); // Brief backoff before retry
    }
    return false;
}

Added 16 Mar 2026
Edited 5 Apr 2026
Views 190
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
1 ping S 0 pings M 0 pings T 2 pings W 0 pings T 2 pings F 1 ping S 0 pings S 2 pings M 0 pings T 2 pings W 1 ping T 0 pings F 1 ping S 1 ping S 1 ping M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 5 pings W 0 pings T 1 ping F 2 pings S 0 pings S 2 pings M
ChatGPT 1 Perplexity 1
No pings yesterday
ChatGPT 12 Google 11 Amazonbot 8 Ahrefs 8 SEMrush 7 Scrapy 6 ShapBot 6 PetalBot 5 Perplexity 4 Unknown AI 4 Applebot 3 Twitter/X 2 Bing 2 DuckDuckGo 2 Meta AI 1 Majestic 1 Sogou 1
crawler 78 crawler_json 4 your_contextpost 1
DEV INTEL Tools & Severity
🟠 High ⚙ Fix effort: Medium
⚡ Quick Fix
Use database optimistic locking with a version column — UPDATE users SET balance=new, version=version+1 WHERE id=:id AND version=:expected_version; check affected rows = 1
📦 Applies To
PHP 7.0+ any web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
Balance update without version check; read-modify-write without atomic operation; concurrent updates causing lost updates
Auto-detectable: ✗ No semgrep
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: Medium ✗ Manual fix Fix: High Context: Function Tests: Update
CWE-362


✓ schema.org compliant