Octane·FrankenPHP Runtime
Why Nexia runs Laravel through Octane and FrankenPHP, and what the long-lived worker model changes for Core and App code.
Octane and FrankenPHP Runtime
Keep tenant and actor objects inside the current call; do not capture them in static properties or process-wide singletons. If a local PHP change is not visible, run task app:reload and retry. The details below explain the worker lifecycle; Tenant and context covers context restoration.
Persistent PHP workers
Nexia runs the Laravel host with Laravel Octane and FrankenPHP. FrankenPHP is the selected application server. Octane is the Laravel integration layer that boots the application into workers, hands requests and tasks to those workers, and prepares the framework between operations.
This differs from a process model that boots a fresh PHP application for every HTTP request. A worker can serve many requests before it is recycled. Framework services and warmed code can therefore be reused, while request-specific state must be cleared or replaced deliberately.
Runtime responsibilities
| Layer | Runtime responsibility |
|---|---|
| FrankenPHP | Accept HTTP traffic and run persistent PHP workers |
| Laravel Octane | Boot Laravel, dispatch operations, and invoke preparation or cleanup listeners |
| Core | Establish and release tenant, actor, authorization, and contribution runtime state |
| App SDK | Expose request-safe contracts without leaking Core implementations |
| App | Keep domain code scoped to the current call and avoid process-global request state |
Code reload and worker restart
The development watch list includes Core, configuration, routes, the local App
SDK source folder, and App package source folders. That makes local changes
normally restart the development worker. If the running web worker still serves
the previous code, run task app:reload and then reload the browser. This is a
deterministic local fallback that restarts only the Octane app container and
waits until it is healthy.
A production deployment must likewise restart workers after code or cached configuration changes; a persistent worker does not discover a new release merely because files changed on disk.
HTTP and queue context
Octane does not define Nexia tenancy. It provides lifecycle hooks; Core owns the responsibility for establishing and safely clearing the tenant and authenticated user for each request.
Finally, queue workers are separate long-lived processes. They share the same
need to restore and release context, but octane:frankenphp does not supervise
the Redis/Horizon queue runtime by itself. HTTP and queue operations belong to
the same deployment model while retaining separate worker lifecycles.
Two tenants in one worker
Consider two consecutive requests handled by one worker. The first request is for tenant A and opens a Workshop record. The next request is for tenant B. The framework prepares the application for the second request, tenant middleware identifies B, and Core resolves B's actor and authorization state. The Workshop App queries through the current tenant connection and returns only B's record.
If the App had stored tenant A's model in a static property, Octane could keep that object alive and make the second request unsafe. The correct implementation stores durable facts in tenant persistence, passes identifiers through explicit contracts, and resolves request-bound objects only after the current tenant and actor exist. Recycling a worker after a maximum number of requests is a defensive operational control, not the fix for a context leak.
Related
- Tenant and context — defines the state that every HTTP or async operation must establish.
- App lifecycle — follows App discovery and installation inside the host.
- Handle events and jobs — restores context outside an HTTP request.
- Set up App development — runs the supported host and mounted package workspace.