laravel/octane
Laravel Octane accelerates Laravel by running it on high-performance app servers like FrankenPHP, Open Swoole/Swoole, and RoadRunner. It boots your app once, keeps it in memory, and serves requests rapidly for better throughput and latency.
Installation:
composer require laravel/octane
php artisan octane:install
Choose your preferred server (FrankenPHP, Swoole, RoadRunner, or OpenSwoole) during installation.
First Run:
php artisan octane:start
Access your app via http://localhost:8000 (default port).
Verify: Check logs for worker initialization:
tail -f storage/logs/octane.log
Compare response times between traditional php artisan serve and Octane:
# Traditional
ab -n 1000 -c 10 http://localhost:8000/
# Octane
ab -n 1000 -c 10 http://localhost:8000/
Expect 5-10x faster response times under concurrent load.
php artisan octane:install --server=frankenphp
php artisan octane:install --server=roadrunner
Customize in config/octane.php:
'workers' => [
'connections' => [
'http' => [
'options' => [
'max_connections' => 100, // Default: 50
'max_requests' => 1000, // Default: 0 (unlimited)
],
],
],
],
Leverage Octane’s Boost for high-performance DI:
use Laravel\Octane\Boost;
class MyService {
public function __construct(
private Boost $boost,
) {}
public function resolve() {
return $this->boost->resolve(MyOtherService::class);
}
}
Offload blocking operations:
use Laravel\Octane\Facades\Octane;
Octane::concurrently(function () {
// Fire-and-forget task
dispatch(new ProcessHeavyTask);
});
Enable during development:
php artisan octane:start --watch
chokidar (configured in octane.php).Use the Dockerfile template from Octane’s docs:
FROM laravel/octane:frankenphp-8.2
WORKDIR /var/www/html
COPY . .
RUN composer install --optimize-autoloader --no-dev
Octane automatically flushes Vite’s per-request state:
// vite.config.js
export default defineConfig({
server: {
watch: {
usePolling: true, // Required for Octane's file watcher
},
},
});
Use Swoole’s async workers for queue listeners:
php artisan octane:install --server=swoole --with-queue-worker
Configure in config/octane.php:
'workers' => [
'queue' => [
'options' => [
'worker_num' => 4, // Match CPU cores
],
],
],
Mock Octane in PHPUnit:
use Laravel\Octane\Testing\Concerns\InteractsWithOctane;
class MyTest extends TestCase {
use InteractsWithOctane;
public function test_with_octane() {
$this->actingAsOctane();
// Test logic...
}
}
Allowed memory size exhausted.max_requests in octane.php to force worker recycling:
'max_requests' => 1000,
--memory-limit flag:
php artisan octane:start --memory-limit=512M
node_modules and vendor from watch list:
'watch' => [
'exclude' => [
'node_modules',
'vendor',
'storage/*',
],
],
APP_DEBUG=true in .env.DB::disconnect() in middleware:
public function terminate(Request $request) {
DB::disconnect();
}
reset_on_exit:
'connections' => [
'http' => [
'options' => [
'reset_on_exit' => true,
],
],
],
HandleRequests:
Octane::serving(function () {
$app->middleware(Cors::class);
});
RoadRunner\Worker::getStdout() for logging:
public function onWorkerStart() {
$this->getStdout()->write("Worker started\n");
}
dd() or dump() in Octane (use Log::debug() instead).tail -f storage/logs/octane.log
php artisan octane:start --verbose
http://localhost:2323.rr get-stats CLI command.\Swoole\Runtime::stats();
| Error | Solution |
|---|---|
Class not found |
Ensure composer dump-autoload ran after installing Octane. |
Port already in use |
Kill existing processes: lsof -i :8000 → kill -9 <PID>. |
OPcache errors |
Set OPcache.enable=0 in php.ini or use octane:clear-opcache. |
Queue worker not starting |
Verify APP_ENV=local and QUEUE_CONNECTION=swoole in .env. |
Extend Laravel\Octane\Worker:
use Laravel\Octane\Worker;
class CustomWorker extends Worker {
protected function handle(): void {
$this->app->make(MyCustomHandler::class)->handle($this->request);
}
}
Register in config/octane.php:
'workers' => [
'custom' => [
'class' => \App\Octane\CustomWorker::class,
],
],
Inject middleware dynamically:
Octane::serving(function () {
$app->pushMiddleware(MyOctaneMiddleware::class);
});
Caddyfile via CADDY_EXTRA_CONFIG:
CADDY_EXTRA_CONFIG=@extra config/octane/frankenphp/Caddyfile
rr.yaml:
server:
command: "php artisan octane:start --server=roadrunner"
env:
APP_ENV: production
Profile DI resolution:
use Laravel\Octane\Boost;
$boost = app(Boost::class);
$boost->profile(function () {
return resolve(MyHeavyService::class);
});
--daemon mode:
How can I help you explore Laravel packages today?