본문 바로가기

Laravel Octane

업데이트됨

번역일: 2026년 10월 26일

이 페이지는 원문이 업데이트되어 번역이 갱신되었습니다.

원문 수정
2026년 10월 23일
번역 갱신
2026년 10월 26일

Laravel Octane

소개

Laravel Octane은 FrankenPHP, Open Swoole, Swoole, RoadRunner와 같은 고성능 애플리케이션 서버로 애플리케이션을 실행해 성능을 크게 끌어올려 줍니다. Octane은 애플리케이션을 한 번만 부팅한 뒤 메모리에 계속 유지하면서, 이후 들어오는 요청을 매우 빠르게 처리합니다.

NOTE

기존 PHP-FPM 방식은 요청마다 프레임워크를 새로 부팅하지만, Octane은 워커 프로세스가 부팅된 애플리케이션을 재사용합니다. 이 차이가 성능 향상의 핵심이며, 뒤에서 다룰 "메모리 누수"와 "의존성 주입 시 주의점"이 생기는 이유이기도 합니다.

설치

Octane은 Composer 패키지 관리자를 통해 설치할 수 있습니다.

composer require laravel/octane

Octane 설치 후에는 octane:install Artisan 명령을 실행하면 Octane의 설정 파일이 애플리케이션에 설치됩니다.

php artisan octane:install

서버 사전 요구 사항

FrankenPHP

FrankenPHP는 Go로 작성된 PHP 애플리케이션 서버로, Early Hints, Brotli, Zstandard 압축과 같은 최신 웹 기능을 지원합니다. Octane을 설치하면서 서버로 FrankenPHP를 선택하면, Octane이 FrankenPHP 바이너리를 자동으로 내려받아 설치해 줍니다.

WARNING

FrankenPHP 정적 바이너리에는 자체 PHP가 포함되어 있습니다. 따라서 시스템에 설치된 PHP를 업데이트해도 Octane이 사용하는 PHP 버전은 바뀌지 않습니다. 번들된 PHP 버전은 ./frankenphp version 명령으로 확인할 수 있습니다. PHP 보안 업데이트를 적용하려면 프로젝트 루트 디렉터리의 frankenphp 바이너리를 삭제하고 php artisan octane:install --server=frankenphp Artisan 명령을 실행해 최신 릴리스를 내려받은 뒤 Octane을 재시작하세요. FrankenPHP를 시스템 전역에 설치했다면, 설치할 때 사용한 방법으로 업데이트해야 합니다.

Laravel Sail에서 FrankenPHP 사용하기

Laravel Sail로 애플리케이션을 개발할 계획이라면, 다음 명령을 실행해 Octane과 FrankenPHP를 설치하세요.

./vendor/bin/sail up./vendor/bin/sail composer require laravel/octane

다음으로 octane:install Artisan 명령을 사용해 FrankenPHP 바이너리를 설치합니다.

./vendor/bin/sail artisan octane:install --server=frankenphp

마지막으로, 애플리케이션의 docker-compose.yml 파일에 있는 laravel.test 서비스 정의에 SUPERVISOR_PHP_COMMAND 환경 변수를 추가합니다. 이 환경 변수에는 Sail이 PHP 개발 서버 대신 Octane으로 애플리케이션을 실행할 때 사용할 명령이 들어갑니다.

services:
laravel.test:
environment:
SUPERVISOR_PHP_COMMAND: "/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan octane:start --server=frankenphp --host=0.0.0.0 --admin-port=2019 --port='${APP_PORT:-80}'" #
XDG_CONFIG_HOME: /var/www/html/config #
XDG_DATA_HOME: /var/www/html/data #

HTTPS, HTTP/2, HTTP/3를 활성화하려면 위 설정 대신 다음과 같이 수정합니다.

services:
laravel.test:
ports:
- '${APP_PORT:-80}:80'
- '${VITE_PORT:-5173}:${VITE_PORT:-5173}'
- '443:443' #
- '443:443/udp' #
environment:
SUPERVISOR_PHP_COMMAND: "/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan octane:start --host=localhost --port=443 --admin-port=2019 --https" #
XDG_CONFIG_HOME: /var/www/html/config #
XDG_DATA_HOME: /var/www/html/data #

