Zum Hauptinhalt springen

Was ist Octane

Laravel Octane ist ein Paket, das mit hochperformanten Application-Servern die Performance Ihrer Laravel-Anwendung drastisch steigert. Bei klassischem PHP-FPM wird die Anwendung für jeden Request neu gestartet und danach wieder beendet. Octane startet die Anwendung nur einmal, hält sie im Speicher und verarbeitet nachfolgende Requests dadurch sehr schnell. Der entscheidende Unterschied zu PHP-FPM: Der Bootstrap der Anwendung (z. B. das Registrieren der Service-Provider) wird nicht bei jedem Request wiederholt. Einmal gestartet, verarbeitet Octane Requests extrem schnell.

Unterstützte Server

Octane unterstützt drei Server:
ServerSpracheInstallationNebenläufige TasksHinweise
FrankenPHPGoAutomatisch (Binary)Empfohlen. Unterstützt HTTP/3 und Brotli
RoadRunnerGoAutomatisch (Binary)Einfach zu konfigurieren
SwoolePHP-ErweiterungManuell über PECLNebenläufige Tasks und Octane-Cache verfügbar
In Laravel Cloud wird der Octane-Betrieb mit FrankenPHP empfohlen und vollständig verwaltet unterstützt.

Installation und Konfiguration

Paket installieren

composer require laravel/octane

Erstkonfiguration von Octane

php artisan octane:install
Beim Ausführen werden Sie zur Auswahl eines Servers aufgefordert. Nach der Auswahl wird config/octane.php erzeugt.

FrankenPHP

Wenn Sie FrankenPHP wählen, lädt Octane das Binary automatisch herunter. Weitere Schritte sind nicht nötig.

RoadRunner

Wenn Sie RoadRunner wählen, lädt Octane das Binary automatisch herunter.

Swoole

Swoole installieren Sie als PHP-Erweiterung über PECL.
pecl install swoole
Für Open Swoole verwenden Sie:
pecl install openswoole

Server starten

Server starten

php artisan octane:start
Der Standardport ist 8000. Erreichbar unter http://localhost:8000.

Server auswählen

php artisan octane:start --server=frankenphp
php artisan octane:start --server=roadrunner
php artisan octane:start --server=swoole

Anzahl der Worker festlegen

php artisan octane:start --workers=4
Bei Swoole können Sie zusätzlich Task-Worker angeben:
php artisan octane:start --workers=4 --task-workers=6

Dateien überwachen

Während der Entwicklung werden Dateiänderungen ohne Neustart des Servers nicht wirksam. Mit dem Flag --watch startet der Server automatisch neu.
php artisan octane:start --watch
Für --watch werden Node.js und Chokidar benötigt.
npm install --save-dev chokidar

Weitere Verwaltungsbefehle

# Worker neu laden (nach Deployment ausführen)
php artisan octane:reload

# Server stoppen
php artisan octane:stop

# Server-Status prüfen
php artisan octane:status

Hinweise zur Dependency Injection

Da Octane die Anwendung im Speicher hält, wird register bzw. boot der Service-Provider nur einmal beim Serverstart ausgeführt. Dieselbe Anwendungsinstanz wird über mehrere Requests hinweg wiederverwendet. Sein Sie daher vorsichtig, wenn Sie den Container oder den Request in Konstruktoren injizieren.

Container injizieren

Wenn Sie den Container direkt in den Konstruktor eines Singleton injizieren, wird der alte Container wiederverwendet.
// ❌ Problematisch — der alte Container wird wiederverwendet
$this->app->singleton(Service::class, function (Application $app) {
    return new Service($app);
});

// ✅ Sicher — per Closure immer den aktuellen Container beziehen
$this->app->singleton(Service::class, function () {
    return new Service(fn () => Container::getInstance());
});
Die globalen Helfer app() und Container::getInstance() liefern stets den aktuellen Container und sind daher sicher.

Request injizieren

// ❌ Problematisch — der alte Request wird wiederverwendet
$this->app->singleton(Service::class, function (Application $app) {
    return new Service($app['request']);
});

// ✅ Sicher — per Closure immer den aktuellen Request beziehen
$this->app->singleton(Service::class, function (Application $app) {
    return new Service(fn () => $app['request']);
});

// ✅ Am besten — nur die benötigten Werte an die Methode übergeben
$service->method($request->input('name'));
In Controller-Methoden oder Route-Closures ist es sicher, Illuminate\Http\Request per Typ-Hint zu verwenden. Auch der globale Helfer request() liefert stets den aktuellen Request.

Config-Repository injizieren

// ❌ Problematisch — auch wenn sich Config-Werte ändern, wird das alte Repository verwendet
$this->app->singleton(Service::class, function (Application $app) {
    return new Service($app->make('config'));
});

// ✅ Sicher
$this->app->singleton(Service::class, function () {
    return new Service(fn () => Container::getInstance()->make('config'));
});
Der globale Helfer config() liefert stets das aktuelle Config-Repository und ist daher sicher.

Speicherlecks vermeiden

Da Octane die Anwendung im Speicher behält, führen z. B. Daten, die in statischen Eigenschaften angesammelt werden, zu Speicherlecks.
// ❌ Beispiel für ein Speicherleck — $data wächst mit jedem Request
class Service
{
    public static array $data = [];
}

public function index(Request $request): array
{
    Service::$data[] = Str::random(10);
    return [];
}

Worker mit max-requests recyceln

