# OpenSwoole: a PHP server with coroutines, fibers and a choice of reactor

> OpenSwoole is a PHP extension that gives the language a programmatic server with asynchronous IO, coroutines and fibers, and its documentation is unusually concrete about the things that usually go wrong: how to install it without losing your extension ordering, and how to switch the coroutine context so Xdebug can still see what your code is doing.

**openswoole/ext-openswoole** — Programmatic server for PHP with async IO, coroutines and fibers

- Repository: https://github.com/openswoole/ext-openswoole
- Website: https://openswoole.com
- Stars: 863 · Forks: 56
- Language: C++
- License: Apache-2.0
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/openswoole-ext-openswoole

## A server you program, not a process you configure

OpenSwoole is a programmatic server for PHP with async IO, coroutines and fibers, described as secure, reliable and high performance. The phrase programmatic server is the important one. Rather than a web server that runs a request handler and returns, you get an event loop with a set of sockets and a set of handlers, and the loop lives in the same process as your code. The coroutine model is what makes that practical in PHP: a request handler can yield while waiting on IO and another coroutine runs, without threads and without the context switch cost of an operating system thread. Fibers are the newer PHP primitive that the extension can use as its coroutine backend, which is the point of the debugging section later on.

## Installing through PIE, the modern path

PIE, the PHP Installer for Extensions, is described as the modern way to install PHP extensions, and it requires PHP 8.1 or later to run.

```shell
pie install openswoole/ext-openswoole
```

With optional configure flags, which are passed through to the extension's own configure script.

```shell
pie install openswoole/ext-openswoole \
  --enable-openssl \
  --enable-sockets \
  --enable-http2 \
  --enable-hook-curl
```

Two of these flags have consequences worth naming. The sockets flag is what gives the extension the ability to work with raw socket connections rather than only HTTP. The http2 flag enables HTTP/2 support, which is a separate capability from HTTP/1.1 handling rather than a default. The hook-curl flag makes the curl extension cooperate with the coroutine scheduler, so a curl call inside a coroutine waits for IO instead of blocking the whole reactor. The README also notes that the project always provides the most reliable stability and the most powerful features in the latest released version, and asks you to use it.

## Compiling from source, and the version floor

The compile requirements are a platform and two versions. The platform is Linux, OS X or Cygwin and WSL. The PHP version is 8.3.0 or later, with the note that the higher the version the better the performance. The compiler is GCC 4.8 or later. The source packages come from the releases, or you clone and build.

```shell
git clone https://github.com/openswoole/ext-openswoole.git && \
cd ext-openswoole
git checkout v26.2.0
phpize && \
./configure && \
make && make install
```

The checkout of a specific tag is the detail that matters: the extension tracks PHP releases closely, with recent tags being v26.2.0, v25.2.0 for PHP 8.4 and v22.1.2, so building the wrong tag against your PHP version is a common failure. The configure flags available are --enable-openssl or --with-openssl-dir=DIR, --enable-sockets, --enable-http2, --enable-mysqlnd, --enable-hook-curl, and --with-postgres with an optional directory. The mysqlnd flag is described as needed only for supporting the escape method on the mysql object.

## The extension load order is not optional

After compiling and installing the extension, you have to add a new line extension=openswoole.so at the end of php.ini, or create an ini file in the conf.d folder to enable OpenSwoole. Then the recommendation that follows is the part people miss: it is recommended to be added after all the other extensions because openswoole may depend on extensions such as sockets, mysqlnd and curl. That is an ordering dependency, not a style preference. If openswoole loads first and the extensions it hooks are not yet present, the failure is at startup and the error message will not necessarily name the ordering as the cause. The conf.d folder approach is worth preferring when your distribution or image already manages php.ini, since a separate file makes the load order explicit rather than something you have to preserve when the main file is regenerated.

## Choosing a reactor, and what each one costs

OpenSwoole uses an event-driven reactor for non-blocking IO and the type is configured globally through Co::set.

```php
Co::set(['reactor_type' => OPENSWOOLE_IO_URING]);
```

The table of available reactors is the useful part. OPENSWOOLE_SELECT uses the select system call and is portable but limited in scalability. OPENSWOOLE_POLL uses poll on Linux and macOS, with no file descriptor limit like select. OPENSWOOLE_EPOLL uses epoll on Linux for high performance with large numbers of connections. OPENSWOOLE_KQUEUE uses kqueue on macOS and BSD. OPENSWOOLE_IO_URING uses io_uring on Linux 5.1 and later, described as the highest performance with async IO support. By default OpenSwoole automatically selects the best available reactor for your platform, epoll on Linux and kqueue on macOS, so the setting is for the cases where the default is wrong.

## Reactor threads are separate from worker processes

The number of reactor threads is configured on the server object.