FrankenPHP를 사용하는 Sail 애플리케이션에는 일반적으로 https://localhost로 접속하세요. https://127.0.0.1로 접속하려면 추가 설정이 필요하며 권장되지 않습니다.

Docker에서 FrankenPHP 사용하기

FrankenPHP 공식 Docker 이미지를 사용하면 성능이 더 좋아질 수 있고, FrankenPHP 정적 설치에 포함되지 않은 추가 확장도 사용할 수 있습니다. 또한 공식 Docker 이미지는 Windows처럼 FrankenPHP가 기본적으로 지원하지 않는 플랫폼에서도 실행할 수 있게 해 줍니다. FrankenPHP 공식 Docker 이미지는 로컬 개발과 프로덕션 환경 모두에 적합합니다.

다음 Dockerfile을 FrankenPHP 기반 Laravel 애플리케이션을 컨테이너화하는 출발점으로 사용할 수 있습니다.

FROM dunglas/frankenphp RUN install-php-extensions \ pcntl # Add other PHP extensions here... COPY . /app ENTRYPOINT ["php", "artisan", "octane:frankenphp"]

개발 중에는 다음 Docker Compose 파일로 애플리케이션을 실행할 수 있습니다.

# compose.yaml services: frankenphp: build: context: . entrypoint: php artisan octane:frankenphp --workers=1 --max-requests=1 ports: - "8000:8000" volumes: - .:/app

php artisan octane:start 명령에 --log-level 옵션을 명시적으로 전달하면, Octane은 FrankenPHP의 기본 로거를 사용합니다. 별도로 설정하지 않았다면 구조화된 JSON 로그가 출력됩니다.

Docker에서 FrankenPHP를 실행하는 방법에 대한 자세한 내용은 FrankenPHP 공식 문서를 참고하세요.

사용자 정의 Caddyfile 설정

FrankenPHP를 사용할 때는 Octane을 시작하면서 --caddyfile 옵션으로 사용자 정의 Caddyfile을 지정할 수 있습니다.

php artisan octane:start --server=frankenphp --caddyfile=/path/to/your/Caddyfile

이를 통해 사용자 정의 미들웨어 추가, 고급 라우팅 구성, 사용자 정의 지시어 설정 등 기본 설정으로는 할 수 없는 FrankenPHP 구성을 할 수 있습니다. Caddyfile 문법과 설정 옵션은 Caddy 공식 문서를 참고하세요.

RoadRunner

RoadRunner는 Go로 만들어진 RoadRunner 바이너리로 동작합니다. RoadRunner 기반 Octane 서버를 처음 시작하면, Octane이 RoadRunner 바이너리를 내려받아 설치할지 물어봅니다.

Laravel Sail에서 RoadRunner 사용하기

Laravel Sail로 애플리케이션을 개발할 계획이라면, 다음 명령을 실행해 Octane과 RoadRunner를 설치하세요.

./vendor/bin/sail up./vendor/bin/sail composer require laravel/octane spiral/roadrunner-cli spiral/roadrunner-http

다음으로 Sail 셸을 시작한 뒤 rr 실행 파일을 사용해 최신 Linux용 RoadRunner 바이너리를 받아옵니다.

./vendor/bin/sail shell# Sail 셸 안에서..../vendor/bin/rr get-binary

그다음 애플리케이션의 docker-compose.yml 파일에 있는 laravel.test 서비스 정의에 SUPERVISOR_PHP_COMMAND 환경 변수를 추가합니다. 이 환경 변수에는 Sail이 PHP 개발 서버 대신 Octane으로 애플리케이션을 실행할 때 사용할 명령이 들어갑니다.

services:
laravel.test:
environment:
SUPERVISOR_PHP_COMMAND: "/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan octane:start --server=roadrunner --host=0.0.0.0 --rpc-port=6001 --port='${APP_PORT:-80}'" #

마지막으로 rr 바이너리에 실행 권한이 있는지 확인하고 Sail 이미지를 빌드합니다.

chmod +x ./rr./vendor/bin/sail build --no-cache

Swoole

Swoole 애플리케이션 서버로 Laravel Octane 애플리케이션을 실행하려면 Swoole PHP 확장을 설치해야 합니다. 보통 PECL로 설치할 수 있습니다.