Sie können Worker nach einer bestimmten Anzahl Requests automatisch neu starten, um Speicherlecks abzumildern. Standard ist 500 Requests.
php artisan octane:start --max-requests=250

Maximale Ausführungszeit einstellen

In config/octane.php legen Sie die maximale Ausführungszeit eines Requests fest. Standard ist 30 Sekunden.
'max_execution_time' => 30,
Nach einer Änderung von max_execution_time müssen Sie den Octane-Server neu starten.

Nebenläufige Tasks (nur Swoole)

Mit Swoole können Sie über Octane::concurrently() mehrere Aufgaben parallel ausführen.
use App\Models\User;
use App\Models\Server;
use Laravel\Octane\Facades\Octane;

[$users, $servers] = Octane::concurrently([
    fn () => User::all(),
    fn () => Server::all(),
]);
Nebenläufige Tasks werden als „Task-Worker“ von Swoole in separaten Prozessen ausgeführt. Die Anzahl legen Sie mit --task-workers fest.
php artisan octane:start --workers=4 --task-workers=6
An concurrently können maximal 1024 Tasks übergeben werden (Limit von Swoole).

Tick und Interval (nur Swoole)

Mit Swoole können Sie in festgelegten Intervallen wiederkehrende Aufgaben registrieren. Sie werden in der boot-Methode eines Service-Providers registriert.
use Laravel\Octane\Facades\Octane;

// Alle 10 Sekunden ausführen
Octane::tick('delayed-ticker', fn () => ray('Ticking...'))
    ->seconds(10);

// Zusätzlich direkt beim Serverstart ausführen
Octane::tick('immediate-ticker', fn () => ray('Ticking...'))
    ->seconds(10)
    ->immediate();

Octane-Cache (nur Swoole)

Ein extrem schneller In-Memory-Cache basierend auf Swoole Tables. Bis zu 2 Millionen Lese-/Schreibvorgänge pro Sekunde sind möglich.
use Illuminate\Support\Facades\Cache;

Cache::store('octane')->put('framework', 'Laravel', 30);

Interval-Cache

Cache, der sich in einem festgelegten Intervall automatisch aktualisiert.
use Illuminate\Support\Str;

Cache::store('octane')->interval('random', function () {
    return Str::random(10);
}, seconds: 5);
Beim Neustart des Servers gehen alle Daten im Octane-Cache verloren.

Swoole-Tabellen (nur Swoole)

Sie können beliebige In-Memory-Tabellen definieren, auf die alle Worker zugreifen. Konfiguriert werden sie in config/octane.php unter tables.
'tables' => [
    'example:1000' => [
        'name' => 'string:1000',
        'votes' => 'int',
    ],
],
Der Zugriff erfolgt über die Methode Octane::table().
use Laravel\Octane\Facades\Octane;

Octane::table('example')->set('uuid', [
    'name' => 'Nuno Maduro',
    'votes' => 1000,
]);

$row = Octane::table('example')->get('uuid');
Als Spaltentypen sind in Swoole-Tabellen nur string, int und float möglich. Beim Serverneustart gehen die Daten verloren.

Produktivbetrieb

Nginx + Octane

In der Produktion wird Octane typischerweise hinter Nginx betrieben. Nginx bedient statische Dateien und terminiert TLS, dynamische Requests werden an Octane geproxyt.
map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

server {
    listen 80;
    server_name example.com;
    root /home/forge/example.com/public;

    location /index.php {
        try_files /not_exists @octane;
    }

    location / {
        try_files $uri $uri/ @octane;
    }

    location @octane {
        set $suffix "";

        if ($uri = /index.php) {
            set $suffix ?$query_string;
        }

        proxy_http_version 1.1;
        proxy_set_header Host $http_host;
        proxy_set_header Scheme $scheme;
        proxy_set_header SERVER_PORT $server_port;
        proxy_set_header REMOTE_ADDR $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;

        proxy_pass http://127.0.0.1:8000$suffix;
    }
}

Persistieren mit Supervisor

Im Produktivbetrieb halten Sie Octane mit Supervisor dauerhaft am Laufen.
[program:octane]
process_name=%(program_name)s_%(process_num)02d
command=php /home/forge/example.com/artisan octane:start --server=frankenphp --host=127.0.0.1 --port=8000
autostart=true
autorestart=true
user=forge
redirect_stderr=true
stdout_logfile=/home/forge/example.com/storage/logs/octane.log
stopwaitsecs=3600

HTTPS aktivieren

Damit über Octane HTTPS-Links generiert werden, setzen Sie in der .env:
OCTANE_HTTPS=true

Integration mit Laravel Cloud

Laravel Cloud unterstützt Octane mit FrankenPHP vollständig verwaltet. Konfigurationen für Nginx oder Supervisor sind nicht erforderlich – in nur zwei Schritten aktivieren Sie Octane.
1

Paket installieren

Installieren Sie Octane. Den Befehl octane:install können Sie ausführen, er ist aber nicht zwingend erforderlich.
composer require laravel/octane
2

Octane in Laravel Cloud aktivieren

Öffnen Sie in der Umgebung die Einstellungen des App-Compute-Clusters, aktivieren Sie „Use Octane as runtime“ und speichern bzw. deployen Sie. Laravel Cloud baut und startet die Anwendung automatisch mit FrankenPHP + Octane.
Details finden Sie in der Dokumentation von Laravel Cloud.

Worker nach Deployment neu laden

Um nach dem Deployment neuen Code in den Speicher zu laden, führen Sie ein Reload der Worker aus.
php artisan octane:reload
Zuletzt geändert am 13. Juli 2026