<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: klsoft</title>
    <description>The latest articles on DEV Community by klsoft (@klsoft).</description>
    <link>https://dev.to/klsoft</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4064661%2Fea1f7ceb-2fee-44ba-8710-e142f2a8199d.png</url>
      <title>DEV Community: klsoft</title>
      <link>https://dev.to/klsoft</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/klsoft"/>
    <language>en</language>
    <item>
      <title>Benchmark testing of FrankenPHP vs RoadRunner vs Swoole in Yii 3</title>
      <dc:creator>klsoft</dc:creator>
      <pubDate>Thu, 06 Aug 2026 10:56:07 +0000</pubDate>
      <link>https://dev.to/klsoft/benchmark-testing-of-frankenphp-vs-swoole-in-yii-3-88i</link>
      <guid>https://dev.to/klsoft/benchmark-testing-of-frankenphp-vs-swoole-in-yii-3-88i</guid>
      <description>&lt;p&gt;FrankenPHP, RoadRunner and Swoole all use workers to handle incoming requests much more quickly. Now, let's look at how many requests each web server can process per second.&lt;/p&gt;

&lt;p&gt;Testing environment: 13th Gen Intel® Core™ i7-1355U × 12, 16&amp;nbsp;GB&lt;/p&gt;

&lt;p&gt;Testing tool: &lt;a href="https://github.com/wg/wrk" rel="noopener noreferrer"&gt;wrk&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prepare the FrankenPHP testing application.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clone the &lt;a href="https://github.com/yiisoft/app" rel="noopener noreferrer"&gt;yiisoft/app&lt;/a&gt; repository.&lt;/li&gt;
&lt;li&gt;Add the &lt;a href="https://github.com/yiisoft/yii-runner-frankenphp" rel="noopener noreferrer"&gt;yiisoft/yii-runner-frankenphp&lt;/a&gt; package to the &lt;code&gt;composer.json&lt;/code&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"require"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"yiisoft/yii-runner-frankenphp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^1.0"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;In your application root &lt;a href="https://github.com/yiisoft/yii-runner-frankenphp#general-usage" rel="noopener noreferrer"&gt;create worker.php&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Replace the contents of the &lt;code&gt;docker/dev/Caddyfile&lt;/code&gt; with the following:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="err"&gt;{&lt;/span&gt;
    &lt;span class="err"&gt;skip_install_trust&lt;/span&gt;

    &lt;span class="err"&gt;frankenphp&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
    &lt;span class="err"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;

&lt;span class="err"&gt;{$&lt;/span&gt;&lt;span class="py"&gt;SERVER_NAME&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;:80} {&lt;/span&gt;
    &lt;span class="err"&gt;encode&lt;/span&gt; &lt;span class="err"&gt;zstd&lt;/span&gt; &lt;span class="err"&gt;br&lt;/span&gt; &lt;span class="err"&gt;gzip&lt;/span&gt;
    &lt;span class="err"&gt;php_server&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
        &lt;span class="err"&gt;root&lt;/span&gt; &lt;span class="err"&gt;/app/public&lt;/span&gt;
        &lt;span class="err"&gt;worker&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
            &lt;span class="err"&gt;num&lt;/span&gt; &lt;span class="err"&gt;12&lt;/span&gt; &lt;span class="c"&gt;# number of workers
&lt;/span&gt;            &lt;span class="err"&gt;max_threads&lt;/span&gt; &lt;span class="err"&gt;12&lt;/span&gt; &lt;span class="c"&gt;# number of threads
&lt;/span&gt;            &lt;span class="err"&gt;match&lt;/span&gt; &lt;span class="err"&gt;*&lt;/span&gt;
            &lt;span class="err"&gt;file&lt;/span&gt; &lt;span class="err"&gt;/app/worker.php&lt;/span&gt;
        &lt;span class="err"&gt;}&lt;/span&gt;
    &lt;span class="err"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Replace the contents of the &lt;code&gt;docker/dev/.env&lt;/code&gt; with the following:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;APP_ENV&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;prod&lt;/span&gt;
&lt;span class="py"&gt;APP_DEBUG&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;false&lt;/span&gt;
&lt;span class="py"&gt;SERVER_NAME&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;:80&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Set &lt;code&gt;DEV_PORT&lt;/code&gt; in the &lt;code&gt;docker/.env&lt;/code&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;DEV_PORT&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;8080&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Run &lt;code&gt;make composer update&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;make up&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Run benchmark testing:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;./wrk -t12 -c1000 -d30s http://localhost:8080&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prepare the RoadRunner testing application.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clone the &lt;a href="https://github.com/klsoft-web/yii3-road-runner-app" rel="noopener noreferrer"&gt;klsoft-web/yii3-road-runner-app&lt;/a&gt; repository.&lt;/li&gt;
&lt;li&gt;Add &lt;code&gt;num_workers: 12&lt;/code&gt; to the pool section of the &lt;code&gt;.rr.yaml&lt;/code&gt; file.&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;docker compose up -d&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Run benchmark testing:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;./wrk -t12 -c1000 -d30s http://localhost:8080&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prepare the Swoole testing application.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clone the &lt;a href="https://github.com/klsoft-web/yii3-swoole-app" rel="noopener noreferrer"&gt;klsoft-web/yii3-swoole-app&lt;/a&gt; repository.&lt;/li&gt;
&lt;li&gt;Add to the &lt;code&gt;config/common/params.php&lt;/code&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;'klsoft/yii&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="err"&gt;-swoole'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="err"&gt;'swooleServerSettings'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;'reactor_num'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;number&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;threads&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;'worker_num'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;number&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;workers&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="err"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Run &lt;code&gt;docker compose up -d&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Run benchmark testing:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;./wrk -t12 -c1000 -d30s http://localhost:9501&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Results&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyeotdanys3h4zbsj34qg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyeotdanys3h4zbsj34qg.png" alt="FrankenPHP vs RoadRunner vs Swoole benchmark testing result" width="800" height="795"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>yii3</category>
      <category>benchmark</category>
    </item>
  </channel>
</rss>