pecl install swoole

Open Swoole

Open Swoole 애플리케이션 서버로 Laravel Octane 애플리케이션을 실행하려면 Open Swoole PHP 확장을 설치해야 합니다. 보통 PECL로 설치할 수 있습니다.

pecl install openswoole

Laravel Octane을 Open Swoole과 함께 사용하면 동시 작업, 틱, 인터벌 등 Swoole이 제공하는 기능을 동일하게 사용할 수 있습니다.

Laravel Sail에서 Swoole 사용하기

WARNING

Sail로 Octane 애플리케이션을 실행하기 전에, 최신 버전의 Laravel Sail을 사용 중인지 확인하고 애플리케이션 루트 디렉터리에서 ./vendor/bin/sail build --no-cache를 실행하세요.

Laravel의 공식 Docker 기반 개발 환경인 Laravel Sail로 Swoole 기반 Octane 애플리케이션을 개발할 수도 있습니다. Laravel Sail에는 기본적으로 Swoole 확장이 포함되어 있습니다. 다만 Sail이 사용하는 docker-compose.yml 파일은 직접 수정해야 합니다.

먼저 애플리케이션의 docker-compose.yml 파일에 있는 laravel.test 서비스 정의에 SUPERVISOR_PHP_COMMAND 환경 변수를 추가합니다. 이 환경 변수에는 Sail이 PHP 개발 서버 대신 Octane으로 애플리케이션을 실행할 때 사용할 명령이 들어갑니다.

services:
laravel.test:
environment:
SUPERVISOR_PHP_COMMAND: "/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan octane:start --server=swoole --host=0.0.0.0 --port='${APP_PORT:-80}'" #

마지막으로 Sail 이미지를 빌드합니다.

./vendor/bin/sail build --no-cache

Swoole 설정

Swoole은 필요에 따라 octane 설정 파일에 추가할 수 있는 몇 가지 설정 옵션을 지원합니다. 거의 수정할 일이 없기 때문에 이 옵션들은 기본 설정 파일에 포함되어 있지 않습니다.

'swoole' => [ 'options' => [ 'log_file' => storage_path('logs/swoole_http.log'), 'package_max_length' => 10 * 1024 * 1024, ], ],

애플리케이션 실행하기

Octane 서버는 octane:start Artisan 명령으로 시작할 수 있습니다. 기본적으로 이 명령은 애플리케이션의 octane 설정 파일에 있는 server 설정 옵션에 지정된 서버를 사용합니다.

php artisan octane:start

기본적으로 Octane은 8000번 포트에서 서버를 시작하므로, 웹 브라우저에서 http://localhost:8000으로 애플리케이션에 접속할 수 있습니다.

프로덕션에서 Octane을 계속 실행 상태로 유지하기

Octane 애플리케이션을 프로덕션에 배포한다면, Supervisor 같은 프로세스 모니터를 사용해 Octane 서버가 항상 실행 중인 상태를 유지해야 합니다. Octane용 Supervisor 설정 파일 예시는 다음과 같습니다.

[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로 애플리케이션 실행하기

기본적으로 Octane으로 실행되는 애플리케이션은 http://로 시작하는 링크를 생성합니다. HTTPS로 애플리케이션을 제공할 때는 애플리케이션의 config/octane.php 설정 파일에서 사용하는 OCTANE_HTTPS 환경 변수를 true로 설정하면 됩니다. 이 값이 true이면 Octane은 Laravel이 생성하는 모든 링크 앞에 https://를 붙이도록 지시합니다.

'https' => env('OCTANE_HTTPS', false),

Nginx로 애플리케이션 실행하기

NOTE

직접 서버 설정을 관리할 준비가 되지 않았거나, 안정적인 Laravel Octane 애플리케이션을 운영하는 데 필요한 여러 서비스를 구성하는 것이 부담스럽다면, 완전 관리형 Laravel Octane을 지원하는 Laravel Cloud를 살펴보세요.

프로덕션 환경에서는 Octane 애플리케이션을 Nginx나 Apache 같은 일반 웹 서버 뒤에서 실행하는 것이 좋습니다. 그러면 웹 서버가 이미지, 스타일시트 같은 정적 자산을 직접 제공하고 SSL 인증서 종료(termination)도 맡을 수 있습니다.

다음 Nginx 설정 예시에서는 Nginx가 사이트의 정적 자산을 제공하고, 8000번 포트에서 실행 중인 Octane 서버로 요청을 프록시합니다.

map $http_upgrade $connection_upgrade { default upgrade; '' close; } server { listen 80; listen [::]:80; server_name domain.com; server_tokens off; root /home/forge/domain.com/public; index index.php; charset utf-8; location /index.php { try_files /not_exists @octane; } location / { try_files $uri $uri/ @octane; } location = /favicon.ico { access_log off; log_not_found off; } location = /robots.txt { access_log off; log_not_found off; } access_log off; error_log /var/log/nginx/domain.com-error.log error; error_page 404 /index.php; 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; } }

