Swoole Server Configuration

Swoole Server configurations can be set with $server->set once you have created your server with $server = new Swoole\Server.

Starting from v4.5.5, Swoole will perform a configuration check on the options you check, any incorrect values will produce a PHP warning during server startup

List of configurations

The following configuration example is merely just an example, you should go through and check which configuration options you need as the example may not be what you want.


    // Process
    'daemonize' => 1,
    'user' => 'www-data',
    'group' => 'www-data',
    'chroot' => '/data/server/',
    'open_cpu_affinity' => true,
    'cpu_affinity_ignore' => [0, 1],
    'pid_file' => __DIR__.'/server.pid',

    // Server
    'reactor_num' => 8,
    'worker_num' => 2,
    'message_queue_key' => 'mq1',
    'dispatch_mode' => 2,
    'discard_timeout_request' => true,
    'dispatch_func' => 'my_dispatch_function',

    // Worker
    'max_request' => 0,
    'max_request_grace' => $max_request / 2,

    // Task worker
    'task_ipc_mode' => 1,
    'task_max_request' => 100,
    'task_tmpdir' => '/tmp',
    'task_worker_num' => 8,
    'task_enable_coroutine' => true,
    'task_use_object' => true,

    // Logging
    'log_level' => 1,
    'log_file' => '/data/swoole.log',
    'log_rotation' => SWOOLE_LOG_ROTATION_DAILY,
    'log_date_format' => '%Y-%m-%d %H:%M:%S',
    'log_date_with_microseconds' => false,
    'request_slowlog_file' => false,

    // TCP
    'input_buffer_size' => 2097152,
    'buffer_output_size' => 32*1024*1024, // byte in unit
    'tcp_fastopen' => false,
    'max_conn' => 1000,
    'tcp_defer_accept' => 5,
    'open_tcp_keepalive' => true,
    'open_tcp_nodelay' => false,
    'pipe_buffer_size' => 32 * 1024*1024,
    'socket_buffer_size' => 128 * 1024*1024,

    // Kernel
    'backlog' => 512,
    'kernel_socket_send_buffer_size' => 65535,
    'kernel_socket_recv_buffer_size' => 65535,

    // TCP Parser
    'open_eof_check' => true,
    'open_eof_split' => true,
    'package_eof' => '\r\n',
    'open_length_check' => true,
    'package_length_type' => 'N',
    'package_body_offset' => 8,
    'package_length_offset' => 8,
    'package_max_length' => 81920,
    'package_length_func' => 'my_package_length_func',

    // Coroutine
    'enable_coroutine' => true,
    'max_coroutine' => 3000,
    'send_yield' => false,

    // tcp server
    'heartbeat_idle_time' => 600,
    'heartbeat_check_interval' => 60,
    'enable_delay_receive' => true,
    'enable_reuse_port' => true,
    'enable_unsafe_event' => true,

    // Protocol
    'open_http_protocol' => true,
    'open_http2_protocol' => true,
    'open_websocket_protocol' => true,
    'open_mqtt_protocol' => true,

    // SSL
    'ssl_cert_file' => __DIR__ . '/config/ssl.cert',
    'ssl_key_file' => __DIR__ . '/config/ssl.key',
    'ssl_ciphers' => 'ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP',
    'ssl_method' => SWOOLE_SSLv3_CLIENT_METHOD, // removed from v4.5.4
    'ssl_protocols' => 0, // added from v4.5.4
    'ssl_verify_peer' => false,
    'ssl_sni_certs' => [
        "cs.php.net" => [
            'ssl_cert_file' => __DIR__ . "/config/sni_server_cs_cert.pem",
            'ssl_key_file' => __DIR__ . "/config/sni_server_cs_key.pem"
        "uk.php.net" => [
            'ssl_cert_file' => __DIR__ . "/config/sni_server_uk_cert.pem",
            'ssl_key_file' => __DIR__ . "/config/sni_server_uk_key.pem"
        "us.php.net" => [
            'ssl_cert_file' => __DIR__ . "/config/sni_server_us_cert.pem",
            'ssl_key_file' =>  __DIR__ . "/config/sni_server_us_key.pem",

    // Static Files
    'document_root' => __DIR__ . '/public',
    'enable_static_handler' => true,
    'static_handler_locations' => ['/static', '/app/images'],

    // Source File Reloading
    'reload_async' => true,
    'max_wait_time' => 30,

    // HTTP Server
    'http_parse_post' => true,
    'http_parse_cookie' => true,
    'upload_tmp_dir' => '/tmp',

    // Compression
    'http_compression' => true,
    'http_compression_level' => 3, // 1 - 9
    'compression_min_length' => 20,

    // Websocket
    'websocket_compression' => true,
    'open_websocket_close_frame' => false,
    'open_websocket_ping_frame' => false, // added from v4.5.4
    'open_websocket_pong_frame' => false, // added from v4.5.4

    // TCP User Timeout
    'tcp_user_timeout' => 0,

    // DNS Server
    'dns_server' => '',
    'dns_cache_refresh_time' => 60,
    'enable_preemptive_scheduler' => 0,

    'open_fastcgi_protocol' => 0,
    'open_redis_protocol' => 0,

    'stats_file' => './stats_file.txt',

    'enable_object => true,



Daemonize the Swoole Server process.

If the value of daemonize is more than 1, the swoole server will be daemonized. By default this option is turned off.

This option is useful for programs that you need to run for an extended period of time, like a production server. By daemonizing a server, you won't be left with the program running in the console. The server will run the background as a daemon process,

If daemonize has been enabled, the standard output and error of the program will be redirected to what the logfile configuration option is set to, if the configuration of log_file hasn't been set, the standard output and error of the program will be redirected to /dev/null.

After daemonizing the process, the value of the current working directory will change and the relative path of files will be different so you must use the absolute path instead.


Set the operating system user of the worker and task worker child processes. The default is set to the user who executes the script.

If the user is trying to start a service which uses a port within the root port range, which is anything below 1024, the script will have to be executed with root privileges.


$server->set(['user' => 'www-data']);

Don't use root here, it is better to use sudo to start the script.


Set the group of the worker and task worker child processes.The default is set to the user who executes the script.

This configuration option is similar to the user option where it allows you to change how each worker or task worker operates as, in this case the group which the process runs under.


    'group' => 'www-data'

Don't use root here, it is better to use sudo to start the script.


Redirect the root path of the worker processes.

This configuration is to separate the operation to the file system in the worker process from the rest of the servers file system. Locking out the worker process to one area of the file system, used to improve security so that the process only has access to the area of the file system it needs access to.


    'chroot' => '/data/server/'


Set the CPU affinity for reactor and worker threads/processes. This option is disabled by default and is for hardware which runs multi-core CPUs.

By enabling open_cpu_affinity, the reactor/worker processes are bound to a CPU core to increase CPU cache hit rate, sometimes known as CPU pinning or cache affinity. CPU affinity allows Swoole to bind and unbind threads to a fixed CPU core or a range of CPU cores, this kind of behavior is good because it forces the thread/process to only execute on the same CPU core(s) rather than any CPU, which, improves performance due to the process staying on the same CPU core(s), making it quicker to access the same state and cache memory, a thread/process does not incur a performance hit of switching between cores.

How to check if the process is bound with a CPU core?

taskset -p PID

pid 24666\'s current affinity mask: f
pid 24901\'s current affinity mask: 8

Check more about CPU affinity and taskset.


By default, all the I/O interrupts are processed by CPU 0 (first core).

Set the CPU core(s) number which are only used to handle the I/O interrupts.

By default all IO intensive network interrupts are handled by CPU 0. When network IO becomes too intense and CPU 0 cannot keep up with the traffic, performance will decrease.

However, Swoole (when this option is not set) will use all CPU cores and will set the CPU binding based on the number of rector and worker threads you have, along with the total number of CPU cores available. If the kernel and the network card have multi-queue features, network interrupts will be distributed to multiple cores, which can alleviate the pressure of network interrupts.


    'cpu_affinity_ignore' => [0, 1],

How to check I/O interrupts on CPU cores?

cat /proc/interrupts 

For performance reasons and scale, it is recommended to not set this option because once the CPU cores become exhausted at 100%, network operations will struggle.

You must set open_cpu_affinity in order for this option to take effect at the same time


The file path where the master process ID is saved to. This happens once the server is started and is useful when you daemonize your server, knowing the process ID.

This file is automatically deleted when the server is shutdown.


    'pid_file' => __DIR__ . '/server.pid',

If you are not running a server, the PID file is not automatically deleted if your process is stopped. You could use Swoole\Process:: kill($pid, 0) to kill and detect the outcome


The number of the reactor threads to start. A reactor thread is a process that handles event processing in the main program, allows you to make use of multi-core performance. This option is enabled by default and each reactor can maintain its own event loop and there is no blocking between each event loop, they run in parallel.

You can change the number of I/O threads in the master process.

The default number of reactor_num is the number of CPU cores you have.

You can use swoole_cpu_num() + 2 for example to configure different threads.

One limit is that reactor_num has to be smaller than the worker_num and it is only recommended that you set this number no more than swoole_cpu_num() * 2 so you don't lose performance due to system OS scheduling.

If you set reactor_num higher than the amount of workers (worker_num), Swoole will just reset the reactor_num to equal the amount of workers you have set.


The number of worker processes to start. By default this is set to the number of CPU cores you have.

If your server is running code that is asynchronous and non-blocking, set the worker_num to the value from one to four times of CPU cores. For example, you could use swoole_cpu_num() * 2.

If your server is running code that is synchronous and blocking, set the worker_num to an average of how long a single request takes, so 100ms to 500ms would be a worker_num of somewhere between that range.

The maximum you can reach is swoole_cpu_num() * 1000`. Each new worker will consume more memory and overhead will increase with the switching between processes, so don't set this option too high.

You can look into enabling Coroutine Hooks to support blocking code in most cases, meaning can just stick to using swoole_cpu_num() * 2 or swoole_cpu_num() * 4.


Set the key of the message queue.

This configuration only works if the configuration of task_ipc_mode has been set to 2 or 3.

The default value of message_queue_key is calculated by ftok($php_script_file, 1) which gets a queue key based on the file path an ID of 1.

More information about ftok can be found here.

You can check the data in message queue with command:

ipcs -q 
ipcrm -Q [msgkey]


The mode of dispatching connections to the worker processes.

This parameter only works for the SWOOLE_PROCESS mode is set when running your server.

List of the different dispatch modes (default is 2):

  • 1 Round Robin: Uses the Round Robin algorithm to dispatch connections to workers.
  • 2 Fixed Mode: The Default mode. Dispatches the connection to the worker according to the ID number of connection (file descriptor). In this mode, the data from the same connection will be handled by the same worker process.
  • 3 Preemptive mode: Dispatches connections to only the idle worker processes.
  • 4 IP Allocation: Connections dispatched based on IP. Dispatch the connection to the worker according to the IP of the client. The dispatch algorithm is ip2long(ClientIP) % worker_num. This mode guarantees that the same connection and its data will use the same worker process.
  • 5 UID Allocation: Dispatch based on a user defined ID. If the connection has been bound with a uid by Swoole\Server->bind, Swoole will dispatch the connection to the worker according to the uid. The dispatch algorithm is uid % worker_num. If you want to use a string as a uid, it should convert this string by crc32($uid).
  • 7 Stream Mode: use the idle worker process to accept and process the incoming requests.
  • 8 Lowest Coroutine Number Mode On Connect: Dispatches to the process with lowest total coroutines number when the connection is established.
  • 9 Lowest Coroutine Number Mode On Request: Dispatches to the process with lowest total coroutines number for each request.

Usage advice

  • Stateless Server: 3 is advised for synchronous and blocking server as a worker can only accept a new connection once a worker is free/idle again, or 1 is advised for asynchronous and non-blocking server because round robin offers a starvation free execution of processes.

  • Stateful Server: You should use 2, 4 or 5. This is because the server will make the most of performance due to executing workers in a asynchronous manner, there is no waiting between processes. These modes are not preemptive so it won't block the workers for new incoming requests but the application has to be programmed around a stateful design. Workers will be shared between requests.

You cannot use dispatch_mode when you are running a server as SWOOLE_BASE because there is no delivery of connections, just a range of identical processes that handle a request. Once the server receives a request, the processing and data is returned from the same thread.

If the dispatch_mode is 1 or 3, the event of connect and close will not be triggered/used because in those modes, the return order cannot be guaranteed.


Discard incoming data requests when a connection is closed. Enabled by default.

If the configuration of dispatch_mode is 1 or 3, there may be some data that arrive to the worker process after closing the connection, this is because in these modes, Swoole cannot guarantee the return order.

In this situation, if discard_timeout_request is true, the worker process will discard any data or still process this data.


Use dispatch_func to set a user defined dispatch function which handles dispatching the connections to the worker processes.

This option is mainly for advanced usage where you require a different method to dispatch connections to processes or workers, if the 5 provided dispatch modes don't fulfil your needs, this is the best way for you to define your own dispatch behavior.

You can write C++ or PHP functions to set a custom dispatch strategy/algorithm. If you define a function, the dispatch_mode will be ignored and your function will be used instead. A fatal error will be thrown if the function cannot be found.


    'dispatch_func' => 'my_dispatch_function',

If the data dispatched is more than 8K, dispatch_func can only get 0-8180 bytes data.

PHP function

It is forbidden to add any blocking operations in the dispatch_func otherwise the Reactor group will be blocked and halt, because ZendVM does not support multi-threaded environments, the dispatch function can only be executed once, even if you set multiple reactor threads. Therefore, you must not perform anything which would block the event loop as PHP will acquire a lock when calling the function which will result in rector threads being blocked.

An example of setting up a PHP function to dispatch connections:

    'dispatch_func' => function($server, $fd, $type, $data) 
        var_dump($fd, $type, $data);
        return intval($data[0]);


  • $fd, the ID number of the connected client, use Server::getClientInfo to get client information

  • $type, the type of data and its current state:

    • 0: received data from the client, connection is established
    • 4: the connection with the client closes
    • 5: the connection with the client starts
  • $data, the data to dispatch from the request/connection with a maximum of 8K


The return must be an integer between 0 and total number of worker_nums. Data will be discarded if the return does not match a worker number.

C++ function

If you are writing another PHP extension, use swoole_add_function to register the function with Swoole, this makes your function available to use as a dispatch function:

C++ Dispatch Function Example

int dispatch_function(swServer *serv, swConnection *conn, swEventData *data);

int dispatch_function(swServer *serv, swConnection *conn, swEventData *data)
    printf("cpp, type=%d, size=%d\n", data->info.type, data->info.len);
    return data->info.len % server->worker_num;

int register_dispatch_function(swModule *module)
    swoole_add_function("my_dispatch_function", (void *) dispatch_function);

The C++ version follows the same rules as the PHP function example. The return must match a worker number, you can discard data by passing -1. If the connection is using UDP, the conn is set to null.

Only use dispatch_func when you are NOT using SWOOLE_BASE as there is no delivery strategy to work out, connections are passed to threads where they are processed until returned, it does not use the master to worker structure


A worker process is restarted to avoid memory leak when receiving max_request + rand(0, max_request_grace) requests.

The default value of max_request_grace is (max_request / 2);

The default value of max_request is 0 which means there is no limit of the max request. If the max_request is set to some number, the worker process will exit and release all the memory and resource occupied by this process after receiving the max_request request. And then, the manager will respawn a new worker process to replace it.

This parameter is to resolve the problem of nonlocalizable and slow memory leaks.

You should only set max_request for synchronous, blocking and stateless response servers. For asynchronous applications, this should be set to 0. A asynchronous server should not set max_request because the application itself should not introduce memory leaks, they should be fixed if ever found. When set to 0, the worker processes will not exit.

You can only use max_request when in SWOOLE_PROCESS mode because SWOOLE_BASE does not use the master to worker structure.

$server = new swoole_server("", 9501);

    'worker_num' =>   2,    
    'max_request' =>  3,  
    'dispatch_mode'=> 3,

$server->on('receive', function ($server, $fd, $from_id, $data) {
    $server->send($fd, "Server: ".$data);


You may need to check the PID of the worker process before a request and after many requests because it may change from being respawned.

Once a server reaches max_request, it does not necessarily stop the process right away, you should refer to max_wait_time to understand more.

If a worker experiences a fatal error or an exit event, the process will automatically exit and the master process will create a new replacement worker in order to complete the request.


The default value of max_request_grace is (max_request / 2);

A worker process is restarted to avoid memory leak when receiving and the condition of max_request + rand(0, max_request_grace) is met.

You can disable the rand function by setting max_request_grace = 0. Refer to max_request to see how this option works together.


Set the communication mode between the task worker and worker processes.

  • 1, default mode, use UNIX socket to communicate, supports directional delivery through the task and taskwait methods
  • 2, use the message queue to communicate (sysvmsg)
  • 3, use the message queue to communicate (sysvmsg) and set the mode to competition

The difference between mode 2 and 3 is mode 2 supports the feature of sending a task to a specified task worker process by $server->task($data, $task_worker_id) while mode 3 does not support to specify task worker process, instead the tasks will compete for the queue in mode 2 and 3.

The message queue uses the memory queue provided by the OS to store the data.

If the configuration message_queue_key hasn't been set, the message queue would use the private queue and this private queue will be deleted after the close of Swoole server and when message_queue_key has been set, the data of message queue would not be deleted and the Swoole server could get the data after a restart.

You can use ipcrm -q message_queue_id to delete the data of message queue.


After handling the number of task_max_request tasks, the task worker process will exit and release all the memory and resource used by this process. And then, the manager will respawn a new task worker process.

The default value of task_max_request is 0 which means there is no limit of the max task request. This option is used to prevent PHP memory leaks but you should find and fix any memory leaks instead. A task worker will only exit once it has finished processing its current task.

For a asynchronous server, this option should be set to 0 to indicate there is not limit, memory leaks should instead be fixed.


Set the path of temporary task data.

If size of a task message exceeds 8192 bytes, Swoole uses a temporary file to store the data.

The default of task_tmpdir is /tmp. If the directory does not already exist, Swoole will try to create it. The server will fail to start if it cannot create the directory.


Set the number of task worker processes to create.

To make use of task workers , you need to register the callback functions of the task events and finish events within your server, see task or task finish.

A task worker process is synchronous and blocking.

In relation to the performance you need and your operational requirements, you should set a reasonable value for task_worker_num and it should not exceed swoole_cpu_num() * 1000. You can calculate the number of tasks you need by benchmarking how long a normal task takes to complete in milliseconds.


Enable coroutine support inside a task worker process.

By default this option is false and is supported from v4.2.12.

When using the onTask event callback to start a task off, with this option enabled you can use coroutines or have support for coroutine functionality.

If you enable this, a coroutine context is automatically created for you during the call to the onTask event callback.

For Example:

$server->on('Task', function ($serv, Swoole\Server\Task $task) {

    // Identify the current task worker being used to execute this task

    // The task ID or task number

    // The type of task, taskwait, task, taskCo or taskWaitMulti use different flags

    // The data that has been passed to the task process

    // The delivery time

    // Making use of the Coroutine System API within a task

    // Complete the task and indicate that we have finished, returning the data
    $task->finish([123, 'hello']);

If you don't enable coroutine support within a task worker, they execute tasks in a synchronous blocking mode.


Use object-oriented style callback to pass task data. Default value is false.



$server = new Swoole\Server('', 9501);

    'worker_num'      => 1,
    'task_worker_num' => 3,
    'task_use_object' => true,
    // 'task_object' => true, // v4.6.0, another alias

$server->on('receive', function (Swoole\Server $server, $fd, $tid, $data) {
    $server->task(['fd' => $fd,]);

$server->on('Task', function (Swoole\Server $server, Swoole\Server\Task $task) {

    // Here $task is the Swoole\Server\Task object
    $server->send($task->data['fd'], json_encode($server->stats()));


Instead of the data being passed as a string, it is passed as an object when this option is enabled, set to true.


Set the level of the log that is kept by the server.

If an incorrect log level is set, a log will not be recorded and no error will be thrown.

The default value is set to SWOOLE_LOG_INFO.


    'log_level' => 2,

Log level list

0 => DEBUG // all the levels of log will be recorded
1 => TRACE
2 => INFO
5 => ERROR

To use SWOOLE_LOG_DEBUG you need to enable --enable-debug-log during compilation, same goes for if you want to use SWOOLE_LOG_TRACE, you must enable --enable-trace-log during install.


Set the log path of Swoole Server.

If you are not using the log file, all error or debug output will be printed to the screen by default. If you are using daemonize => true then this log file will be used to record output. Even if you perform echo, var_dump or print it will be redirected to the log file.


In the log file, there are some labels to distinguish the thread or process that output the log item.

  • # Master process

  • $ Manager process

  • * Worker process

  • ^ Task worker process

These symbols are placed before the process ID.

Reopen the log file

If the log file has been mv or unlink, the log can't be recorded normally. In this situation, you can send SIGRTMIN to let the server know to create another log file.


If you are using the log file and have setup your other log file settings, you can allow the Swoole server to rotate the log file to stop it getting too big.

The default is SWOOLE_LOG_ROTATION_SINGLE, log rotation is not enabled.

A list of other log rotation settings:

  • SWOOLE_LOG_ROTATION_MONTHLY: rotate per month
  • SWOOLE_LOG_ROTATION_DAILY: rotate per day
  • SWOOLE_LOG_ROTATION_HOURLY: rotate per hour


Set the server log time format in relation to the PHP function strftime.


    'log_date_format' => '%Y-%m-%d %H:%M:%S',


Set whether the server shall output logs using microsecond precision. Default is false.


Enable slow log and set the location of log file. Default is false.

IMPORTANT: This option is only meant to be used with synchronous and blocking servers, do not use this option within a coroutine environment.

If you enable this, the manager process wil set a clock signal and detect when the Task or worker processes are blocking requests and if they are, only then will the log file be written to, after the timeout has been reached (see example).


  'request_slowlog_file' => '/tmp/swoole_slowlog.log',
  'request_slowlog_timeout' => 2,
  'trace_event_worker' => true,

The log file must be writable, otherwise a fatal error will be thrown.


Configure the memory size of the server receive input buffer. Default value is 2M.


Set the output memory buffer server send size.

The default value is 2M. The data to send can't be larger than buffer_output_size.

In relation to, data must not exceed the byte size you set:

  • Server->send
  • Http\Server->end/write
  • WebSocket\Server->push

Be careful when setting a value, you don't want to set this buffer too high because it will lead to large memory consumption. Consider that for each worker you will have worker_num * buffer_output_size.

This option is also only for when you are using SWOOLE_PROCESS mode, as this is the only mode where the server has a relationship with a worker thread, each worker will have its own buffer.

Also known as output_buffer_size.


    'buffer_output_size' => 32 * 1024*1024, // value in bytes


By enabling tcp_fastopen, data is sent with SYNC, enabling TCP fast handshakes. The default is false.

This option can improve TCP response speed of the short connection, the third step to complete the handshake at the client, transmitting SYN packets to carry the data packets. It uses a TFO cookie to authenticate itself and speed up the connections between two endpoints, so when a client later connects, a lot of the authentication has already been done, lowering latency because the server can send back data without completing the round trip three-way handshake.

Check more about tcp_fastopen.


The max number of TCP connections the Swoole server should handle at any given time.

After exceeding this limit, the Swoole server will refuse any new incoming connections.

Some things to consider when using this option:

  • The default value of max_conn is ulimit -n

  • The value of max_conn should be less than ulimit -n on Linux

  • The value of max_conn should be more than (server->worker_num + SwooleG.task_worker_num) * 2 + 32

  • The value of max_conn should not be too large and be set according to the memory usage of server.


This configuration is set to defer the TCP connection to trigger onReceive events before receiving data. Default is false.

This option takes an integer value to indicate how long a TCP connection should be deferred before being accepted and when the onReceive, onConnect and accept events are triggered.

    'tcp_defer_accept' => 5 // Seconds
  • If the client sends data within 5 seconds, then accept/onConnect/onReceive are triggered
  • If the client does not send data within 5 seconds, then only accept/onConnect is triggered


The TCP Protocol has a feature called Keep-Alive and is used for detecting dead connections, when setting this option to true you can configure the Swoole server is send messages between the client and server to check that the link between them is still operating and not dead. The purpose of Keep-Alive is to check the health of a connection, emitting a periodic check to test if the connection is still alive, useful for clearing out old connections .


When enabling TCP Keep-Alive, it comes with some extra options that you need to consider:

    'worker_num' => 1,
    'open_tcp_keepalive' => true, // Enable TCP Keep-Alive check
    'tcp_keepidle' => 4,       // Check if there is no data for 4s.
    'tcp_keepinterval' => 1,   // Check if there is data every 1s
    'tcp_keepcount' => 5,      // Close the connection if there is no data for 5 cycles.
  • 'open_tcp_keepalive': Enables TCP keep alive checks
  • 'tcp_keepidle': In seconds, the time a connection needs to remain idle before TCP starts sending keep alive probes
  • 'tcp_keepinterval': In seconds, the time between individual keep alive probes/checks
  • 'tcp_keepcount': The maximum number of keep alive probes/checks to send before dropping the connection, classing it as dead or broken


Set this configuration to true to use the Nagle merge algorithm. Default is false.

This option attempts to improve the efficiency of TCP/IP by reducing the number of packets that need to be sent.

More information about the Nagle Algorithm.


Set the buffer size (in bytes) of the pipe, defines the maximum number of bytes that can be written to the pipe buffer.

The pipe is used for I/O operations within the Swoole Server, specifically the communication between workers and the master process.

Only effective when using SWOOLE_PROCESS mode.

More information about Pipes.


    'pipe_buffer_size' => 32 * 1024 *1024,


Set the maximum buffer size (in bytes) of the socket connection for clients.

This configuration is to set the maximum memory size of the connection.

Unlike buffer_output_size, a worker process sends/creates the size limits, the size of the socket buffer is provided to Worker and Master processes, only effective when using SWOOLE_PROCESS mode.


    'socket_buffer_size' => 128 * 1024 *1024,

Above, 128 * 1024 * 1024 means that each TCP client connection allows a maximum of 128M data to be sent.

When the Master process sends a large amount of data to the client, it cannot be sent immediately, the data sent in this situation will be stored in the memory buffer area on the server side. The socket_buffer_size parameter can be adjusted to set the size of the memory buffer area.

If you send too much data, the data fills the cache and the server will report the following error message:

swFactoryProcess_finish: send failed, session#1 output buffer has been overflowed.

Any socket buffer that gets filled will only affect the current client, not other TCP connections but what will affect other clients is when server->max_connection * socket_buffer_size causes the system to exhaust all the memory. It may be useful to save data to disk before the buffer and wait for the client to accept, that way you won't fill up the buffer too quickly when dealing with large amounts of data.


Allow a number of waiting connections.

This configuration is an integer representing the number of pending connections that wait for the server to accept them.

The backlog is used for when max_conn is reached, the backlog is the maximum number of connections to queue before rejecting them.


Sets the maximum buffer size (in bytes) of the kernel send socket.


Sets the maximum buffer size (in bytes) of the kernel receive socket.


This configuration is to check the package EOF (End of File). The package EOF is set by the configuration package_eof.

Default for this option is false.

Data is read until either the buffer area is exceeded or the timeout is breached. When an error happens, Swoole will discard the connection and data as a malicious attack. Most applications like Memcache, SMTP and POP use and agree to \r\n as the EOF but you can change it, just make sure worker processes are receiving data correctly.


If this configuration has been enabled, Swoole will check the end of data from the client. If the end of data from the client is the string set by package_eof, Swoole will send the data to the worker process otherwise Swoole will continue to receive and joint data from the client until the set package_eof is found.

    'open_eof_check' => true,
    'package_eof' => "\r\n", 

The above configuration example can be used for Memcache or POP protocol which ends by \r\n. Once set, the worker process will receive one or several data packets. Within a worker process, you should use explode("\r\n", $data) to split the data or set the configuration package_eof to split the data automatically, see open_eof_split. This is because a worker may receive multiple data packets but you are required to dismantle sub-packets sent to the worker processes.


Enable automatic EOF (End of File) data packet splitting.

Once the configuration of open_eof_check has been set, the worker processes will receive the data ending with the specified string. This data may contain one or serval data packets. In this situation, you can enable the open_eof_split to split the data to split the data packets automatically. And then the callback function onReceive will receive a data packet instead of your application layer having to use explode("\r\n", $data) to split sub-packets up.


    'open_eof_check' => true,
    'open_eof_split' => true,
    'package_eof' => "\r\n", 


Set the end string (End of File) for incoming data.

This configuration requires that open_eof_check be enabled.

The max length of this string is 8 bytes. You should also consider using open_eof_split.


Enable the check of packet length. Default is false.

If this configuration is enabled, Swoole will analyse data packets and format the packet header and body ensuring the worker processes will receive all the data as a whole in the callback function onReceive.

Internally, this option will only need to detect the length of the data packet once, achieving this by offsetting a pointer, so performance is very good and is recommended.

This configuration works with three other configurations:

  • package_length_type

Use a certain field in the header of the data packet to stand for the length of the packet. Swoole supports 10 types of length. Check the full list in the configuration of package_length_type.

  • package_body_offset

Allows you to set the body offset in order to calculate the complete length of the data packet. See the package_body_offset for more information.

  • package_length_offset

You can set the offset before calculating the data packet size in bytes. See the section package_length_offset for more details.


The type of length accepted as a character to indicate which field in the packet header is used, Swoole currently supports 10 different types:

  • c: Signed, 1 byte
  • C: Unsigned, 1 byte
  • s: Signed, host byte order, 2 bytes
  • S: Unsigned, host byte order, 2 bytes
  • n: Unsigned, network byte order, 2 bytes
  • N: Unsigned, network byte order, 4 bytes
  • l: Signed, host byte order, 4 bytes (lowercase L)
  • L: Unsigned, host byte order, 4 bytes (uppercase L)
  • v: Unsigned, little endian, 2 bytes
  • V: Unsigned, little endian, 4 bytes


The offset of the package to calculate the length of the data packet:

  • 0, the length stands for the length of header and body
  • N, this value stands for that the length of the header is N and the length of a package only contains the length of the body.


The offset of the value of length in the header


    uint32_t type;
    uint32_t uid;
    uint32_t length;
    uint32_t serid;
    char body[0];

The configuration from the protocol design:

    'open_length_check' => true,
    'package_max_length' => 81920,
    'package_length_type' => 'N',
    'package_length_offset' => 8,
    'package_body_offset' => 16,


The max length of a package in bytes. Default value is 2 * 1024 * 1024, minimum value is 64K.

Once the configuration for open_length_check, open_eof_check, open_http_protocol, open_http2_protocol, open_websocket_protocol and open_mqtt_protocol have been enabled, Swoole will join the data received from the client and the data in the memory before receiving the whole data packet. So to limit the usage of memory, you should set the value of package_max_length, this then indicates the maximum size allowed for a data packet.

For example, if there are 10,000 TCP connections to send data, each data packet is around 2M, then in the most extreme cases, it will take up 20G of memory.

This configuration also controls the maximum file size that can be uploaded.


  • When using open_length_check and package_max_length, if the packet length is found to exceed package_max_length, the data will be directly discarded, and the connection will be closed without occupying any memory

  • If open_eof_check is enabled and because the length of the data packet cannot be known in advance, the received data will still be stored in the memory and continue to grow. When the memory usage exceeds package_max_length, the data is discarded directly, and close the connection

  • If open_http_protocol is used, the maximum GET data allowed is 8K, and the configuration cannot be modified. POST requests Will detect a request size using Content-Length, if Content-Length exceeds package_max_length, data is discarded and the Swoole server will emit transmission HTTP 400 errors, and close the connection

Make sure to consider how much memory is available when using this setting.


Define a function to check the length of a incoming data packet. Swoole supports the use of a PHP function and a C++ function.

The function must return an integer.

  • 0, lack of data to join a data packet, insufficient data length has been detected

  • -1, error detected with the data, Swoole will close the connection

  • The total length of the data packet if there are no errors

PHP function example

$server = new Swoole\Server("", 9501);

    'open_length_check' => true,
    'dispatch_mode' => 1,
    'package_length_func' => function ($data) {
        if (strlen($data) < 8) {
            return 0;
        $length = intval(trim(substr($data, 0, 8)));
        if ($length <= 0) {
            return -1;

        return $length + 8;
    'package_max_length' => 32 * 1024*1024,

$server->on('receive', function (Swoole\Server $serv, $fd, $from_id, $data){
    echo "#{$server->worker_id}>> received length=" . strlen($data) . "\n";


You must not execute any code that will block or hang up the server, PHP does not support multi-threaded environments so any blocking operations will not work within this function.

C++ function example

Just like the PHP example, it follows the same rules with what needs to be returned. Within the PHP extension where your function may be defined, you can register it with Swoole and make it available by using swoole_add_function.

One major benefit of using a C++ function is Swoole or PHP will not be blocking by IO operations in this function, however, you are responsible to ensure thread safety.

#include <string>
#include <iostream>
#include "swoole.h"

using namespace std;

int test_get_length(swProtocol *protocol, swConnection *conn, char *data, uint32_t length);

void register_length_function(void)
    swoole_add_function((char *) "test_get_length", (void *) test_get_length);
    return SW_OK;

int test_get_length(swProtocol *protocol, swConnection *conn, char *data, uint32_t length)
    printf("cpp, size=%d\n", length);
    return 100;


Enable or disable coroutine support in the callback functions and with the Swoole server. The default is true.

It is highly encouraged that you make use of coroutines because they improve performance massively when running code concurrency, not all application logic will support coroutines, either you have to enable coroutine hooks or rewrite application logic to support a coroutine enabled environment.

You are able to set this option within the php.ini file under swoole.enable_coroutine = 'On|Off'. The INI file takes higher priority than:

    'enable_coroutine' => true,

When coroutines are enabled, Swoole will automatically create a coroutine context for you upon the call to any event callback, there is then no need to run the initial call to Co\run to create a coroutine context, Swoole will do this for you. You can use go() straight away.

Callback Events Affected

  • onWorkerStart
  • onConnect
  • onOpen
  • onReceive
  • setHandler
  • onPacket
  • onRequest
  • onMessage
  • onPipeMessage
  • onFinish
  • onClose
  • tick/after timer functions

Coroutines are what enable a Swoole server to run concurrently and execute code when the server is waiting for a response from some IO operation and not waste any time the server request has.


Set the maximum number of coroutines per worker process. Default is 100000.

If this limit is exceeded, Swoole will not be able to create a new coroutine context, an error will be thrown and the TCP connection will be closed, a HTTP server will return an error of 503.

An exceeded error is exceed max number of coroutine.

A good range is something like worker_num * max_coroutine.


Yield the current task and wait for I/O if the send buffer is full.

When data is being transmitted, the memory buffer can become full which means some IO operations can become stuck or blocked because they are waiting for the buffer to become clear again. Because of this situation, when this option is set to true, a coroutine will yield (suspend) and let other coroutines do some work so time and resources are not wasted. Once the buffer memory becomes available again, the coroutine will resume.

If this option is not enabled, Server/Client->send will return false and SW_ERROR_OUTPUT_BUFFER_OVERFLOW will be thrown to indicate a buffer overflow.

The following code will cause a buffer overflow if send_yield is disabled:

for ($i = 0; $i < 100; $i++) {
    $server->send($fd, $data_2m);

When the buffer area is full, it will directly return false and report an error output buffer overflow when send_yield is disabled.

And when send_yield is enabled and the buffer area is full, the current coroutine will be yielded, and will resume to continue execution after the transmission is completed with the memory buffer.

Functions Affected

  • Swoole\Server::send
  • Swoole\Http\Response::write
  • Swoole\WebSocket\Server::push
  • Swoole\Coroutine\Client::send
  • Swoole\Coroutine\Http\Client::push

This option will change the underlying default behavior of how coroutines work


This configuration which works with heartbeat_check_interval defines the max idle time of a connection.

This option does not send packets to the client, it expects the client to keep the connection alive. If heartbeat_idle_time is set but not heartbeat_check_interval, then the heartbeat check will not run, you would then have to check yourself.


    'heartbeat_idle_time' => 600,
    'heartbeat_check_interval' => 60,
  • heartbeat_idle_time: Indicates that the connection has not sent any data to the server within 600 seconds, so the connection will be closed

  • heartbeat_check_interval: The interval between how long to wait before checking idle connections again


This configuration is the interval of when to poll every TCP connection to see if it is idle. Default value is false, set in seconds.

If the connection hasn't sent any data to the server in the last interval of heartbeat_check_interval, the connection will be closed, this option works with heartbeat_idle_time which decides if a connection is idle or not.

The Swoole server does not send the heartbeat packet to the client, it waits for the heartbeat packet from the client. The heartbeat check thatis done by the Swoole server only checks the last time data has been received from the client. If the time exceeds heartbeat_idle_time, the connection between the server and the client will be closed.

When a connection is closed due to breaching a heartbeat check, it will trigger the call to onClose.

This is only for a TCP Swoole server.


Enable the delay of receiving a new connection. Default is false.

Once enabled, the client which has been accepted would not be added to the EventLoop automatically and only trigger the callback function of the received event.

The worker process needs to call $server->confirm($fd) to confirm the connection manually and add the connection to the EventLoop.


// enable `enable_delay_receive`
    'enable_delay_receive' => true,

// Process the connection before adding to the event loop
$server->on("Connect", function ($server, $fd, $reactorId) {
    $server->after(2000, function() use ($server, $fd) {

        // ...

        // Confirm the connection and add the connection to the event loop

You can also call $server->close($fd) to reject/close the connection. Once a connection has been confirmed, it will be added to the event loop then the server can start receiving data.


Enable the reuse of port. Default value is false.

When this option is enabled you can reuse the same port that the server is listening on, meaning it is not bound and restricted to one server/process.


Enables certain event callbacks when in dispatch_mode 1 or 3 that are usually disabled. Default is false.

When Swoole is configured to use dispatch_mode 1 or 3, the return order of onConnect, onReceive and onClose cannot be guaranteed and if some applications can risk the return order or handle such risky events, you may turn this behavior off which will then enable both onConnect and onClose events.


Enable the HTTP protocol. Default is false if not using a Swoole HTTP Server already.

Once this configuration has enabled, the callback function onReceive will receive a whole HTTP data packet.

If you are already using a Swoole HTTP Server, it will enable this configuration automatically.


    'open_http_protocol' => true


Enable support for using the HTTP2 server protocol.

This configuration needs to be compiled at install with --enable-http2.


    'open_http2_protocol' => true


Enable support for the WebSocket protocol. Default is false unless you are already using a Swoole WebSocket server.

Swoole enables this configuration open_http_protocol automatically if the configuration open_websocket_protocol has been enabled.

If you are running a Swoole WebSocket Server already, it will enable this configuration automatically.


    'open_websocket_protocol' => true


Enable support for using the Queuing MQTT protocol. Default is false.

Once this configuration has enabled, Swoole will analyse the MQTT package header and the callback function onReceive will receive a whole MQTT package.


    'open_mqtt_protocol' => true

ssl_cert_file and ssl_key_file

With Swoole servers, you can setup SSL tunnel encryption.

You must add --enable-openssl to enable support for SSL when you compile/install Swoole.

To enable SSL, set the file path of the cert file and the key file:


// Starting a new Swoole server with SSL support
$server = new Swoole\Server("", 9501, SWOOLE_PROCESS, SWOOLE_SOCK_TCP | SWOOLE_SSL);

    'ssl_cert_file' => __DIR__ . '/config/ssl.cert',
    'ssl_key_file' => __DIR__ . '/config/ssl.key',
  • The web browser must trust the credential before browsing the webpage
  • In the WebSocket application, the client starting the connection with the WebSocket must use HTTPS
  • The certificate extensions must be PEM and not DER

Convert PEM to DER:

openssl x509 -in cert.crt -outform der -out cert.der

Convert DER to PEM:

openssl x509 -in cert.crt -inform der -outform pem -out cert.pem


Set the ssl_ciphers to change the default encryption algorithm of OpenSSL. The default encryption algorithm of OpenSSL is EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH


    'ssl_ciphers' => 'ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP',

Swoole will use the default algorithm when ssl_ciphers is empty.

More information about different ciphers can be found here.


This option has been removed since v4.5.4, please use use ssl_protocols instead.

Set the algorithm used by SSL. The algorithm of the client and server must be same otherwise the handshake of a WebSocket connection will fail.

The default algorithm is SWOOLE_SSLv23_METHOD.

    'ssl_method' => SWOOLE_SSLv3_CLIENT_METHOD,

Supported Methods:



This option was added since v4.5.4

Define which SSL protocols that can be used for OpenSSL tunnel encryption. By default, all protocols are enabled.

Supported Protocols:


Usage and SSL Protocols


// Start a Swoole server and enable SSL
$serv = new Swoole\Server('', 9501, SWOOLE_PROCESS, SWOOLE_SOCK_TCP | SWOOLE_SSL);

    'ssl_cert_file' => __DIR__.'/config/ssl.crt',
    'ssl_key_file' => __DIR__.'/config/ssl.key',
    'ssl_verify_peer' => true,
    'ssl_allow_self_signed' => true,
    'ssl_client_cert_file' => __DIR__ . '/config/client.crt',
    'ssl_protocols' => SWOOLE_SSL_TLSv1_2 | SWOOLE_SSL_TLSv1_3 | SWOOLE_SSL_TLSv1_1 | SWOOLE_SSL_SSLv2,


Verify the SSL certificate from client side before establishing the connection. Default value is false.

If you enable this option, you must also use ssl_client_cert_file.



// Start a Swoole server and enable SSL
$serv = new Swoole\Server('', 9501, SWOOLE_PROCESS, SWOOLE_SOCK_TCP | SWOOLE_SSL);

    'ssl_cert_file' => __DIR__.'/config/ssl.crt',
    'ssl_key_file' => __DIR__.'/config/ssl.key',
    'ssl_verify_peer' => true,
    'ssl_allow_self_signed' => true,
    'ssl_client_cert_file' => __DIR__ . '/config/client.crt',


Server Name Indication (SNI) allows the server to safely host multiple TLS Certificates for multiple sites, all under a single IP address.

You can set multiple SSL certificate for different domains. Server Name Indication is widely supported by browsers and many devices.


    'ssl_cert_file' => __DIR__ . '/server.crt',
    'ssl_key_file' => __DIR__ . '/server.key',
    'ssl_protocols' => SWOOLE_SSL_TLSv1_2 | SWOOLE_SSL_TLSv1_3 | SWOOLE_SSL_TLSv1_1 | SWOOLE_SSL_SSLv2,
    'ssl_sni_certs' => [
        'cs.php.net' => [
            'ssl_cert_file' => __DIR__ . '/sni_server_cs_cert.pem',
            'ssl_key_file' => __DIR__ . '/sni_server_cs_key.pem',
        'uk.php.net' => [
            'ssl_cert_file' =>  __DIR__ . '/sni_server_uk_cert.pem',
            'ssl_key_file' => __DIR__ . '/sni_server_uk_key.pem',
        'us.php.net' => [
            'ssl_cert_file' => __DIR__ . '/sni_server_us_cert.pem',
            'ssl_key_file' => __DIR__ . '/sni_server_us_key.pem',

You must set the SSL certificate and key for each domain you list.


Set the Swoole servers document root.


Enable or disable static file handling by the Swoole server, related to the locations set in static_handler_locations.


An array list of directories that are allowed to be served as static files by the Swoole server.


    'static_handler_locations' => ['/static', '/app/images', '/releases'],


A Swoole server runs on the CLI and is stateful, so any files loaded before or after server startup are kept in memory, so any file changes you make won't immediately take effect until you restart the whole Swoole server. This isn't much of a worry in production but during development this can be annoying, so, Swoole offers you a configuration option called reload_async. It is on by default but when enabled it will hot reload file changes for you.

By enabling reload_async, the worker processes shutdown after processing all the pending events/connections and restart to hot reload modified code, saving time during development when making code changes.

This can only be done when you include PHP files after the onWorkerStart event, anything before the Swoole server or the actual Swoole runtime cannot be hot reloaded.

If you want this feature to work please read how to reload file changes with Swoole.

If you enable coroutines, this option is always true because it ensures workers and coroutines can finish their tasks normally before restarting


The maximum waiting time before restarting a worker process. Default 3 seconds.

This option directly relates to reload_async and when it is enabled.

Because worker processes will have to finish processing before they restart, they may become stuck or be waiting too long, so a timeout option value can be set to force a worker to restart if it exceeds the defined timeout.

The manager process will receive the restart request because of code/file changes that need to be reloaded or a shutdown request then, the manager process will begin to restart workers.

The process of restarting workers:

  • Swoole will wait and respect the set value of max_wait_time in seconds, after it is reached, checks are done to see if the process still exists and if it does, it will be force killed and another process started
  • When a process is killed, the onWorkerStop event callback is called


Enable or disable POST body parsing, when a POST request is received, Swoole will parse the data if this is enabled. If you are using the Swoole HTTP Server, this is enabled by default.

Enable or disable HTTP Cookie parsing. If you are using the Swoole HTTP Server, this is enabled by default.


Set the temp directory to save uploaded files to. Default is /tmp.


Enable or disable compression for HTTP responses.

When enabled, you can set the http_compression_level.


Set the HTTP compression level to be 1 - 9.

There are three types of compression supported: gzip, br, deflate and used based on the Accept-Encoding HTTP header from HTTP request.

For gzip and deflate requires zlib. You have to install it before installing Swoole:

sudo apt-get install libz-dev

And for br requires brotli from Google. You have to install it before installing Swoole:

sudo apt-get install libbrotli-dev


To specify the minimum length of the response to compress, use the compression_min_length directive. The default is 20 bytes.


Enable or disable compression for websocket responses.


This is disabled by default.

Pass the close frame from client to the message callback function:

$server->on('message', function (swoole_websocket_server $server, $frame) 
    if($frame->opcode == 0x08) 
        echo "Close frame received: Code {$frame->code} Reason {$frame->reason}\n";
        echo "Message received: {$frame->data}\n";


Enable or disable the web socket ping frame. Default value is false.

Used at the application layer to keep web socket connections alive.

For information on WebSocket Ping.


Enable or disable the web socket pong frame. Default value is false.

Used at the application layer to keep web socket connections alive.

For information on WebSocket Pong.


This related to sockets and the TCP layer. The value is the maximum length of time that an ACK confirmation is not received after a data packet is sent, in milliseconds. Please check the man document for details.


Set the DNS server that will be used for lookup requests by the Swoole server.


A timeout in seconds for when the DNS cache is cleared/reset. Default value is 60s.


Enable or disable the preemptive scheduler.

Can also be set using ini_set("swoole.enable_preemptive_scheduler", "1").


Enable or disable FastCGI support. Default value is false.

When enabled FastCGI can be used on the TCP server or client, meaning a server can parse data using the FastCGI protocol.


Enable or disable Redis support. Default value is false.

When enabled, a worker process and the onReceive event will be given a complete Redis data packet.


Set a file location for Swoole server to print the stats info to the file once per second.


If this option is enabled, then on the server event callback functions, object style will be used when passing arguments to the callback events instead of individual arguments.

For example, for the server event Receive, when this option is enabled, you will be passed a Swoole\Server\Event instead of individual arguments, you can then use this object to access the same information and data.

By default this option is false. For more examples, see here.

Since v4.6.0