Serving with OpenSwoole

OpenSwoole gives Assegai a long-lived HTTP runtime instead of the normal request-per-process development server.

Use it when you want to explore:

  • long-lived workers
  • coroutine-friendly I/O
  • reusable application state between requests

The default php runtime is still the easiest place to start. OpenSwoole is the path to try when you specifically want the alternate runtime.

Install the extension first

The OpenSwoole serve path depends on the PHP extension being installed and enabled for the same PHP binary that runs assegai.

Typical Linux flow:

pecl install openswoole

Then enable the extension in your CLI and web PHP config if needed.

Check that the active PHP binary can see it:

php -m | grep openswoole

If that command returns nothing, assegai serve --runtime=openswoole will stop early and tell you the extension is missing.

Start a project with OpenSwoole

From a project root:

assegai serve --runtime=openswoole

That uses your normal bootstrap.php, but the app runs through the OpenSwoole HTTP runtime instead of php -S.

You can still choose host and port:

assegai serve --runtime=openswoole --host 127.0.0.1 --port 9510

Store the runtime in assegai.json

If a project should usually boot with OpenSwoole, keep that in config:

{
  "development": {
    "server": {
      "runtime": "openswoole",
      "host": "127.0.0.1",
      "port": 9510,
      "openBrowser": false,
      "openswoole": {
        "workerNum": 1,
        "taskWorkerNum": 0,
        "maxRequest": 0,
        "enableCoroutine": true,
        "hookFlags": "all"
      }
    }
  }
}

Then a normal serve command is enough:

assegai serve

What the settings mean

Assegai validates these settings before the runtime boots, so a typo like workerNums or an invalid value like "workerNum": 0 fails early instead of leaving you with a vague server-start error.

  • workerNum controls how many HTTP workers the server starts
  • taskWorkerNum reserves task workers for short internal offloading work
  • maxRequest lets a worker restart after a fixed number of requests
  • enableCoroutine turns coroutine support on or off
  • hookFlags controls which coroutine hooks OpenSwoole enables

hookFlags can be:

  • "all" to enable the standard full hook set
  • "none" to disable hook flags entirely
  • an integer bitmask if you already know the exact OpenSwoole constant combination you want
  • a list such as ["file", "sleep"] when you want to be explicit about the hooks you are turning on

For a first pass, the defaults are fine.

Current limits

This runtime is still experimental.

What already works well:

  • app graph boot happens once per worker
  • request and response state is refreshed per request
  • escaped handler failures go back through the framework error pipeline
  • lifecycle hooks run on worker boot and shutdown

What still needs more work:

  • broader end-to-end runtime coverage beyond the focused integration tests
  • more runtime-specific tooling around worker management
  • fuller async guidance across the ecosystem

Two practical limits matter today:

  • --https is not supported on the OpenSwoole serve path yet
  • it is not a full replacement for the default php runtime yet

When to stay on the default runtime

Stay on the normal php runtime if you are:

  • learning Assegai for the first time
  • building a conventional API or server-rendered app
  • debugging ordinary controller, DTO, ORM, or rendering work

Switch to OpenSwoole when you want to test the long-lived runtime model directly.

Read next

If you want the runtime details and current architecture boundary, continue with OpenSwoole Runtime.