파일 변경 감지하기

애플리케이션은 Octane 서버가 시작될 때 메모리에 한 번만 로드되므로, 애플리케이션 파일을 수정해도 브라우저를 새로고침한다고 바로 반영되지 않습니다. 예를 들어 routes/web.php 파일에 추가한 라우트 정의는 서버를 재시작해야 반영됩니다. 편의를 위해 --watch 플래그를 사용하면 애플리케이션 내 파일이 변경될 때마다 Octane이 서버를 자동으로 재시작합니다.

php artisan octane:start --watch

이 기능을 사용하기 전에 로컬 개발 환경에 Node가 설치되어 있는지 확인하세요. 또한 프로젝트에 파일 감시 라이브러리인 Chokidar를 설치해야 합니다.

npm install --save-dev chokidar

감시할 디렉터리와 파일은 애플리케이션의 config/octane.php 설정 파일에 있는 watch 설정 옵션으로 지정할 수 있습니다.

워커 수 지정하기

기본적으로 Octane은 머신이 제공하는 CPU 코어마다 애플리케이션 요청 워커를 하나씩 시작합니다. 이 워커들이 애플리케이션으로 들어오는 HTTP 요청을 처리합니다. octane:start 명령을 실행할 때 --workers 옵션으로 시작할 워커 수를 직접 지정할 수 있습니다.

php artisan octane:start --workers=4

Swoole 애플리케이션 서버를 사용한다면 시작할 "태스크 워커"의 수도 함께 지정할 수 있습니다.

php artisan octane:start --workers=4 --task-workers=6

최대 요청 수 지정하기

예기치 않은 메모리 누수를 막기 위해, Octane은 워커가 500개의 요청을 처리하면 해당 워커를 정상적으로(graceful) 재시작합니다. 이 숫자는 --max-requests 옵션으로 조정할 수 있습니다.

php artisan octane:start --max-requests=250

최대 실행 시간 지정하기

기본적으로 Laravel Octane은 애플리케이션의 config/octane.php 설정 파일에 있는 max_execution_time 옵션을 통해 들어오는 요청의 최대 실행 시간을 30초로 설정합니다.

'max_execution_time' => 30,

이 설정은 들어온 요청이 종료되기 전까지 실행될 수 있는 최대 시간(초)을 정의합니다. 이 값을 0으로 설정하면 실행 시간 제한이 완전히 해제됩니다. 이 옵션은 파일 업로드, 데이터 처리, 외부 서비스 API 호출처럼 오래 걸리는 요청을 처리하는 애플리케이션에서 특히 유용합니다.

WARNING

max_execution_time 설정을 변경했다면 변경 사항이 적용되도록 Octane 서버를 재시작해야 합니다.

워커 다시 로드하기

octane:reload 명령으로 Octane 서버의 애플리케이션 워커를 정상적으로 재시작할 수 있습니다. 보통 배포 직후에 이 명령을 실행해, 새로 배포한 코드를 메모리에 로드하고 이후 요청이 그 코드로 처리되게 합니다.

php artisan octane:reload

NOTE

한국에서 흔히 쓰는 배포 방식(Git pull 후 스크립트 실행, GitHub Actions, Deployer 등)을 사용한다면, 배포 스크립트의 마지막 단계에 php artisan octane:reload를 넣어 두면 배포할 때마다 워커가 새 코드를 읽도록 보장할 수 있습니다.