```php
$server = new OpenSwoole\Server('0.0.0.0', 9501);
$server->set([
    'reactor_num' => 4, // defaults to number of CPU cores
]);
```

The comment is the point: the default is the number of CPU cores, which is rarely the right number. Reactor threads are the threads that wait on IO, and they are not the same thing as the worker processes that run your handlers. A reactor thread blocked on a slow connection is not doing useful work, and having as many reactor threads as cores means a handful of slow clients can occupy every one of them. Setting the number explicitly is the first lever most people reach for when tuning an OpenSwoole service, and the default of core count is a starting point rather than a tuned value.

## The fiber context mode, and what it costs you in production

OpenSwoole supports using PHP's native Fiber API as the coroutine context backend, and this exists for compatibility with debugging and profiling tools like Xdebug that rely on PHP's fibre infrastructure to trace execution across coroutines. It is enabled with an INI setting.

```ini
openswoole.use_fiber_context=On
```

Or from code with Co::set and the use_fiber_context key set to true. When enabled, OpenSwoole uses PHP fibers internally to switch between coroutines instead of the default boost ASM context, which lets tools like Xdebug properly trace and debug coroutine execution, including step debugging, stack traces and profiling across coroutine boundaries. The note at the end is the part to carry into production planning: fiber context mode requires PHP 8.3 or later, and there is a minor performance overhead compared to the default ASM context, so it is recommended to use this mode only during development and debugging.

## Where OpenSwoole is the wrong choice

Four limits apply. It is a C++ extension, so every deployment target needs a matching build and the usual PHP extension packaging concerns, and the version coupling is tight enough that the README asks you to use the latest release. The coroutine model changes how your code is written, because a function that blocks without yielding will block the reactor, so existing blocking library calls are a hazard unless they have been hooked. The debugging story is a compromise rather than a fix, because the default ASM context is what Xdebug cannot see, and the alternative costs performance and requires PHP 8.3. And the ecosystem is comparatively young, with the framework list in the README limited to a handful of integrations and a note that pull requests are welcome for frameworks that use OpenSwoole, which tells you the coverage is not complete.

## Conclusion

Use OpenSwoole when you are running PHP at a concurrency PHP's request-per-process model cannot handle, because it gives you coroutines, fibers and an event-driven reactor with options from select through to io_uring. Do not enable it without reading the extension ordering advice, because openswoole depends on sockets, mysqlnd and curl and has to be loaded after them. Verify first which PHP version you are on, since the extension requires 8.1 to install through PIE and 8.3 to compile from source, that the reactor type you pick is available on your kernel, since io_uring needs Linux 5.1 or newer, and that you understand the fiber context mode has a performance cost and is meant for development rather than production.

## FAQ

### What is OpenSwoole?

It is a PHP extension providing a programmatic server with async IO, coroutines and fibers, described as secure, reliable and high performance. The README positions it as an event-driven reactor for non-blocking IO with a choice of reactor backends.

### How do I install OpenSwoole?

PIE, the PHP Installer for Extensions, is the modern route and requires PHP 8.1 or later to run, with pie install openswoole/ext-openswoole and optional configure flags passed through. Compiling from source needs PHP 8.3.0 or later, GCC 4.8 or later, and Linux, OS X, Cygwin or WSL.

### Which reactor backends does OpenSwoole support?

OPENSWOOLE_SELECT, portable but limited in scalability, OPENSWOOLE_POLL on Linux and macOS, OPENSWOOLE_EPOLL on Linux, OPENSWOOLE_KQUEUE on macOS and BSD, and OPENSWOOLE_IO_URING on Linux 5.1 and later. By default OpenSwoole picks the best available for the platform.

### How do I make Xdebug work with OpenSwoole coroutines?

Enable the fiber context, either with openswoole.use_fiber_context=On in php.ini or Co::set(['use_fiber_context' => true]) in code, so OpenSwoole switches coroutines with PHP fibers instead of the boost ASM context and Xdebug can trace across coroutine boundaries. The mode requires PHP 8.3 or later and carries a minor performance overhead, so it is recommended for development only.

### What licence is OpenSwoole released under?

Apache-2.0, with the LICENSE file at the repository root. The recent tags are v26.2.0 from 2026-02-28, v25.2.0 for PHP 8.4, and v22.1.2, and the last push to the repository was on 2026-08-12.

## Sources

- [License: Apache-2.0](https://github.com/openswoole/ext-openswoole/blob/master/LICENSE)
- [openswoole/ext-openswoole on GitHub](https://github.com/openswoole/ext-openswoole)
- [Project website](https://openswoole.com)
- [README](https://github.com/openswoole/ext-openswoole/blob/master/README.md)
- [Releases](https://github.com/openswoole/ext-openswoole/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/openswoole-ext-openswoole
