Handle all your HTTP requests and WebSocket rooms securely by default, through OS-enforced process isolation. Based on PHP’s shared-nothing architecture, Qbix Server is able to run thousands of existing PHP websites★ without modification. It now runs on Linux, Mac, Windows, iOS and Android, and is able to generate standalone binaries that you can sign and distribute. And now, v2 makes it easy to make apps decentralized and continue working offline via WiFi and Bluetooth, too. 🤯
★ including WordPress, OwnCloud, Magento, Drupal, Joomla, and frameworks including Qbix, Laravel and Symfony.
git clone https://github.com/Qbix/webserver cd webserver php qbixserver.php
curl -LO https://github.com/Qbix/webserver/releases/latest/download/qbixserver-macos-arm64 chmod +x qbixserver-macos-arm64 ./qbixserver-macos-arm64
Replaces nginx + fpm + Node + Redis + supervisor + Docker.
Persistent workers at 120KB each. 400 workers on 200MB. 1,060 req/s where fpm does 78.
Learn more →Same port as HTTP. Rooms are forked processes with shared state. Socket.IO protocol. No Node.
Learn more →WordPress, Laravel, Symfony, Drupal. 27 functions rewritten as files load. Reads .htaccess. Just works.
Learn more →Authority + sandbox with one config change. Same code, different roles. Secrets never leave the authority.
Learn more →Multiple servers with SQLite. Events replicate. Kill a node, restart — it catches up.
Learn more →Resize with ?w=400. Serves AVIF or WebP from the Accept header. Save-Data support. Disk cache that regenerates when the original changes.
X-Cache-Tree for per-component invalidation. X-Accel-Redirect for access-controlled files. ETag generation. Directory listing.
Learn more →Write handler files, get OpenAPI 3.1 and MCP specs automatically. Swagger UI, Postman, Redoc — and AI tools can call your app’s API directly.
Learn more →HTTPS auto-starts when certs exist. Built-in cron scheduler. Buffered access logs with daily rotation and gzip archiving.
Learn more →Plus six example apps included: chat, kanban, SSE stream, REST API, live counter and a distributed swarm. See examples →
Every Qbix Server now has a cryptographic identity and can find other servers nearby over Bluetooth and Wi-Fi. Phones on the same bus, in the same hall, or in a place with no signal can exchange data directly, encrypted end to end, with no server in the middle.
Servers discover each other over BLE and Wi-Fi. ECDH handshake, AES-256-GCM sessions. Distance-vector routing with multi-hop relay. No central server needed.
Learn more →Runs on mobile via NativePHP/Phphone. Native TransportManager handles BLE + Wi-Fi discovery with auto-fallback. Background persistence for always-on mesh.
Learn more →Bloom filter exchange finds differences. Prolly tree comparison for large datasets — 10K records diffed in 1.2ms. Pluggable conflict resolution.
Learn more →// React to peers coming and going
Q_WebServer_Transport::onPeerOnline(function ($peer) {
Q_WebServer_MeshSync::syncWithPeer('notes', $peer['peer_id'], $since,
array('Q_WebServer_Transport', 'requestFromPeer'));
});
No breaking changes from v1.x: the mesh layer does nothing until a peer is discovered. Release notes →
The problem with php-fpm: Whether opcache is enabled or not, the vast majority of production PHP code is I/O-bound. Workers wait for the database, the filesystem, an API call. During that wait, the worker is doing nothing — but it’s holding 30–60MB of RAM. On a 4GB server, fpm gets maybe 80 workers. Each one blocks on a 200ms query. That’s the ceiling.
The problem with Swoole, RoadRunner, and FrankenPHP: They try to solve this by making PHP evented, like Node.js. But that means rewriting your code to use their async libraries. Every PDO::query(), every file_get_contents(), every curl_exec() in every WordPress plugin and Laravel package uses blocking I/O. It doesn’t yield. Swoole can’t help with code that doesn’t cooperate.
How Qbix solves it: Instead of making each worker do more, run more workers. The server loads your framework into a parent process, then calls pcntl_fork(). The kernel marks every page copy-on-write. Each worker shares the parent’s loaded classes and only pays for pages it writes to. A WordPress-like request dirties 30 pages = 120KB. The same 4GB that gives fpm 80 workers gives Qbix thousands.
Your code runs unmodified, in two modes:
Persistent workers (default) — workers stay alive across requests. 27 functions are rewritten as files load. Static properties restored from snapshot in 0.03ms. This is the fast path: 2,294 req/s on CPU-bound work.
Fork-per-request — for code the shim can’t track (functions with internal static variables, plugins that register untrackable global state). Each request gets a fresh fork. Slower than persistent mode, but each worker still costs only 120KB instead of 50MB — so you can run 100× more workers than fpm on the same hardware. That’s the whole point.
Even on Windows — where fork isn’t available, the server runs persistent workers with the same 27-function rewriting. You don’t get COW memory savings, but you get the same code compatibility and the same control panel.
We proposed this for PHP core as switch_global_context(). While that works its way through the RFC process, the server does it in userland today.
CPU-bound (WordPress-like workload, same 200MB):
| Workers | req/s | vs fpm | |
|---|---|---|---|
| php-fpm | 4 | ~350 | — |
| Swoole | 4 | ~400 | 1.1× |
| Qbix | 100 | 2,294 | 6.6× |
I/O-bound (50ms database query):
| Workers | req/s | vs fpm | |
|---|---|---|---|
| php-fpm | 4 | 78 | — |
| Swoole (coroutines*) | 4 | ~300 | ~4× |
| Qbix | 100 | 1,060 | 14× |
I/O-bound (200ms — real database load):
| Workers | req/s | vs fpm | |
|---|---|---|---|
| php-fpm | 4 | 20 | — |
| Swoole (coroutines*) | 4 | ~200–500 | ~10–25× |
| Qbix | 200 | 488 | 24× |
* Swoole coroutines require Runtime::enableCoroutine() and coroutine-aware drivers. Unmodified WordPress/Laravel uses blocking I/O and hits fpm’s ceiling.
Workers are persistent — they handle thousands of requests without restarting. Between each request, a Reflection-based snapshot restores all static properties in 0.03ms. 27 PHP functions are rewritten as each file is loaded, before PHP compiles it:
header(), setcookie(), session_start(), move_uploaded_file(), ini_set(), register_shutdown_function(), set_error_handler(), spl_autoload_register(), putenv(), and 18 others — all tracked per request and cleaned up between requests.
Unmodified WordPress, Laravel, Symfony, and Drupal get shared-nothing safety automatically. No adapters, no code auditing.
Full compatibility details → · What gets rewritten in each framework →
| Metric | php-fpm | Qbix |
|---|---|---|
| Workers on 4GB | ~80 (50MB each) | 400 (120KB each) |
| Throughput (200ms I/O) | ~80 req/s | ~2,000 req/s |
| Concurrent active users | 1,600 | 40,000 |
| Registered accounts | 16K–32K | 400K–800K |
| WebSocket | Needs Node.js | 100K+ built in |
| Database | Needs Postgres | SQLite (50K writes/sec) |
| Monthly cost | $30 + DB server | $30 total |
One machine. No database server, no Redis, no Node, no Docker. Add a second with DNS failover for redundancy — distributed mode keeps both SQLite copies in sync.
Load everything once. Fork workers. Each costs 120KB, not 42MB.
Built-in at /Q/dashboard. No Grafana, no Prometheus.
git clone https://github.com/Qbix/webserver cd webserver php qbixserver.php --root=examples/todo/web
Download a binary for your platform. PHP is bundled inside — nothing to install.
On Linux and macOS, thousands of COW-forked workers at ~120KB each. On Windows, persistent workers with the same 27-function rewriting. On phones, the same server behind a native Bluetooth and Wi-Fi transport. FreeBSD builds from source.
If you already have a PHP app running on nginx + php-fpm, switching is one command.
cd my-laravel-app && php qbixserver.php --root=public --preset=laravel cd my-wordpress-site && php qbixserver.php --root=. --preset=wordpress cd my-symfony-app && php qbixserver.php --root=public --preset=symfony cd my-drupal-site && php qbixserver.php --root=web --preset=drupal
Try persistent mode first — it handles most apps. If yours needs fork-per-request, that’s still 100× more workers than fpm on the same hardware. How your code gets rewritten →