서버 중지하기

octane:stop Artisan 명령으로 Octane 서버를 중지할 수 있습니다.

php artisan octane:stop

서버 상태 확인하기

octane:status Artisan 명령으로 Octane 서버의 현재 상태를 확인할 수 있습니다.

php artisan octane:status

의존성 주입과 Octane

Octane은 애플리케이션을 한 번만 부팅한 뒤 메모리에 유지하면서 요청을 처리하므로, 애플리케이션을 만들 때 고려해야 할 몇 가지 주의점이 있습니다. 예를 들어 서비스 프로바이더의 register와 boot 메서드는 요청 워커가 처음 부팅될 때 딱 한 번만 실행됩니다. 이후 요청에서는 같은 애플리케이션 인스턴스가 재사용됩니다.

따라서 객체의 생성자에 애플리케이션 서비스 컨테이너나 요청(request)을 주입할 때는 특히 주의해야 합니다. 그렇게 하면 해당 객체가 이후 요청에서 오래된(stale) 컨테이너나 요청을 가지고 있을 수 있습니다.

Octane은 요청 사이에 프레임워크 자체(first-party)의 상태를 자동으로 초기화합니다. 하지만 애플리케이션이 만들어 내는 전역 상태를 어떻게 초기화해야 하는지는 Octane이 항상 알 수는 없습니다. 그러므로 Octane에 친화적인 방식으로 애플리케이션을 작성하는 방법을 알아 두어야 합니다. 아래에서는 Octane을 사용할 때 문제를 일으킬 수 있는 가장 흔한 상황들을 살펴봅니다.

컨테이너 주입

일반적으로 애플리케이션 서비스 컨테이너나 HTTP 요청 인스턴스를 다른 객체의 생성자에 주입하는 것은 피해야 합니다. 예를 들어 다음 바인딩은 싱글톤으로 바인딩된 객체에 애플리케이션 서비스 컨테이너 전체를 주입합니다.

use App\Service; use Illuminate\Contracts\Foundation\Application; /** * Register any application services. */ public function register(): void { $this->app->singleton(Service::class, function (Application $app) { return new Service($app); }); }

이 예시에서 Service 인스턴스가 애플리케이션 부팅 과정에서 해석(resolve)되면 컨테이너가 서비스에 주입되고, 이후 요청에서도 Service 인스턴스가 그 동일한 컨테이너를 계속 보유합니다. 애플리케이션에 따라서는 문제가 되지 않을 수도 있습니다. 하지만 부팅 주기의 뒷부분이나 이후 요청에서 추가된 바인딩이 컨테이너에 없는 것처럼 보이는 예기치 않은 상황이 발생할 수 있습니다.

해결 방법으로는 바인딩을 싱글톤으로 등록하지 않거나, 항상 현재 컨테이너 인스턴스를 해석해 주는 컨테이너 리졸버 클로저를 서비스에 주입할 수 있습니다.

use App\Service; use Illuminate\Container\Container; use Illuminate\Contracts\Foundation\Application; $this->app->bind(Service::class, function (Application $app) { return new Service($app); }); $this->app->singleton(Service::class, function () { return new Service(fn () => Container::getInstance()); });

전역 app 헬퍼와 Container::getInstance() 메서드는 항상 최신 버전의 애플리케이션 컨테이너를 반환합니다.

요청 주입

일반적으로 애플리케이션 서비스 컨테이너나 HTTP 요청 인스턴스를 다른 객체의 생성자에 주입하는 것은 피해야 합니다. 예를 들어 다음 바인딩은 싱글톤으로 바인딩된 객체에 요청 인스턴스 전체를 주입합니다.

use App\Service; use Illuminate\Contracts\Foundation\Application; /** * Register any application services. */ public function register(): void { $this->app->singleton(Service::class, function (Application $app) { return new Service($app['request']); }); }

이 예시에서 Service 인스턴스가 애플리케이션 부팅 과정에서 해석되면 HTTP 요청이 서비스에 주입되고, 이후 요청에서도 Service 인스턴스가 그 동일한 요청을 계속 보유합니다. 그 결과 모든 헤더, 입력값, 쿼리 문자열 데이터는 물론 나머지 요청 데이터도 모두 잘못된 값이 됩니다.

