PHP-FPM workers that ate the host
RSS grew after every catalog request. The leak was copy-on-write, not a missing unset().
Delivery
Write-ups of past business projects. What the goal was, which decisions we made, and what changed after release.
RSS grew after every catalog request. The leak was copy-on-write, not a missing unset().
Two stores, one job each. Pages live in Memcached. The rebuild lock lives in Redis.
Three locales in one JSON column inflated every listing. A packed slab in Memcached cut the worker heap in half.
Redis filled with serialized Eloquent. The queue was slow because the payload was the catalog.
Vue SSR rendered Russian and still allocated English and German message files. The isolate grew with every page.
nginx cached HTML per auth_token. Hit rate died. Public pages do not need that cookie in the key.
ORDER BY JSON_EXTRACT filled a temp table. Forty rows still cost a filesort over fifty thousand SKUs.
PHP-FPM was not slow. Docker NAT to port 9000 dropped SYNs when the backlog hit 128.
withoutOverlapping lived in Memcached. HTML eviction dropped the mutex. Four rebuilds wrote one listing key.
Redis filled with laravel_session blobs. Horizon lost reserved jobs to allkeys-lru.
The php service mounted apps/. Every request stat() the tree over virtiofs. Hits in OPcache were noise.
compose restart php killed in-flight FCGI. nginx said 502. A half-written Memcached key stayed.
ATTR_PERSISTENT on php-fpm, Horizon, and schedule. max_connections 151. Too many connections at noon.
Vue SSR printed 14 Jul in UTC. The client printed 13 Jul in Berlin. Hydration failed, then the page rendered twice.
WHERE title->>'ru' ILIKE scanned fifty thousand JSONB rows. The GIN was for tags. The catalog paid for extract.
The provider returned 200. The worker died before ack. Redis redelivered. Unique middleware did not cover SIGKILL.
The Docker healthcheck became liveness. First request compiled LaraBoom. Kubelet sent SIGKILL. The replica never Ready.
The catalog was Vue SSR. A shared island ran React. Dates disagreed. The page painted twice and shipped the CMS graph.
Cloudflare cached the first HTML for the URL. A de visitor got ru markup. Vue hydrated the wrong language, then navigated.