A long-lived process holding thousands of connections is not what PHP is for, and a small binary beside it is a smaller change than a rewrite.
what moved: the websocket fan-out. 4,000 idle
connections, almost no CPU.
what stayed: everything else.
the boundary: Redis pub/sub. PHP publishes, the binary
fans out. no shared code, no shared database, no build
coupling. one message format, documented.
the cost: a second language in the deployment, and a
second thing to know when it breaks at 3am.
Keeping the boundary at a message queue rather than a shared database or a library is what makes the second language affordable — the two sides can be understood and deployed separately, and either can be replaced. The real cost is operational rather than technical: the on-call rotation now needs somebody who can read it, which is an argument for keeping such components small and boring.