Edited by humans. Written by AI. How our editing works
All articles

Qbix Bets on Copy-on-Write to Rethink PHP Servers

Qbix Server uses copy-on-write forks to run blocking PHP at scale. Its design is intriguing, but speed, memory and compatibility claims remain self-reported.

Dev Kapoor

Written by AI. Dev Kapoor

September 18, 20267 min read
Share:
Qbix Bets on Copy-on-Write to Rethink PHP Servers

Qbix Server 1.2 arrived two months after its creator first announced the project, carrying a claim designed to stop a PHP developer mid-scroll: run PHP scripts more than 100 times faster than nginx and php-fpm.

The number needs a large asterisk. Every benchmark and compatibility assertion discussed here comes from the project's creator, spread across the Qbix website, repository and launch post. Those are three useful primary documents, but they do not provide independent corroboration.

The architecture deserves attention even with that caveat. Qbix approaches blocking PHP code as a capacity problem. It preloads an application, forks many persistent workers and uses the operating system's copy-on-write memory behavior to keep those workers small. Instead of requiring an application to yield during database or network operations, Qbix plans to have another worker ready while the first one waits.

That choice offers a useful third answer to a stubborn PHP question: how do you increase concurrency without making developers rewrite an installed universe of blocking code?

Fork First, Copy Only When Needed

In the creator's Hacker News announcement, Qbix Server 1.2 is described as a pure-PHP server that can handle websites, files, certificates, scheduled jobs and real-time sockets. Standalone binaries are offered for Linux and macOS, and the project is MIT licensed.

Its core trick happens before traffic arrives. Qbix loads the framework and application classes into a parent process, then calls pcntl_fork(). The resulting workers inherit the parent's memory pages. Under copy-on-write, those pages remain shared until a worker modifies them, at which point the operating system copies the affected page for that worker.

The project's website says a WordPress-like request dirties about 30 pages, or 120KB on Linux. Its published architecture and benchmark tables compare that with a php-fpm worker consuming about 42MB. The site says 400 Qbix workers occupy 47MB after the parent has loaded the application, while four php-fpm workers use 168MB.

Treat those memory figures as workload-dependent measurements rather than constants. A request that mutates more pages will surrender more of the sharing advantage. The launch materials do not show how memory changes across large plugin sets, long-lived production traffic or applications with substantial mutable state. Copy-on-write makes the design plausible; it does not freeze every worker at 120KB by decree of the kernel gods.

The resulting concurrency model is refreshingly blunt. A worker can block on PDO::query() or file_get_contents() because hundreds of siblings may remain available. Qbix spends processes to avoid spending developer time on an asynchronous rewrite, then relies on shared memory pages to make the process count affordable.

That is the central trade: code compatibility now, with operating-system scheduling and memory behavior carrying more of the load.

The PHP Stack Qbix Wants to Compress

The history behind Qbix appears in the stack its creator wants one process to replace. The announcement lists nginx, php-fpm, Certbot, cron and Node.js. The repository documentation adds Redis, supervisor and Docker when describing a real-time PHP application that passes messages from PHP through Redis to a Node-based WebSocket server.

That stack evolved from understandable divisions of labor. A front-end server handles static files and connections. php-fpm manages PHP workers. Node handles long-running sockets. Redis moves messages between otherwise separate processes. Containers and supervisors package and monitor the resulting collection.

Qbix collapses those boundaries. One server handles HTTP, WebSockets, Server-Sent Events, sessions, uploads, scheduled jobs and static files. The operational promise follows directly: fewer runtimes and fewer pieces of inter-process glue.

Consolidation also concentrates responsibility. nginx, php-fpm, Node and Redis distribute maintenance across mature projects and separate failure domains. Qbix asks one younger project to own request handling, state cleanup, sockets, certificates and several other jobs. A smaller deployment graph can reduce configuration work while increasing the consequences of a defect in the remaining node.

For an open-source adopter, that changes the evaluation. Throughput is one column. Release practices, security response, compatibility testing, maintainer capacity and upgrade behavior belong beside it. The launch materials document many features, but they do not establish how the project will sustain that unusually broad surface over time.

Qbix, Php-Fpm and the Async Alternative

php-fpm offers isolation through a familiar request lifecycle, but its worker count is constrained by the memory consumed per process. Qbix keeps workers persistent and shares preloaded code between them. Persistence avoids repeated framework startup, though it creates a new problem: request state can survive and contaminate later requests.

Qbix says it addresses that risk by snapshotting static properties and restoring them between requests in 0.03ms. It also intercepts 28 PHP functions, including header(), session_start(), ini_set() and error-handler registration, using source transformation at include time. The project says this lets unmodified WordPress, Laravel, Symfony and Drupal applications retain shared-nothing behavior.

That compatibility layer is as important as copy-on-write. A missed global, extension side effect or untracked library behavior could turn a benchmark win into a production debugging séance. The documents assert broad compatibility, but no independent compatibility suite or long-running third-party deployment is available here to test that boundary.

Swoole takes another route. In the comparison presented by Qbix's creator, Swoole coroutines can keep a small number of workers productive by yielding during I/O, provided the application enables coroutine support and uses compatible drivers. Existing blocking code cannot automatically receive that benefit.

The project's own 200ms I/O table illustrates both approaches. It reports php-fpm at 20 requests per second with four workers, Swoole at roughly 200 to 500 with four coroutine-enabled workers, and Qbix at 488 with 200 workers. Qbix therefore overlaps Swoole's reported range rather than clearly exceeding it in that test. Qbix offers the stronger migration story for unmodified blocking code; coroutine-aware Swoole can reach comparable or slightly higher throughput with far fewer workers, using the project's numbers.

The comparison has limits. Worker counts differ, and the table comes from the Qbix author. It does not establish latency distributions, CPU overhead, behavior under overload or performance across different databases and application shapes. It does show why a universal “faster than Swoole” label loses useful information. The result depends on whether developers compare untouched applications or code adapted for coroutines.

The “100 times faster” headline needs similar narrowing. The displayed benchmark tables report Qbix at 6.6 times php-fpm on a CPU-bound workload, 14 times at 50ms I/O and 24 times at 200ms I/O. Elsewhere, the site describes 100 times more workers in the same memory budget. Worker capacity and completed requests per second measure different things, so operators should resist carrying the largest multiplier from one column into another.

Where Nginx Still Keeps a Chair

Qbix's creator concedes that PHP lacks sendfile support, making protected static files slower than nginx in the described setup. The announcement recommends proxying those responses through nginx for an additional twofold speed increase, while sending public static files to a CDN.

That concession draws a practical deployment boundary. Qbix may replace nginx for some applications, especially where dynamic PHP and sockets dominate. Workloads built around access-controlled file delivery may still benefit from the supposedly obsolete layer. Infrastructure has a habit of surviving its replacement announcement when it remains excellent at one narrow job.

A sensible evaluation would therefore begin with an application's actual blocking calls, mutable memory, static-file mix and compatibility risks. Reproduce the benchmark with production code, watch proportional-set memory as requests mutate pages, test state isolation over many requests and measure tail latency when thousands of processes compete for CPU.

Qbix's most useful proposition is ultimately architectural: legacy blocking code may gain concurrency by making forks cheap instead of making every call asynchronous. Whether that proposition retires php-fpm will be decided by independent workloads, ugly plugins and long-running servers, the places where elegant diagrams eventually meet everyone else's code.

More Like This