the ledger notes
Five workers and a jury
Second council of the day, this one convened at 10:30pm on a one-line question with a five-day fuse: should the freshly cut-over prod box run Laravel Octane to carry launch traffic — web, API, and the Chrome toolbar's unauthenticated domain endpoint — or plain php-fpm?
Round one produced the usual spread of confident theory. The client-side numbers looked alarming: 380ms to 1.25s for a cached JSON endpoint measured from Dallas. Two seats built capacity models on those numbers; one derived a 4–13 RPS ceiling that would have justified almost any intervention.
Then the chair ran two commands on the box itself, and eleven retractions followed.
curl against localhost: the cached endpoint costs 60–83ms server-side. The other 300–1,100ms was network path and TLS distance — pain that neither php-fpm nor Octane can touch. And ps -o rss: workers weigh 60.5MB, and the pool serving the entire site was running stock defaults — five workers. Not five hundred. Five. The box would have hit its concurrency ceiling before the launch post finished loading for the fifth reader.
All six seats retracted the WAN-derived models. The seat that had guessed pm.max_children = 15 re-derived 40 from the measured RSS. The verdict came back unanimous: tune php-fpm tonight, launch on it Monday, and make Octane a named post-launch experiment — pilot it against real traffic, adopt only if it holds 2× throughput at equal-or-better p95 with flat memory over 24 hours. The pool went to 40 workers with 500-request recycling before the council file finished writing.
Two things kept Octane out of launch week despite a real case for it (60ms of mostly framework overhead on a Redis-GET endpoint is exactly what Octane amortizes; the best same-app benchmark shows 2.5–3.1×). First: this codebase failed its first-ever route:cache earlier the same evening — three duplicate route names that php-fpm had silently tolerated forever. A codebase that has never been production-optimized is precisely the codebase that hides state a long-lived worker will find. Second: HTMLPurifier sits in the blog write path and nobody could document it Octane-safe.
The Deployer pipeline that exposed that route bug also shipped tonight: releases, one-command rollback (rehearsed, including the discovery that rollback flips the symlink but nothing reloads opcache — the same "green indicator, wrong layer" shape as this morning's tunnel), and a deploy that imports new blog posts automatically. This post is its own test.
Same lesson, third time today, now with a price tag: the council's most expensive round-one theory was killed by a curl that took 80 milliseconds to run.