Swoole by Examples
August 1, 2026 · View on GitHub
The repository is to help developers to get familiar with Swoole through a variety of examples. All the examples are fully functioning; they can be executed and verified using the Docker images provided.
NOTE: I'm adding examples for latest versions of Swoole, so please be patient.
Setup the Development Environment
We use Docker to setup our development environment. Other than Docker, you don't need to install any other software to run and test the examples: you don't need to have PHP, Swoole, Composer, or some other software installed locally.
We use the official Docker image of Swoole to run the examples. There are tens of examples under repository swoole/docker-swoole shown how to use the image. Please spend some time checking it first.
Before running the examples, please run command docker-compose up -d under the root repository directory to start the
Docker containers. There are two containers used to run the examples:
- a server container where application servers are running.
- a client container where client-side scripts should be executed.
Both containers have the same PHP scripts in place, so most standalone scripts (e.g., most CSP programming examples) can be executed from either container. Once the containers are running, you can use one of following commands to get a Bash shell in the containers:
docker compose exec -ti server bash # Get a Bash shell in the server container.
docker compose exec -ti client bash # Get a Bash shell in the client container.
List of Examples
The examples are grouped by topic, progressing from coroutine fundamentals to servers, clients, and operational patterns like multiprocessing and cronjobs.
- CSP programming: coroutine fundamentals — how Swoole turns blocking PHP code into concurrent, non-blocking code.
- from blocking I/O to non-blocking I/O
- blocking I/O: a plain PHP script in which every call blocks the whole process.
- non-blocking I/O: the same script rewritten with coroutines. There is also a debug version showing the exact order in which the non-blocking version executes.
- blocking vs non-blocking: how the return statement is treated differently in Swoole — a function call could return a value back first before finishing its execution.
- coroutines
- create coroutines
- many coroutines created in a loop
- nested coroutines
- yield and resume coroutines
- exit from coroutines
- enable and disable coroutines: the different ways to enable and disable coroutine support (runtime hooks) in a standalone process.
- context: per-coroutine data storage using Context objects.
- benchmark: create 1,000,000 coroutines in a single process; each coroutine sleeps for 5 seconds.
- channels and synchronization
- channels: basic usage: pass data between coroutines.
- class \Swoole\Coroutine\WaitGroup: wait for a group of coroutines to finish (like the WaitGroup type in Golang).
- class \Swoole\Coroutine\Barrier: wait for a set of coroutines to finish by tracking references to a shared barrier object.
- defer: register cleanup callbacks that run (in reverse order) when a coroutine finishes.
- runtime hooks: make blocking PHP functions and extensions coroutine-friendly without changing their code.
- configure and utilize different runtime hook flags in Swoole
- curl. There are two different ways to hook curl functions:
- Option SWOOLE_HOOK_NATIVE_CURL (recommended)
- Option SWOOLE_HOOK_CURL: This approach is implemented through Swoole Library; however, it doesn't work for curl_multi*_ functions.
- the
mysqliextension - the
PDO(PHP Data Objects) extension - Redis clients
- locks: the same locking concept at three different scopes.
- use a lock across coroutines (Swoole v6.1.0+ only)
- use a lock across processes
- use a lock across threads (Swoole v6.1.0+ only)
- deadlocks
- how deadlocks happen
- pop data from an empty channel
- push data to a full channel
- try to lock a locked file while the existing lock never gets released
- acquire a locked lock from another coroutine
- improperly shutdown or reload a server
- When the only coroutine yields its execution. The examples are shown in the next section when we talk about
How to detect/handle deadlocks.
- how to detect/handle deadlocks. In the following examples, we trigger deadlocks by yielding the execution of the only coroutine in the program.
- how deadlocks happen
- advanced topics
- CPU-intensive job scheduling: how coroutines behave when nothing yields voluntarily.
- block coroutines/processes: what "blocking" really blocks — a single coroutine, or the whole process.
- unit tests
- from blocking I/O to non-blocking I/O
- server-side programming
- application servers: one server per protocol.
- HTTP/1 server: support gzip compression, serving static content, customizing status code, etc.
- HTTP/2 server
- HTTP/1 SSE server: stream responses chunk by chunk over HTTP/1.1 using Server-Sent Events, the mechanism behind ChatGPT-style text streaming.
- HTTP/2 server push
- WebSocket server
- TCP server
- UDP server
- Redis server: a server speaking the Redis protocol, usable from any Redis client.
- MQTT broker: a minimal MQTT broker built on the open_mqtt_protocol setting, supporting a basic publish/subscribe round trip with the Mosquitto command-line clients.
- reverse-proxy server: a TCP-level reverse proxy relaying each connection to an upstream server.
- multiple ports listening: one server listening on multiple ports, each port with its own set of callbacks.
- integrated servers: multiple protocols/features combined in a single server.
- integrated HTTP/1 server: an HTTP/1 server that supports cron jobs and synchronous/asynchronous tasks.
- integrated WebSocket server: a WebSocket server that supports cron jobs and asynchronous tasks, using separate processes to handle cron jobs and task queues.
- mixed protocols
- server lifecycle and reliability
- How are different server events triggered?
- enable and disable coroutines in a server
- interruptible sleep: let a cronjob inside a web server execute one last time when the server is shutting down.
- network connection detection (dead network detection)
- DDoS protection: How to protect your Swoole-based application server from DDoS attacks.
- resource pooling
- process pool: reusable worker processes managed by class \Swoole\Process\Pool, with different IPC options.
- connection pool: share a bounded set of database/Redis connections among coroutines.
- MySQL connection pool
- PostgreSQL connection pool
- Redis connection pool
- How to implement a customized connection pool? Check package crowdstar/vertica-swoole-adapter for details. This package implements connection pool for HP Vertica databases through ODBC, and it's maintained by me.
- task scheduling and handling
- timer: recurring and one-off timers via class \Swoole\Timer.
- There is a 2nd example included to show how to implement timer using coroutines only.
- To see how to setup cronjobs using the \Swoole\Timer class in an application server, please check integrated HTTP/1 server. For the full spectrum of recurring-job patterns, see the
cronjobssection below.
- timer: recurring and one-off timers via class \Swoole\Timer.
- benchmark
- base mode vs multi-process mode
- advanced topics
- Rock Paper Scissors: implement the hand game Rock Paper Scissors using Swoole — one server coordinating three concurrent players.
- application servers: one server per protocol.
- multiprocessing
- wait and wakeup processes: block one process and wake it up from another, using shared-memory class \Swoole\Atomic.
- process pool
- pool creation and inter-process communication: Please check previous section
resource poolingfor details. - detach processes from a process pool: let a worker escape the pool manager's control to finish a long task at its own pace.
- pool creation and inter-process communication: Please check previous section
- cronjobs: recurring in-process jobs, implemented in six different ways.
- standalone cronjobs: the scheduler is a program of its own, deployed and supervised independently.
- using timers: fixed-rate scheduling via \Swoole\Timer.
- using a coroutine loop: overlap-free scheduling with a plain coroutine sleep.
- using an interruptible sleep: a Channel-based sleep that a shutdown can wake instantly.
- using a standalone process pool: cron as its own supervised deployable, with the schedule sharded across pool workers.
- cronjobs as part of a server: the scheduler runs inside an application server, following the server's lifecycle and sharing its state.
- using a worker-registered timer plus task workers: a \Swoole\Timer guarded to one server worker dispatches scheduled work to blocking-safe task workers.
- using a dedicated user process: an isolated scheduler process attached to a server, with SIGTERM-driven graceful shutdown.
- standalone cronjobs: the scheduler is a program of its own, deployed and supervised independently.
- event listening and handling
- the default exit condition: signal listeners alone do not keep a process running - by default, the process exits before any signal can be handled.
- a customized exit condition: option exit_condition keeps the event loop alive while signal listeners are registered, so a process can stay running just to listen for signals.
- wait for signals inside a coroutine: method \Swoole\Coroutine\System::waitSignal() blocks the calling coroutine until a signal arrives or a timeout expires - no callbacks involved.
- built-in clients provided by Swoole
- HTTP/1 client
- HTTP/2 client: multiplex concurrent requests as streams over a single TCP connection.
- WebSocket client
- TCP client
- UDP client
- miscellaneous topics
- data management in Swoole: globals, persistence, and caching
- APCu caching: APCu caching in Swoole works the same way as in other PHP CLI applications. This example explains it in details.
- share structured data between processes: class \Swoole\Table implements a fixed-schema table built on shared memory, with atomic counter updates across processes.
- atomic counters: shared-memory counters that work across processes.
- UDP multicast: make a UDP server join an IP multicast group and receive datagrams sent to the group address.
- data management in Swoole: globals, persistence, and caching