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

PHP Execution Model — Shared-Nothing Architecture

php PHP 5.0+ Intermediate
debt(d7/e5/b7/t7)
d7 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'only careful code review or runtime testing' (d7). Misunderstanding the shared-nothing boundary manifests as subtle bugs: stale singletons under Swoole, connection exhaustion under high traffic, or session corruption under RoadRunner. No linter or static analyzer detects 'this static property will cause state bleed under persistent runtimes' — you discover it through careful code review when migrating, or through production incidents.

e5 Effort Remediation debt — work required to fix once spotted

Closest to 'touches multiple files / significant refactor in one component' (e5). The quick_fix indicates externalizing state to Redis/database/APCu, which typically requires refactoring session handling, singleton patterns, and connection management across multiple files. Not architectural rework, but more than a localized fix — especially when auditing all statics and singletons for Swoole migration.

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

Closest to 'strong gravitational pull' (b7). The execution model shapes every architectural decision in PHP: how you handle sessions, database connections, caching, and global state. Moving to persistent runtimes (Swoole/RoadRunner) requires auditing the entire codebase. This is a load-bearing concept that influences design patterns across the system, though not quite 'defines the system's shape' since PHP still functions without understanding it.

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

Closest to 'serious trap' (t7). The misconception states developers believe 'PHP is stateless so global variables are safe' — conflating between-request isolation with within-request safety. This contradicts mental models from persistent runtimes (Node, Go) where developers know globals persist. Worse, code that works perfectly in traditional PHP-FPM fails silently under Swoole/RoadRunner, creating a serious trap when modernizing.

About DEBT scoring →

Also Known As

shared-nothing PHP request lifecycle PHP stateless PHP process model

TL;DR

Each PHP request runs in a completely isolated process or thread — no memory, globals, or state is shared between requests. Every request bootstraps the entire application from scratch and discards everything when it ends.

Explanation

PHP's shared-nothing model means each HTTP request gets a fresh PHP interpreter state: no variables, no loaded classes, no open connections persist from previous requests unless explicitly stored externally (in Redis, a database, or APCu). This design makes horizontal scaling trivial — any server can handle any request — and eliminates entire classes of concurrency bugs. The trade-off is bootstrap cost: frameworks like Laravel or Symfony load hundreds of files, parse configurations, and build dependency injection containers on every request. OPcache eliminates the parsing cost, but the object construction cost remains. Tools like Swoole, RoadRunner, and FrankenPHP break the shared-nothing model to keep the application bootstrapped in memory between requests, trading simplicity for performance.

Common Misconception

PHP is stateless between requests so global variables are safe to use. Within a single request, global variables are fully stateful and can cause the same coupling and testability problems as in any language. The shared-nothing boundary is between requests, not within them.

Why It Matters

The shared-nothing model is why PHP scales horizontally so easily — and why global state, static properties, and singletons are safe within a single request but do not persist across requests. It is also why PHP developers moving to Swoole or RoadRunner must audit their code for stale state: a singleton that resets each request now persists for thousands of requests.

Common Mistakes

  • Storing user-specific data in static class properties expecting isolation — statics are per-process, not per-request under persistent runtimes like Swoole.
  • Opening database connections without connection pooling — each shared-nothing request opens and closes a connection; under high traffic this is expensive without pooling.
  • Assuming session_start() works the same under RoadRunner — persistent PHP workers require custom session handlers because the request lifecycle differs.
  • Not auditing singletons when migrating to Swoole — a database connection singleton that resets each request becomes a shared connection across coroutines.

Code Examples

✗ Vulnerable
<?php
// ❌ Assuming static state persists across requests — fine in shared-nothing PHP,
// but a bug if you migrate to Swoole/RoadRunner
class RequestCounter
{
    private static int $count = 0;

    public static function increment(): void
    {
        self::$count++; // Resets to 0 each request in traditional PHP
        // But persists across requests under Swoole — counts all requests
    }
}
✓ Fixed
<?php
// ✅ For persistent counters — use an external store
class RequestCounter
{
    public function __construct(private Redis $redis) {}

    public function increment(string $key): int
    {
        return $this->redis->incr($key);
    }
}

// ✅ For Swoole/RoadRunner — use coroutine-local storage instead of static
// Each coroutine context gets its own storage, not shared across requests

Added 23 Mar 2026
Views 68
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 0 pings F 0 pings S 0 pings S 0 pings 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 0 pings W 0 pings T 0 pings F 0 pings S 1 ping S 2 pings M 2 pings T 1 ping W 0 pings T 0 pings F 1 ping S 3 pings S 0 pings M 0 pings T 2 pings W 6 pings T 0 pings F
No pings yet today
ChatGPT 3 Google 2 Amazonbot 1
ChatGPT 25 Google 14 Amazonbot 10 Perplexity 2 Ahrefs 1
crawler 48 crawler_json 4
DEV INTEL Tools & Severity
⚡ Quick Fix
Store any state that must persist across requests in an external store: Redis for sessions and cache, a database for data, APCu for process-local cache (shared within a worker, not across workers).
📦 Applies To
PHP 5.0+ web cli

✓ schema.org compliant