swooletw/laravel-swoole
Run Laravel or Lumen on the Swoole extension for a major performance boost. This package serves your app through Swoole's high-performance HTTP server, keeping the framework bootstrapped in memory to slash per-request overhead and handle high concurrency with ease.
laravel-swoole replaces PHP-FPM with a persistent Swoole HTTP server that boots your Laravel app once per worker and reuses it across requests. v2.13.0 adds Laravel 10.x support, so the package is now viable for current Laravel projects (PHP 8.1+ required by Laravel 10 — confirm your ext-swoole is 4.8+ or 5.x).
Minimal path:
pecl install swoole (or distro package) and verify with php --ri swoole — include sockets, openssl, http2 if you terminate TLS or use coroutines.composer require swooletw/laravel-swoole:^2.13 — pin the minor, since Laravel 10 support landed only in 2.13.0 and earlier 2.x constraints may resolve against incompatible Illuminate versions.php artisan vendor:publish --tag=laravel-swoole and review config/swoole_http.php.php artisan swoole:http start.Look first at server.host / server.port (default 1215), server.options (worker_num, max_request, task_worker_num, package_max_length), and the hosts array if you serve more than one app from one process.
First use case: put the Swoole listener behind nginx as a reverse proxy for a JSON API or a read-heavy app where per-request framework bootstrap is the dominant cost. Keep php artisan serve for local debugging — don't develop against Swoole until the app is stateless.
Reverse-proxy deployment. Let nginx own TLS, static assets, and compression; proxy everything else to 127.0.0.1:1215 with proxy_set_header Host, X-Real-IP, X-Forwarded-For, and X-Forwarded-Proto. Configure Laravel's trusted proxies so url() and secure URLs generate correctly behind the proxy.
Multi-app routing. The hosts config key lets one Swoole process serve several Laravel applications keyed by hostname. Useful for a monorepo of small APIs; skip it if you only have one app — separate processes are easier to reason about.
Deploys. Use php artisan swoole:http reload for graceful worker recycling so in-flight requests finish; restart/stop are hard. Run config:cache and route:cache as part of the release, then reload — never edit config under a running server.
State discipline. Treat every singleton as process-global. Register request-dependent data with scoped() bindings rather than singleton(), resolve the current user from $request rather than caching it on a service, and never store per-request values in static properties. Set server.options.max_request (a few hundred to a thousand) as a safety valve that recycles workers before drift becomes a memory leak.
Bootstrapping via config. The providers key registers app-specific providers that boot once per worker — the right place for Swoole timers, task-worker handlers, connection pools, or metric registration. Anything that must run per request belongs in middleware.
Async work. With task_worker_num set, you can hand blocking work to task workers instead of blocking the request coroutine. For normal queue workloads keep your existing queue workers; don't repurpose task workers as a job runner.
exit, die, and dd() kill the worker process, not just the request. dd() is the classic footgun — use Log::debug() or an Xdebug breakpoint instead.$_GET, $_POST, and $_SERVER are empty or stale; always go through the Request object.config(['x' => 'y']) and Config::set() leak into every subsequent request on that worker. Do the same for Carbon::setTestNow(), App::setLocale(), and container rebinds.env() outside config files is unreliable once config is cached — and caching is mandatory in production here.package_max_length, not php.ini's upload_max_filesize. Large payloads fail before Laravel sees them.wait_timeout and idle connection counts, and consider a connection pool or periodic max_request recycling.swoole:http start in the foreground with one worker, tail storage/logs/laravel.log, and set server.options.log_file for Swoole-level errors. If a request hangs, check whether a coroutine is blocked on synchronous I/O.terminate() middleware or deferred providers.laravel-swoole if you need its multi-host config, already run it, or want the lighter dependency footprint; otherwise Octane is the safer default.How can I help you explore Laravel packages today?