해결 방법으로는 바인딩을 싱글톤으로 등록하지 않거나, 항상 현재 요청 인스턴스를 해석해 주는 요청 리졸버 클로저를 서비스에 주입할 수 있습니다. 또는 가장 권장되는 방법으로, 객체가 필요로 하는 특정 요청 정보를 런타임에 객체의 메서드 인자로 전달하면 됩니다.

use App\Service; use Illuminate\Contracts\Foundation\Application; $this->app->bind(Service::class, function (Application $app) { return new Service($app['request']); }); $this->app->singleton(Service::class, function (Application $app) { return new Service(fn () => $app['request']); }); // Or... $service->method($request->input('name'));

전역 request 헬퍼는 항상 애플리케이션이 현재 처리 중인 요청을 반환하므로 애플리케이션 안에서 안전하게 사용할 수 있습니다.

WARNING

컨트롤러 메서드와 라우트 클로저에서 Illuminate\Http\Request 인스턴스를 타입 힌트로 받는 것은 문제없습니다.

설정 리포지토리 주입

일반적으로 설정(configuration) 리포지토리 인스턴스를 다른 객체의 생성자에 주입하는 것은 피해야 합니다. 예를 들어 다음 바인딩은 싱글톤으로 바인딩된 객체에 설정 리포지토리를 주입합니다.

use App\Service; use Illuminate\Contracts\Foundation\Application; /** * Register any application services. */ public function register(): void { $this->app->singleton(Service::class, function (Application $app) { return new Service($app->make('config')); }); }

이 예시에서 요청 사이에 설정 값이 바뀌더라도, 서비스는 처음의 리포지토리 인스턴스에 의존하고 있으므로 새 값에 접근할 수 없습니다.

해결 방법으로는 바인딩을 싱글톤으로 등록하지 않거나, 설정 리포지토리 리졸버 클로저를 클래스에 주입할 수 있습니다.

use App\Service; use Illuminate\Container\Container; use Illuminate\Contracts\Foundation\Application; $this->app->bind(Service::class, function (Application $app) { return new Service($app->make('config')); }); $this->app->singleton(Service::class, function () { return new Service(fn () => Container::getInstance()->make('config')); });

전역 config 헬퍼는 항상 최신 버전의 설정 리포지토리를 반환하므로 애플리케이션 안에서 안전하게 사용할 수 있습니다.

메모리 누수 관리

Octane은 요청 사이에 애플리케이션을 메모리에 유지한다는 점을 기억하세요. 따라서 정적(static)으로 유지되는 배열에 데이터를 계속 추가하면 메모리 누수가 발생합니다. 예를 들어 다음 컨트롤러는 애플리케이션에 요청이 들어올 때마다 정적 $data 배열에 데이터를 계속 추가하므로 메모리 누수가 있습니다.

