OxPHP

Asynchronous PHP application server written in Rust.
Replaces nginx + PHP‑FPM with a single binary.

Features

Native PHP via Custom SAPI

Executes PHP natively through a custom sapi_module_struct — no CGI, no FastCGI, no external process. Full ZTS thread safety with OPcache + JIT.

🧵

Multi-Threaded Worker Pool

Dedicated OS thread per PHP worker with ZTS isolation. Static (PHP_WORKERS=N) or dynamic (MIN:MAX) scaling with automatic dead worker respawning.

🌐

Modern HTTP Stack

Built on Hyper + Tokio for async I/O. HTTP/1.1 with keep-alive, Brotli compression, HTTP caching with ETag/304, native TLS via rustls, and configurable timeouts.

📊

Built-in Observability

Prometheus metrics at /metrics, health checks at /health, structured JSON access logging, and auto-generated X-Request-ID headers.

🛡

Production Ready

Per-IP rate limiting, cooperative execution deadlines, graceful shutdown with connection draining, custom error pages, and bounded request queues with backpressure.

🔀

Flexible Routing

Three modes: Traditional (direct file mapping), Framework (front controller), and SPA (HTML5 history). Static file serving with MIME detection and caching.

📡

SSE & Streaming

Server-Sent Events and chunked transfer encoding with real-time flush. Use oxphp_stream_flush() to push data as it becomes available.

🧩

Plugin System

Typed event dispatcher with priority ordering. Core features (rate limiting, metrics, compression) are implemented as plugins using the same API available to extensions.

🚀

High Performance

mimalloc allocator, zero-clone hot path, lock-free response slot pool, pre-allocated buffers. Benchmarked at ~32.7k req/s — outperforming nginx + PHP‑FPM.

Quick Start

Dockerfile
FROM ghcr.io/oxphp/oxphp:nightly

COPY --chown=www-data:www-data . /var/www/html

Place your PHP application in the build context. The document root is /var/www/html/public.

Build & Run
# Build your image
docker build -t my-app ghcr.io/oxphp/oxphp:nightly

# Run with defaults (auto-scaled workers, port 8080)
docker run -p 8080:8080 my-app

# Run with custom configuration
docker run -p 8080:8080 \
  -e PHP_WORKERS=8 \
  -e RATE_LIMIT=100 \
  -e INDEX_FILE=index.php \
  my-app
Example project structure
my-app/
├── Dockerfile
├── public/          # ← DOCUMENT_ROOT
│   ├── index.php    # front controller (framework mode)
│   └── assets/      # static files (served directly)
├── app/             # application code (outside doc root)
│   ├── routes.php
│   └── ...
└── preload.php      # OPcache preload (optional)

Configuration

All configuration is via environment variables. No config files needed.

Server
VariableDefaultDescription
LISTEN_ADDR0.0.0.0:8080HTTP listen address
DOCUMENT_ROOT/var/www/html/publicDocument root path
INDEX_FILE(empty)Routing mode: index.php = framework, index.html = SPA
TOKIO_WORKERS0Async I/O threads (0 = auto, CPU/2)
COMPRESSION_LEVEL4Brotli compression level (0-11, 0=off)
STATIC_CACHE_TTL30dStatic file cache TTL (30s, 5m, 2h, 30d, 1w, 1y, or off)
PHP Workers
VariableDefault
PHP_WORKERS0 (auto: cpu×2)
QUEUE_CAPACITYworkers × 128
PHP_WORKERS_IDLE_SECONDS30

PHP_WORKERS=8 (static) or PHP_WORKERS=2:16 (dynamic scaling).

Worker Mode
VariableDefault
WORKER_FILE(none)
WORKER_MAX_REQUESTS0 (unlimited)
WORKER_MAX_MEMORY_MIB0 (unlimited)

Set WORKER_FILE=../worker.php for persistent PHP with soft reset between requests.

Timeouts
VariableDefault
REQUEST_TIMEOUT_SECONDS120
HEADER_TIMEOUT_SECONDS5
DRAIN_TIMEOUT_SECONDS30
Security
VariableDefault
RATE_LIMIT0 (off)
RATE_WINDOW_SECONDS60 sec
TLS_CERT(none)
TLS_KEY(none)
Observability
VariableDefault
INTERNAL_ADDR(none)
ACCESS_LOGtrue
LOG_LEVELinfo
ERROR_PAGES_DIR(none)

Set INTERNAL_ADDR=0.0.0.0:9090 to enable /health, /metrics, /config.

PHP Functions

OxPHP exposes these functions to PHP scripts via the oxphp_sapi extension.

oxphp_request_id(): string

Returns the 16-char hex request ID for the current request.

oxphp_worker_id(): int

Returns the zero-based worker thread index.

oxphp_server_info(): array

Returns SAPI name, version, worker ID, request timestamp, and worker mode flag.

oxphp_finish_request(): bool

Sends response immediately, continues background execution.

oxphp_stream_flush(): bool

Activates streaming mode and flushes output as a chunk.

oxphp_is_worker(): bool

Returns true if running in worker mode, false in traditional mode.

oxphp_is_streaming(): bool

Returns true if chunked/SSE streaming mode is active.

oxphp_request_heartbeat(int $time = 10): bool

Extends the execution deadline by N seconds.

oxphp_worker(callable $handler): bool

Enters persistent worker loop. Calls handler per request with soft reset.

Documentation

SectionContent
Getting StartedInstallation, Docker setup, quick start guide
ArchitectureRequest lifecycle, worker pool, SAPI bridge, event system
FeaturesRouting, TLS, compression, rate limiting, error pages, timeouts
PHP IntegrationCustom functions, superglobals, OPcache configuration
OperationsConfiguration reference, health checks, metrics, graceful shutdown

Available in: English · Русский · Беларуская · 中文