<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Benchmarking on Luther Monson</title>
    <link>https://luth.io/tags/benchmarking/</link>
    <description>Recent content in Benchmarking on Luther Monson</description>
    <generator>Hugo</generator>
    <language>en</language>
    <lastBuildDate>Thu, 15 Oct 2026 19:45:00 -0700</lastBuildDate>
    <atom:link href="https://luth.io/tags/benchmarking/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Fourth Place in Worker Mode, and Why It Wasn&#39;t PHP</title>
      <link>https://luth.io/blog/2026/10/ephpm-worker-mode-performance/</link>
      <pubDate>Thu, 15 Oct 2026 19:45:00 -0700</pubDate>
      <guid>https://luth.io/blog/2026/10/ephpm-worker-mode-performance/</guid>
      <description>&lt;p&gt;We added &lt;a href=&#34;https://github.com/ephpm/ephpm&#34;&gt;ePHPm&lt;/a&gt; to the&#xA;&lt;a href=&#34;https://github.com/Yii3-Benchmarks/app-api&#34;&gt;Yii3 runtime benchmark&lt;/a&gt;. It runs the same Yii3 API app on a bunch of PHP&#xA;runtimes and compares them. Our fork with the ePHPm runner is &lt;a href=&#34;https://github.com/ephpm/app-api&#34;&gt;ephpm/app-api&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Most of the results were good. ePHPm came first in classic mode and first on the database endpoint in both modes.&#xA;Classic mode is the PHP-FPM style, where every request starts fresh.&lt;/p&gt;&#xA;&lt;p&gt;Worker mode was the surprise. In worker mode the app boots once and stays in memory, like Octane or FrankenPHP&amp;rsquo;s&#xA;worker mode. We came fourth of ten at about 50.7k requests a second. Workerman (~65k) and Swoole (~62k) were ahead.&lt;/p&gt;</description>
    </item>
    <item>
      <title>P99 From 280 ms to 58 ms by Making the Queue Fair</title>
      <link>https://luth.io/blog/2026/09/php-dispatch-fair-queue-p99/</link>
      <pubDate>Mon, 07 Sep 2026 19:45:00 -0700</pubDate>
      <guid>https://luth.io/blog/2026/09/php-dispatch-fair-queue-p99/</guid>
      <description>&lt;p&gt;A third-party Laravel runtime comparison put &lt;a href=&#34;https://github.com/ephpm/ephpm&#34;&gt;ePHPm&lt;/a&gt;&amp;rsquo;s worker mode at the top on&#xA;throughput. It was about 19% ahead of FrankenPHP on &lt;code&gt;/api/static&lt;/code&gt;. It was also at the bottom of the fast group on tail&#xA;latency, with a P99 of 157 ms against FrankenPHP&amp;rsquo;s 57 ms. Best throughput plus the fattest tail is a shape worth&#xA;chasing, because fast execution can&amp;rsquo;t produce it. Making requests faster lowers the mean &lt;em&gt;and&lt;/em&gt; the tail. Only waiting&#xA;can pull them apart. Specifically, unfair waiting.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Stop Running PHP on tokio&#39;s spawn_blocking - Own Your Thread Pool</title>
      <link>https://luth.io/blog/2026/09/own-your-php-thread-pool/</link>
      <pubDate>Fri, 04 Sep 2026 20:30:00 -0700</pubDate>
      <guid>https://luth.io/blog/2026/09/own-your-php-thread-pool/</guid>
      <description>&lt;p&gt;For most of its life, &lt;a href=&#34;https://github.com/ephpm/ephpm&#34;&gt;ePHPm&lt;/a&gt; ran every PHP request on tokio&amp;rsquo;s &lt;code&gt;spawn_blocking&lt;/code&gt;&#xA;pool. It works. It passes tests and it serves benchmarks fine. It&amp;rsquo;s the first thing anybody reaches for when they need&#xA;to call blocking code from async Rust. It&amp;rsquo;s also quietly wrong for a language runtime. The problems only show up under&#xA;overload or after a crash. Over the last three weeks it got replaced with a pool of OS threads that ePHPm owns. That&#xA;pool shipped first behind a config flag, then as the default. As of v0.9.0 the &lt;code&gt;spawn_blocking&lt;/code&gt; engine is gone.&lt;/p&gt;</description>
    </item>
    <item>
      <title>What Does One More WordPress Site Cost?</title>
      <link>https://luth.io/blog/2026/08/what-does-one-more-wordpress-site-cost/</link>
      <pubDate>Tue, 25 Aug 2026 20:20:00 -0700</pubDate>
      <guid>https://luth.io/blog/2026/08/what-does-one-more-wordpress-site-cost/</guid>
      <description>&lt;p&gt;ePHPm v0.7.0 shipped per-site multi-tenancy. Point &lt;code&gt;[server] sites_dir&lt;/code&gt; at a directory and every &lt;code&gt;Host&lt;/code&gt; maps to its own&#xA;docroot and its own Turso database file. One process serves all of them. The first question anybody asks about that is&#xA;&amp;ldquo;how many sites fit on a box?&amp;rdquo; The honest way to answer it is to turn the question around. What does &lt;strong&gt;one more&lt;/strong&gt; site&#xA;cost? If you know the marginal RAM, file descriptors, CPU and disk for a tenant, the box size falls out of arithmetic.&lt;/p&gt;</description>
    </item>
    <item>
      <title>What an Overloaded PHP Server Actually Returns</title>
      <link>https://luth.io/blog/2026/08/what-an-overloaded-php-server-actually-returns/</link>
      <pubDate>Mon, 24 Aug 2026 19:40:00 -0700</pubDate>
      <guid>https://luth.io/blog/2026/08/what-an-overloaded-php-server-actually-returns/</guid>
      <description>&lt;p&gt;Ask most people what their PHP server does when it&amp;rsquo;s overloaded and you&amp;rsquo;ll hear &amp;ldquo;it returns 503s.&amp;rdquo; Ask them how they&#xA;know and it usually comes down to a config setting they read about. I was in that camp for &lt;a href=&#34;https://github.com/ephpm/ephpm&#34;&gt;ePHPm&lt;/a&gt;.&#xA;We had a &lt;code&gt;[server.limits] max_connections&lt;/code&gt; knob, and the docs said it returned 503 at the cap. Every benchmark we had&#xA;ever run reported zero errors under heavy load. Then I wrote a load generator that could produce overload. The honest&#xA;answer was that an overloaded ePHPm returned nothing at all.&lt;/p&gt;</description>
    </item>
    <item>
      <title>My Benchmark Was 4x Wrong Because of WSL</title>
      <link>https://luth.io/blog/2026/08/benchmark-4x-wrong-wsl-drvfs-cwd/</link>
      <pubDate>Thu, 20 Aug 2026 20:45:00 -0700</pubDate>
      <guid>https://luth.io/blog/2026/08/benchmark-4x-wrong-wsl-drvfs-cwd/</guid>
      <description>&lt;p&gt;I do most of my benchmarking on a Windows box in WSL2. It&amp;rsquo;s the machine on my desk with 32 threads and 62 GB of RAM.&#xA;Everybody who does that learns the first rule early: don&amp;rsquo;t put your data on &lt;code&gt;/mnt/c&lt;/code&gt;. DrvFs is the 9p-backed mount that&#xA;exposes the Windows drives inside WSL, and it&amp;rsquo;s slow for file-heavy work. So the databases, the docroot and the build&#xA;output all live on the WSL ext4 disk. My scaling harness for &lt;a href=&#34;https://github.com/ephpm/ephpm&#34;&gt;ePHPm&lt;/a&gt; even says so in&#xA;capital letters in its README.&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