use App\Service; use Illuminate\Http\Request; use Illuminate\Support\Str; /** * Handle an incoming request. */ public function index(Request $request): array { Service::$data[] = Str::random(10); return [ // ... ]; }

애플리케이션을 만들 때는 이런 유형의 메모리 누수가 생기지 않도록 특별히 주의해야 합니다. 로컬 개발 중에 애플리케이션의 메모리 사용량을 모니터링해, 새로운 메모리 누수가 만들어지지 않았는지 확인하는 것을 권장합니다.

동시 작업

WARNING

이 기능은 Swoole이 필요합니다.

Swoole을 사용하면 가벼운 백그라운드 작업을 통해 여러 작업을 동시에 실행할 수 있습니다. Octane의 concurrently 메서드를 사용하면 됩니다. 이 메서드를 PHP 배열 구조 분해(array destructuring)와 함께 사용하면 각 작업의 결과를 받아올 수 있습니다.

use App\Models\User; use App\Models\Server; use Laravel\Octane\Facades\Octane; [$users, $servers] = Octane::concurrently([ fn () => User::all(), fn () => Server::all(), ]);

Octane이 처리하는 동시 작업은 Swoole의 "태스크 워커"를 사용하며, 들어온 요청과는 완전히 다른 프로세스에서 실행됩니다. 동시 작업을 처리하는 데 사용할 수 있는 워커의 수는 octane:start 명령의 --task-workers 지시어로 결정됩니다.

php artisan octane:start --workers=4 --task-workers=6

Swoole 태스크 시스템의 제약 때문에, concurrently 메서드를 호출할 때는 1024개를 넘는 작업을 전달해서는 안 됩니다.

틱과 인터벌

WARNING

이 기능은 Swoole이 필요합니다.

Swoole을 사용하면 지정한 초마다 실행되는 "틱(tick)" 작업을 등록할 수 있습니다. "틱" 콜백은 tick 메서드로 등록합니다. tick 메서드의 첫 번째 인자는 틱의 이름을 나타내는 문자열이고, 두 번째 인자는 지정한 간격마다 호출될 callable입니다.

다음 예시에서는 10초마다 호출되는 클로저를 등록합니다. 일반적으로 tick 메서드는 애플리케이션 서비스 프로바이더 중 하나의 boot 메서드 안에서 호출해야 합니다.

Octane::tick('simple-ticker', fn () => ray('Ticking...')) ->seconds(10);

immediate 메서드를 사용하면 Octane 서버가 처음 부팅될 때 틱 콜백을 즉시 호출하고, 그 이후로는 N초마다 호출하도록 지시할 수 있습니다.

Octane::tick('simple-ticker', fn () => ray('Ticking...')) ->seconds(10) ->immediate();

Octane 캐시

WARNING

이 기능은 Swoole이 필요합니다.

Swoole을 사용하면 초당 최대 200만 건의 읽기·쓰기 속도를 제공하는 Octane 캐시 드라이버를 활용할 수 있습니다. 따라서 캐시 계층에서 극한의 읽기/쓰기 속도가 필요한 애플리케이션에 매우 좋은 선택입니다.

이 캐시 드라이버는 Swoole 테이블을 기반으로 동작합니다. 캐시에 저장된 모든 데이터는 서버의 모든 워커에서 사용할 수 있습니다. 다만 서버가 재시작되면 캐시된 데이터는 모두 삭제됩니다.

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

NOTE

Octane 캐시에 허용되는 최대 항목 수는 애플리케이션의 octane 설정 파일에서 정의할 수 있습니다.

캐시 인터벌

Octane 캐시 드라이버는 Laravel 캐시 시스템이 제공하는 일반적인 메서드 외에도 인터벌 기반 캐시 기능을 제공합니다. 이 캐시는 지정한 간격마다 자동으로 갱신되며, 애플리케이션 서비스 프로바이더 중 하나의 boot 메서드 안에서 등록해야 합니다. 예를 들어 다음 캐시는 5초마다 갱신됩니다.

use Illuminate\Support\Str; Cache::store('octane')->interval('random', function () { return Str::random(10); }, seconds: 5);

테이블

WARNING

이 기능은 Swoole이 필요합니다.

Swoole을 사용하면 원하는 Swoole 테이블을 직접 정의하고 사용할 수 있습니다. Swoole 테이블은 매우 높은 처리량을 제공하며, 테이블의 데이터는 서버의 모든 워커에서 접근할 수 있습니다. 다만 서버가 재시작되면 테이블 안의 데이터는 사라집니다.

테이블은 애플리케이션의 octane 설정 파일에 있는 tables 설정 배열 안에 정의해야 합니다. 최대 1000개의 행을 허용하는 예시 테이블이 이미 설정되어 있습니다. 문자열 컬럼의 최대 크기는 아래와 같이 컬럼 타입 뒤에 크기를 지정해 설정할 수 있습니다.

'tables' => [ 'example:1000' => [ 'name' => 'string:1000', 'votes' => 'int', ], ],

테이블에 접근하려면 Octane::table 메서드를 사용하면 됩니다.

use Laravel\Octane\Facades\Octane; Octane::table('example')->set('uuid', [ 'name' => 'Nuno Maduro', 'votes' => 1000, ]); return Octane::table('example')->get('uuid');

WARNING

Swoole 테이블이 지원하는 컬럼 타입은 string, int, float입니다.

이 문서는 Laravel 공식 문서(MIT)를 한국 개발자를 위해 번역·재구성한 것입니다.

번역일: 2026년 10월 26일