<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Kévin Dunglas</title>
	<atom:link href="https://dunglas.dev/feed/" rel="self" type="application/rss+xml" />
	<link>https://dunglas.dev</link>
	<description>Founder of Les-Tilleuls.coop (worker-owned cooperative). Creator of API Platform, FrankenPHP, Mercure.rocks, Vulcain.rocks and of some Symfony components.</description>
	<lastBuildDate>Tue, 31 Mar 2026 13:18:24 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
<site xmlns="com-wordpress:feed-additions:1">43930271</site>	<item>
		<title>Coding at the Speed of Thought: The New Era of Symfony Docker</title>
		<link>https://dunglas.dev/2026/03/coding-at-the-speed-of-thought-the-new-era-of-symfony-docker/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=coding-at-the-speed-of-thought-the-new-era-of-symfony-docker</link>
					<comments>https://dunglas.dev/2026/03/coding-at-the-speed-of-thought-the-new-era-of-symfony-docker/#respond</comments>
		
		<dc:creator><![CDATA[Kévin Dunglas]]></dc:creator>
		<pubDate>Tue, 31 Mar 2026 13:18:19 +0000</pubDate>
				<category><![CDATA[DevOps]]></category>
		<category><![CDATA[FrankenPHP]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Talks]]></category>
		<category><![CDATA[Claude Code]]></category>
		<category><![CDATA[coding agents]]></category>
		<category><![CDATA[Dev Containers]]></category>
		<category><![CDATA[Docker]]></category>
		<category><![CDATA[LLM]]></category>
		<category><![CDATA[Xdebug]]></category>
		<guid isPermaLink="false">https://dunglas.dev/?p=7518</guid>

					<description><![CDATA[<p>If we want to discuss Developer Experience (DX) in 2026, we have to talk about instantaneous feedback and coding agents. At SymfonyLive Paris 2026, I presented &#8220;Coding at the Speed of Thought: Symfony DX in 2026&#8220;, where I detailed the bleeding-edge features we have brought to the PHP and Symfony ecosystems. To make this vision...</p>
The post <a href="https://dunglas.dev/2026/03/coding-at-the-speed-of-thought-the-new-era-of-symfony-docker/">Coding at the Speed of Thought: The New Era of Symfony Docker</a> first appeared on <a href="https://dunglas.dev">Kévin Dunglas</a>.]]></description>
										<content:encoded><![CDATA[<p>If we want to discuss Developer Experience (DX) in 2026, we have to talk about instantaneous feedback and coding agents. At SymfonyLive Paris 2026, I presented &#8220;<a href="https://live.symfony.com/2026-paris/schedule/symfony-frankenphp-une-dx-comme-vous-n-en-avez-jamais-vu" title="">Coding at the Speed of Thought: Symfony DX in 2026</a>&#8220;, where I detailed the bleeding-edge features we have brought to the PHP and Symfony ecosystems.</p>



<p>To make this vision a reality, I have recently made dramatic improvements to the <a href="https://github.com/dunglas/symfony-docker" target="_blank" rel="noreferrer noopener">Symfony Docker</a> project. While it remains the easiest way to spin up a Docker-based <a href="https://frankenphp.dev" title="">FrankenPHP</a> skeleton for your Symfony applications, it now packs some incredible new capabilities out of the box.</p>



<h3 class="wp-block-heading">Sandboxed Coding Agents</h3>



<p>It is hard to imagine modern development without coding agents. Symfony Docker now ships with first-class integration for Claude Code.</p>



<p>If you have used agents locally, you likely know the friction of constantly approving execution permissions. We have solved this by allowing Claude Code (and other AI coding assistants) to run in a fully autonomous &#8220;YOLO&#8221; mode. This is achieved safely because the agent is natively sandboxed inside our environment. Security is strictly enforced via a provided default firewall script, which includes a strict allowlist restricted to essentials like Packagist and GitHub.</p>



<p><a href="https://github.com/dunglas/symfony-docker/blob/main/docs/agents.md" title="">Read the detailed documentation about this new feature</a>!</p>



<h3 class="wp-block-heading">Native Dev Containers and Xdebug</h3>



<p>Setting up local environments should never be a hurdle. Symfony Docker now supports <a href="https://containers.dev/" title="">Dev Containers</a>, leveraging the open specification to define your entire environment. This brings out-of-the-box support for compatible IDEs and editors such as Visual Studio Code, PhpStorm, GitHub Codespaces, and Emacs, as implemented in <a href="https://github.com/dunglas/symfony-docker/pull/918" target="_blank" rel="noreferrer noopener">PR #918</a>.</p>



<p>Building on this foundation, we have seamlessly integrated <a href="https://xdebug.org/" title="">Xdebug</a>, the most popular step-by-step debugger for PHP. It is now pre-installed and configured to work immediately via the Dev Container setup. You just start the project, add a breakpoint in your editor, and it works flawlessly, even when <a href="https://frankenphp.dev/docs/worker/" title="">FrankenPHP&#8217;s worker mode</a> is enabled. You can read the technical details of this integration in <a href="https://github.com/dunglas/symfony-docker/pull/925" target="_blank" rel="noreferrer noopener">PR #925</a>.</p>



<h3 class="wp-block-heading">Hot Reloading with FrankenPHP</h3>



<p>On the server side, FrankenPHP has introduced a true game-changer for PHP development: <a href="https://frankenphp.dev/docs/hot-reload/" title="">hot reloading</a>. If you have used modern JavaScript frameworks, you know how magical Hot Module Replacement feels. Now, you get that exact same experience in PHP.</p>



<p>FrankenPHP automatically watches your PHP, Twig, JavaScript, and CSS files for changes. When a modification occurs, it dispatches a <a href="https://mercure.rocks" title="">Mercure</a> update to the browser, reloads worker scripts, and refreshes the Symfony cache in the background. This eliminates the slow cache-repopulation step in development, bringing instantaneous updates directly to your browser. The full setup for this is available in <a href="https://github.com/dunglas/symfony-docker/pull/920" target="_blank" rel="noreferrer noopener">PR #920</a>.</p>



<h3 class="wp-block-heading">Production-Ready, Rootless Images</h3>



<p>Great DX during development is crucial, but deploying safely and efficiently is just as important. We have completely optimized the production images to be leaner and more secure than ever. The setup is now fully production-ready by default, featuring slim, rootless images. You can review the underlying architecture for this in <a target="_blank" rel="noreferrer noopener" href="https://github.com/dunglas/symfony-docker/pull/909">PR #909</a>.</p>



<h3 class="wp-block-heading">SymfonyLive Paris 2026 Slides</h3>



<p>If you missed my talk at SymfonyLive Paris 2026, you can find the complete slide deck embedded below. During the session, I demonstrated all these features, alongside a live demo showing how to remotely control a local Claude Code session straight from a mobile device.</p>



<figure class="wp-block-embed is-type-rich is-provider-speaker-deck wp-block-embed-speaker-deck wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="Coding at the Speed of Thought: The New Era of Symfony Docker" id="talk_frame_1523727" class="speakerdeck-iframe" src="https://speakerdeck.com/player/2d29c9e832e446eeb2c191833b5740c5" width="640" height="360" style="aspect-ratio:640/360; border:0; padding:0; margin:0; background:transparent;" frameborder="0" allowtransparency="true" allowfullscreen="allowfullscreen"></iframe>
</div></figure>



<h3 class="wp-block-heading">Need Help Modernizing Your Stack?</h3>



<p>Transitioning to these new paradigms can be challenging. At <a target="_blank" rel="noreferrer noopener" href="https://les-tilleuls.coop">Les-Tilleuls.coop</a>, we can help you automate your development workflows using coding agents, and we provide deep expertise for Docker, Symfony, and FrankenPHP. If your team needs assistance building or modernizing its infrastructure, feel free to reach out to us.</p>



<p>Finally, maintaining these tools and continuously pushing the boundaries of PHP takes a massive amount of time. If you or your company rely on Symfony, FrankenPHP, Symfony Docker, or API Platform please consider <strong><a href="https://github.com/sponsors/dunglas" target="_blank" rel="noreferrer noopener">sponsoring me on GitHub</a></strong>. Your support directly fuels this free and open-source innovation.</p>The post <a href="https://dunglas.dev/2026/03/coding-at-the-speed-of-thought-the-new-era-of-symfony-docker/">Coding at the Speed of Thought: The New Era of Symfony Docker</a> first appeared on <a href="https://dunglas.dev">Kévin Dunglas</a>.]]></content:encoded>
					
					<wfw:commentRss>https://dunglas.dev/2026/03/coding-at-the-speed-of-thought-the-new-era-of-symfony-docker/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">7518</post-id>	</item>
		<item>
		<title>Windows Support for FrankenPHP: It’s Finally Alive!</title>
		<link>https://dunglas.dev/2026/03/windows-support-for-frankenphp-its-finally-alive/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=windows-support-for-frankenphp-its-finally-alive</link>
					<comments>https://dunglas.dev/2026/03/windows-support-for-frankenphp-its-finally-alive/#respond</comments>
		
		<dc:creator><![CDATA[Kévin Dunglas]]></dc:creator>
		<pubDate>Fri, 06 Mar 2026 17:45:33 +0000</pubDate>
				<category><![CDATA[FrankenPHP]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Windows]]></category>
		<guid isPermaLink="false">https://dunglas.dev/?p=7499</guid>

					<description><![CDATA[<p>It’s happening! I am thrilled to announce the immediate availability of official Windows support for FrankenPHP. Since the project&#8217;s initial release, this has been by far the most requested feature. While many of you have been successfully running FrankenPHP on Windows via WSL (Windows Subsystem for Linux), native support was the &#8220;white whale&#8221; we’ve been...</p>
The post <a href="https://dunglas.dev/2026/03/windows-support-for-frankenphp-its-finally-alive/">Windows Support for FrankenPHP: It’s Finally Alive!</a> first appeared on <a href="https://dunglas.dev">Kévin Dunglas</a>.]]></description>
										<content:encoded><![CDATA[<p>It’s happening! I am thrilled to announce the immediate availability of <strong>official Windows support</strong> for FrankenPHP.</p>



<p>Since the project&#8217;s initial release, this has been by far the most requested feature. While many of you have been successfully running FrankenPHP on Windows via WSL (Windows Subsystem for Linux), native support was the &#8220;white whale&#8221; we’ve been chasing for a long time.</p>



<p>Today, that chase is over. You can now run FrankenPHP natively on Windows, with 100% compatibility, including our killer features like <a href="https://frankenphp.dev/docs/worker/" title="">Worker Mode</a> and <a href="https://frankenphp.dev/docs/hot-reload/" title="">Hot Reloading</a>.</p>



<h2 class="wp-block-heading">Performance That Screams</h2>



<p>We didn&#8217;t just want it to work; we wanted it to be fast. Early benchmarks from the community are already painting an incredible picture.</p>



<p>One user compared FrankenPHP against an already optimized Nginx/PHP-FPM environment on the same Windows Server 2022 machine. The results speak for themselves: a staggering 3.6x performance boost (an increase of over 260%) simply by switching the server runtime.</p>



<p>Additionally, <a href="https://github.com/php/frankenphp/pull/2119#issuecomment-4001846748">new extensive benchmarks by @henderkes</a> further validate these impressive gains natively on Windows across various workloads.</p>



<p><em>A quick tip for maximum speed:</em> While native Windows support is incredibly fast and convenient for development and many production workloads, it is worth noting that for the absolute highest raw throughput, running FrankenPHP via <strong>WSL (Windows Subsystem for Linux)</strong> still yields more performant results due to Linux&#8217;s underlying I/O and networking architecture. In production, prefer using Linux if you can!</p>



<h2 class="wp-block-heading">The Challenge: A Tale of Two Compilers</h2>



<p>Why did it take so long to get here?</p>



<p>Some brave souls tried to port FrankenPHP to Windows early on (huge thanks to them!), but beyond the usual cross-platform headaches (file paths, filesystems), we hit a fundamental, structural wall.</p>



<p>Here is the technical issue in a nutshell:</p>



<ol class="wp-block-list">
<li>FrankenPHP is a Go library that calls PHP’s <code>libphp</code> using <strong>CGO</strong>.</li>



<li>Official PHP builds on Windows are compiled with Visual Studio (MSVC) to ensure the best performance and stability.</li>



<li>Go’s CGO, however, had no support for Visual Studio on Windows. It historically only supported MinGW (GCC).</li>
</ol>



<p>This left us with a massive compatibility gap. We couldn&#8217;t simply link the two together.</p>



<h2 class="wp-block-heading">The Path to a Solution</h2>



<p>We explored several options, each with its own dead end:</p>



<p><strong>Option 1: Add GCC support to PHP for Windows.</strong> We considered patching PHP to support compiling with GCC. However, the PHP maintainers (understandably) weren&#8217;t keen on the extra complexity. We wanted to guarantee absolute stability, avoid ecosystem fragmentation, and use the official binaries directly, so relying on an alternative compiler than Visual Studio (MSVC), the only compiler officially supported by the PHP project, was a no-go.</p>



<p><strong>Option 2: The &#8220;Frankenstein&#8221; Build (llvm-mingw).</strong> We tried an intermediate solution: compiling FrankenPHP with <code>llvm-mingw</code> and linking it against the official Visual Studio-compiled PHP. This failed because of the Standard Library mismatch. When you mix binaries compiled with MinGW (which uses <code>msvcrt.dll</code> or its own runtime) and MSVC (which uses <code>ucrt</code> / <code>vcruntime</code>), you run into critical issues. If one side allocates memory (malloc) and the other tries to free it, or if you try to pass file descriptors across the boundary, the application crashes. They effectively speak different dialects of &#8220;C&#8221;.</p>



<h2 class="wp-block-heading">The Breakthrough: Go 1.26 and clang</h2>



<p>We eventually realized the best path forward was to add support to CGO for the Clang/LLVM frontend provided by Visual Studio.</p>



<p>For those unfamiliar, Visual Studio includes a version of Clang that works as a drop-in replacement for the MSVC compiler (<code>cl.exe</code>). It accepts GCC-like flags (which CGO likes) but uses the Microsoft STL and runtime libraries under the hood. It’s the best of both worlds.</p>



<p>While exploring prior art and preparing to write a patch for Go, we stumbled upon <a href="https://go-review.googlesource.com/c/go/+/703055" title="">an incredible, undocumented contribution from Google that did exactly this</a>.</p>



<p>This patch made it into <strong>Go 1.26</strong>.</p>



<p>With this new capability in Go, and by using the <code>lld-link</code> linker, we were finally able to compile FrankenPHP using the same toolchain as PHP itself.</p>



<h2 class="wp-block-heading">100% Green Tests</h2>



<p>The result is a native Windows binary that links directly against the official, stable PHP binaries provided by the PHP project.</p>



<p>Crucially, because we link against the official PHP builds, <strong>all native PHP extensions supported on Windows work out of the box</strong> in FrankenPHP.</p>



<p>We updated the FrankenPHP codebase to handle the remaining Windows quirks, and I’m happy to report that <strong>all tests are green</strong>.</p>



<ul class="wp-block-list">
<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Native Windows Binary</li>



<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Full Extension Support</li>



<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Worker Mode</li>



<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Hot Reloading</li>
</ul>



<h2 class="wp-block-heading">Credits &amp; Sponsorship</h2>



<p>This complex work was made possible thanks to the generous sponsorship of <a href="https://intelx.io/"><strong>Intelligence X</strong></a> and <a href="https://les-tilleuls.coop/"><strong>Les-Tilleuls.coop</strong></a>.</p>



<p>Open Source sustainability is hard work. If your company relies on FrankenPHP, Caddy, or API Platform, please consider <a href="https://github.com/sponsors/dunglas"><strong>sponsoring me on GitHub</strong></a>. Your contributions allow me to dedicate time to solving deep technical challenges like this one and keeping the ecosystem healthy and fast.</p>



<h2 class="wp-block-heading">Try It Now</h2>



<p>This support has been merged in <a href="https://github.com/php/frankenphp/pull/2119">Pull Request #2119</a>. You can <a href="https://github.com/php/frankenphp/releases/tag/v1.12.0" title="">download the latest binaries for Windows from our releases page</a>!</p>



<p>A huge thank you to everyone who helped investigate this, specifically @TenHian for the initial exploration and @henderkes for the massive work on the final implementation.</p>



<p>Happy coding on Windows! <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f680.png" alt="🚀" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>The post <a href="https://dunglas.dev/2026/03/windows-support-for-frankenphp-its-finally-alive/">Windows Support for FrankenPHP: It’s Finally Alive!</a> first appeared on <a href="https://dunglas.dev">Kévin Dunglas</a>.]]></content:encoded>
					
					<wfw:commentRss>https://dunglas.dev/2026/03/windows-support-for-frankenphp-its-finally-alive/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">7499</post-id>	</item>
		<item>
		<title>Merry Christmas! FrankenPHP 1.11: Hot Reload, Structured Logging, and More Speed</title>
		<link>https://dunglas.dev/2025/12/merry-christmas-frankenphp-1-11-hot-reload-structured-logging-and-more-speed/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=merry-christmas-frankenphp-1-11-hot-reload-structured-logging-and-more-speed</link>
					<comments>https://dunglas.dev/2025/12/merry-christmas-frankenphp-1-11-hot-reload-structured-logging-and-more-speed/#respond</comments>
		
		<dc:creator><![CDATA[Kévin Dunglas]]></dc:creator>
		<pubDate>Wed, 24 Dec 2025 17:29:07 +0000</pubDate>
				<category><![CDATA[API Platform]]></category>
		<guid isPermaLink="false">https://dunglas.dev/?p=7492</guid>

					<description><![CDATA[<p>Ho ho ho! 🎅 I’m thrilled to announce the immediate availability of FrankenPHP 1.11! We have a special gift for the PHP community to unwrap this Christmas Eve. This release is laser-focused on improving the Developer Experience (DX) and deepening the integration between PHP and the Go ecosystem. Here is what we put under the...</p>
The post <a href="https://dunglas.dev/2025/12/merry-christmas-frankenphp-1-11-hot-reload-structured-logging-and-more-speed/">Merry Christmas! FrankenPHP 1.11: Hot Reload, Structured Logging, and More Speed</a> first appeared on <a href="https://dunglas.dev">Kévin Dunglas</a>.]]></description>
										<content:encoded><![CDATA[<p>Ho ho ho! <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f385.png" alt="🎅" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p>I’m thrilled to announce the immediate availability of <strong><a href="https://github.com/php/frankenphp/releases" title="">FrankenPHP 1.11</a></strong>!</p>



<p>We have a special gift for the PHP community to unwrap this Christmas Eve. This release is laser-focused on improving the Developer Experience (DX) and deepening the integration between PHP and the Go ecosystem.</p>



<p>Here is what we put under the tree this year.</p>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f381.png" alt="🎁" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Built-in Hot Reload</h3>



<p>This is the feature many of you have been putting on your wish lists. FrankenPHP 1.11 introduces <a href="https://frankenphp.dev/docs/hot-reload/" title="">a native <strong>hot reload</strong></a> capability designed to vastly improve your development workflow.</p>



<p>Forget mashing F5. This feature provides an experience similar to the <strong>Hot Module Replacement (HMR)</strong> found in modern JavaScript tooling. When you save a PHP file (or a template, or an asset&#8230;), FrankenPHP detects the change and updates the browser in real-time.</p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-4-3 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<div class="jetpack-video-wrapper"><iframe class="youtube-player" width="640" height="360" src="https://www.youtube.com/embed/vNr4EGq3V-s?version=3&#038;rel=1&#038;showsearch=0&#038;showinfo=1&#038;iv_load_policy=1&#038;fs=1&#038;hl=en-US&#038;autohide=2&#038;wmode=transparent" allowfullscreen="true" style="border:0;" sandbox="allow-scripts allow-same-origin allow-popups allow-presentation allow-popups-to-escape-sandbox"></iframe></div>
</div></figure>



<p>It leverages FrankenPHP&#8217;s <a href="https://frankenphp.dev/docs/mercure" title="built-in Mercure hub">built-in Mercure hub</a> to push updates instantly. A support JavaScript library, built on top of the excellent <a href="https://github.com/bigskysoftware/idiomorph" target="_blank" rel="noreferrer noopener">Idiomorph</a> library, will intelligently &#8220;morph&#8221; the DOM, preserving your scroll position and form input state.</p>



<p>This feature natively works <a href="https://frankenphp.dev/docs/wordpress/" title="">with WordPress</a> (showcased in the video), Laravel, Symfony, and virtually any PHP application.</p>



<h4 class="wp-block-heading">How to use it</h4>



<p>Enable the <code>hot_reload</code> option in your <code>Caddyfile</code>.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><strong>Warning:</strong> This feature incurs performance overhead as it watches the filesystem. <strong>Never enable it in production.</strong></p>
</blockquote>



<pre class="wp-block-code"><code class="">localhost

# Enable the built-in Mercure hub
mercure {
    anonymous
}

root public/
php_server {
    # Enable the hot reload feature
    hot_reload
}</code></pre>



<p>For the best experience, if your app or framework supports the <strong><a href="https://frankenphp.dev/docs/worker" title="">worker mode</a></strong>, combine it with the <code>worker.watch</code> directive. This ensures your worker script kernel restarts while the browser simultaneously updates:</p>



<pre class="wp-block-code"><code class="">localhost

mercure {
    anonymous
}

root public/
php_server {
    hot_reload

    worker {
        file /path/to/my_worker.php
        watch
    }
}</code></pre>



<p>On the client side, just add the necessary JS libraries and meta element to your layout. The Mercure URL is automatically provided via <code>$_SERVER['FRANKENPHP_HOT_RELOAD']</code>.</p>



<pre class="wp-block-code"><code lang="php" class="language-php">&lt;!DOCTYPE html&gt;
&lt;title&gt;FrankenPHP Hot Reload&lt;/title&gt;
&lt;?php if (isset($_SERVER['FRANKENPHP_HOT_RELOAD'])): ?&gt;
&lt;meta name="frankenphp-hot-reload:url" content="&lt;?=$_SERVER['FRANKENPHP_HOT_RELOAD']?&gt;"&gt;
&lt;script src="https://cdn.jsdelivr.net/npm/idiomorph"&gt;&lt;/script&gt;
&lt;script src="https://cdn.jsdelivr.net/npm/frankenphp-hot-reload/+esm" type="module"&gt;&lt;/script&gt;
&lt;?php endif ?&gt;</code></pre>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f384.png" alt="🎄" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Structured Logging with <code>frankenphp_log()</code></h3>



<p>Observability in modern applications is crucial. Go recently <a href="https://go.dev/blog/slog" title="">introduced standardized structured logging via the <code>log/slog</code> package</a>, and we are bridging this capability into PHP.</p>



<p>The new <a href="https://frankenphp.dev/docs/logging/" title=""><code>frankenphp_log()</code> function</a> allows you to emit structured logs directly from your PHP code.</p>



<p>This is fantastic for production environments, as your PHP logs will now be formatted consistently with Caddy&#8217;s logs, making ingestion into platforms like Datadog, Grafana Loki, or Elastic, as well as OpenTelemetry support, much easier.</p>



<pre class="wp-block-code"><code class="">&lt;?php

frankenphp_log(
    message: "User logged in",
    level: FRANKENPHP_LOG_LEVEL_INFO, // FRANKENPHP_LOG_LEVEL_DEBUG, FRANKENPHP_LOG_LEVEL_INFO, FRANKENPHP_LOG_LEVEL_WARN, or FRANKENPHP_LOG_LEVEL_ERROR, defaults to FRANKENPHP_LOG_LEVEL_INFO
    context: [
        "user_id" =&gt; 123,
        "ip" =&gt; $_SERVER['REMOTE_ADDR']
    ]
);</code></pre>



<p>By default, as Caddy is configured to output <a href="https://caddyserver.com/docs/logging#structured-logs" title="">structured JSON logs</a>, this PHP call will produce a beautifully structured log entry in standard output:</p>



<pre class="wp-block-code"><code class="">{"level":"info","ts":1703690000.123,"logger":"frankenphp","msg":"User logged in","user_id":123,"ip":"192.168.1.1"}</code></pre>



<p>Logging can be entirely customized using Caddy configuration.</p>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f6f7.png" alt="🛷" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Performance Improvements</h3>



<p>FrankenPHP is already known for being fast but we want it to fly like a reindeer.</p>



<p>Thanks to <a href="https://github.com/php/frankenphp/discussions/1981" title="">rigorous benchmarking</a> (with <a href="https://tideways.com/profiler/blog/testing-if-franken-php-classic-mode-is-faster-and-more-scalable-than-php-fpm" title="">the help of Tideways</a>), we <a href="https://github.com/php/frankenphp/pull/2033" title="">identified and resolved</a> bottlenecks under very high load. This results in better overall throughput in edge cases and, more importantly, improved <strong>tail latency</strong> (p95 and p99 benchmarks). Your application will be more consistent under heavy load.</p>



<p>We also <a href="https://github.com/php/frankenphp/pull/2040" title="">significantly improved the performance of uncommon HTTP headers parsing</a> by upgrading to version 2 of <a href="https://maypok86.github.io/otter/" title="">the Otter cache library</a>.</p>



<p>Thanks to these patches, according to our benchmarks, FrankenPHP is now faster than PHP-FPM even without enabling the worker mode.</p>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f9f8.png" alt="🧸" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Unwrap &#8220;Le Monstre&#8221;</h3>



<p>What is Christmas without toys?</p>



<figure class="wp-block-image size-full"><a href="https://dunglas.dev/wp-content/uploads/2025/09/FrankenPHP-elePHPant.jpg"><img fetchpriority="high" decoding="async" width="1024" height="1365" src="https://dunglas.dev/wp-content/uploads/2025/09/FrankenPHP-elePHPant.jpg" alt="FrankenPHP elePHPant" class="wp-image-7481"/></a></figure>



<p>We are delighted to announce that the official FrankenPHP plushy—affectionately known as <strong>&#8220;Le Monstre&#8221;</strong>—is finally ready for adoption!</p>



<p>For now, availability is exclusive to those who attended the <strong><a href="https://api-platform.com/con" title="">API Platform Conference</a></strong> last September. If you were there, head over to <strong><a href="https://lemonstre.frankenphp.dev" target="_blank" rel="noopener" title="">Le Monstre shop</a></strong> and use your <strong>conference ticket number</strong> as the coupon code to unlock the checkout and claim your plushy.</p>



<p>For everyone else, don&#8217;t worry! Le Monstre will be available to the general public in <strong>early 2026</strong>.</p>



<h3 class="wp-block-heading">Get it now!</h3>



<p>I want to thank <a href="https://github.com/php/frankenphp/graphs/contributors" title="">all the contributors</a> who helped make this release possible. I hope you enjoy this release as much as we enjoyed building it.</p>



<p>Merry Christmas and Happy New Year from the FrankenPHP team! <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f49c.png" alt="💜" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p><strong><a href="https://github.com/php/frankenphp/releases" target="_blank" rel="noopener" title="">Download FrankenPHP v1.11</a></strong></p>The post <a href="https://dunglas.dev/2025/12/merry-christmas-frankenphp-1-11-hot-reload-structured-logging-and-more-speed/">Merry Christmas! FrankenPHP 1.11: Hot Reload, Structured Logging, and More Speed</a> first appeared on <a href="https://dunglas.dev">Kévin Dunglas</a>.]]></content:encoded>
					
					<wfw:commentRss>https://dunglas.dev/2025/12/merry-christmas-frankenphp-1-11-hot-reload-structured-logging-and-more-speed/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">7492</post-id>	</item>
		<item>
		<title>The Best of Both Worlds: Go-Powered gRPC for Your PHP and API Platform Apps</title>
		<link>https://dunglas.dev/2025/09/the-best-of-both-worlds-go-powered-grpc-for-your-php-and-api-platform-apps/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=the-best-of-both-worlds-go-powered-grpc-for-your-php-and-api-platform-apps</link>
					<comments>https://dunglas.dev/2025/09/the-best-of-both-worlds-go-powered-grpc-for-your-php-and-api-platform-apps/#respond</comments>
		
		<dc:creator><![CDATA[Kévin Dunglas]]></dc:creator>
		<pubDate>Fri, 19 Sep 2025 10:19:56 +0000</pubDate>
				<category><![CDATA[API Platform]]></category>
		<category><![CDATA[FrankenPHP]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[gRPC]]></category>
		<guid isPermaLink="false">https://dunglas.dev/?p=7484</guid>

					<description><![CDATA[<p>I&#8217;m thrilled to announce a brand-new feature I unveiled today during my opening keynote at the API Platform Conference: an experimental extension for FrankenPHP that brings gRPC support to PHP! 🚀 This extension allows you to build high-performance gRPC servers using PHP, Go, or even a mix of both. It leverages the power of FrankenPHP&#8217;s...</p>
The post <a href="https://dunglas.dev/2025/09/the-best-of-both-worlds-go-powered-grpc-for-your-php-and-api-platform-apps/">The Best of Both Worlds: Go-Powered gRPC for Your PHP and API Platform Apps</a> first appeared on <a href="https://dunglas.dev">Kévin Dunglas</a>.]]></description>
										<content:encoded><![CDATA[<p>I&#8217;m thrilled to announce a brand-new feature I unveiled today during my opening keynote at the <a href="https://api-platform.com/con" title="">API Platform Conference</a>: an experimental extension for <a href="https://frankenphp.dev" title="">FrankenPHP</a> that brings <strong><a href="https://grpc.io" title="">gRPC</a> support to PHP</strong>! <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f680.png" alt="🚀" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p>This extension allows you to build high-performance gRPC servers using <a href="https://php.net" title="">PHP</a>, <a href="https://go.dev" title="">Go</a>, or even a mix of both. It leverages the power of <a href="https://frankenphp.dev/docs/extensions/" title="">FrankenPHP&#8217;s Go extension support</a> and the mature <code><a href="https://github.com/grpc/grpc-go" title="">gRPC-Go</a></code> library to deliver exceptional performance.</p>



<p>Ready to dive into the code? The brand-new gRPC extension is free and open-source and <a href="https://github.com/dunglas/frankenphp-grpc" title="">waiting for you on GitHub</a>! If you&#8217;re as excited about bringing high-performance gRPC to PHP as I am, head over to the repository and give it a star <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" />. Your support is hugely appreciated and helps the project grow!</p>



<h3 class="wp-block-heading">Key Features of the gRPC Extension</h3>



<ul class="wp-block-list">
<li><strong>High-Performance Server</strong>: Run a powerful gRPC server with FrankenPHP, executing your PHP code in a persistent worker loop for maximum efficiency.</li>



<li><strong>PHP and Go Handlers</strong>: Write your gRPC service handlers in either PHP or Go, giving you the flexibility to use the best language for the job. You can even mix and match them within the same server!</li>



<li><strong>Full <code>gRPC-Go</code> Compatibility</strong>: Benefit from all the features of the robust and widely-used <code>gRPC-Go</code> library.</li>



<li><strong>Pure Go Implementation</strong>: The extension is written entirely in Go, with no C code involved.</li>



<li>East <strong><a href="https://api-platform.com" title="">API Platform</a> Integration</strong>: Seamlessly integrate with API Platform for building powerful and modern APIs.</li>



<li></li>
</ul>



<p><em>This extension is highly experimental and not yet recommended for production use. It currently requires the <code>main</code> branch of FrankenPHP and its public API may change at any time without notice.</em></p>



<h3 class="wp-block-heading">Getting Started</h3>



<p>Let&#8217;s walk through how to set up a gRPC server with the new FrankenPHP extension.</p>



<h4 class="wp-block-heading">1. Create a New Go Module for Your gRPC Server</h4>



<pre class="wp-block-code"><code lang="bash" class="language-bash">go mod init example.com/mygrpcserver </code></pre>



<h4 class="wp-block-heading">2. Create a Protobuf Definition</h4>



<p>First, define your gRPC service and messages in a <code>.proto</code> file. Here&#8217;s a simple example:</p>



<pre class="wp-block-code"><code class="">syntax = "proto3";

option go_package = "example.com/mygrpcserver/helloworld";

package helloworld;

service Greeter {
    rpc SayHello (HelloRequest) returns (HelloReply) {}
}

message HelloRequest {
    string name = 1;
}

message HelloReply {
    string message = 1;
}</code></pre>



<p>Then, generate the Go code from your <code>.proto</code> file:</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative helloworld/helloworld.proto</code></pre>



<h4 class="wp-block-heading">3. Implement the gRPC Server in Go</h4>



<p>Next, create the Go part of your gRPC server. This code will handle the gRPC requests and forward them to your PHP worker.</p>



<pre class="wp-block-code"><code lang="go" class="language-go">package mygrpcserver

import (
    "context"
    "fmt"

    pb "example.com/mygrpcserver/helloworld"
    "github.com/dunglas/frankenphp"
    phpGrpc "github.com/dunglas/frankenphp-grpc"
    "github.com/go-viper/mapstructure/v2"
    "google.golang.org/grpc"
    "google.golang.org/grpc/reflection"
)

func init() {
    phpGrpc.RegisterGrpcServerFactory(func() *grpc.Server {
        s := grpc.NewServer()
        pb.RegisterGreeterServer(s, &amp;server{})
        reflection.Register(s)

        return s
    })
}

type server struct {
    pb.UnimplementedGreeterServer
}

// SayHello implements helloworld.GreeterServer
func (s *server) SayHello(_ context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
    if in.Name == "" {
        return nil, fmt.Errorf("the Name field is required")
    }

    // Convert the request to a map[string]any
    var phpRequest map[string]any
    if err := mapstructure.Decode(in, &amp;phpRequest); err != nil {
        return nil, err
    }

    // Call the PHP code, pass the map as a PHP associative array
    phpResponse := phpGrpc.HandleRequest(phpRequest)

    // Convert the PHP response (a map) back to a HelloReply struct
    var response pb.HelloReply
    if err := mapstructure.Decode(phpResponse.(frankenphp.AssociativeArray).Map, &amp;response); err != nil {
        return nil, err
    }

    return &amp;response, nil
}
</code></pre>



<h4 class="wp-block-heading">4. Implement the gRPC Service Handler in PHP</h4>



<p>Now, create a <code>grpc-worker.php</code> file to handle the logic of your gRPC service.</p>



<pre class="wp-block-code"><code lang="php" class="language-php">&lt;?php

// Require the Composer autoloader here if needed (API Platform, Symfony, etc.)
//require __DIR__ . '/vendor/autoload.php';

// Handler outside the loop for better performance (doing less work)
$handler = static function (array $request): array {
    // Do something with the gRPC request

    return ['message' => "Hello, {$request['Name']}"];
};

$maxRequests = (int)($_SERVER['MAX_REQUESTS'] ?? 0);
for ($nbRequests = 0; !$maxRequests || $nbRequests &lt; $maxRequests; ++$nbRequests) {
    $keepRunning = \frankenphp_handle_request($handler);

    // Call the garbage collector to reduce the chances of it being triggered in the middle of the handling of a request
    gc_collect_cycles();

    if (!$keepRunning) {
        break;
    }
}</code></pre>



<h4 class="wp-block-heading">5. Enable the FrankenPHP Extension with a <code>Caddyfile</code></h4>



<p>Create a <code>Caddyfile</code> to configure FrankenPHP and enable the gRPC extension.</p>



<pre class="wp-block-code"><code class="">{
    frankenphp
    grpc {
        address :50051
        worker grpc-worker.php
        min_threads 50
    }
}</code></pre>



<h4 class="wp-block-heading">6. Build and Run</h4>



<p>Finally, build your custom FrankenPHP binary with the gRPC extension and run it.</p>



<p>Be sure to install <a href="https://frankenphp.dev/docs/compile/" title="">FrankenPHP dependencies</a> first.</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">XCADDY_DEBUG=1 \
    CGO_ENABLED=1 \
    XCADDY_GO_BUILD_FLAGS="-tags=nobadger,nomysql,nopgx" \
    CGO_CFLAGS="$(php-config --includes) -I/opt/homebrew/include/" \
    CGO_LDFLAGS="$(php-config --ldflags) $(php-config --libs) -L/opt/homebrew/lib/ -L/usr/lib" \
    xcaddy build

./caddy run</code></pre>



<p>Your gRPC server will now be running on <code>localhost:50051</code>. I recommend using a tool like <a target="_blank" rel="noreferrer noopener" href="https://github.com/fullstorydev/grpcui">gRPC UI</a> to test your new server.</p>



<p>I&#8217;m excited to see what the community builds with this new capability. Your feedback is highly welcome, so please give it a try and share your thoughts!</p>



<p>Here are the slides I presented during the keynote:</p>



<figure class="wp-block-embed is-type-rich is-provider-speaker-deck wp-block-embed-speaker-deck wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="Introducing FrankenPHP gRPC" id="talk_frame_1440270" class="speakerdeck-iframe" src="//speakerdeck.com/player/7ffb7c1cc4854b70a0864314df97fae1" width="640" height="360" style="aspect-ratio:640/360; border:0; padding:0; margin:0; background:transparent;" frameborder="0" allowtransparency="true" allowfullscreen="allowfullscreen"></iframe>
</div></figure>The post <a href="https://dunglas.dev/2025/09/the-best-of-both-worlds-go-powered-grpc-for-your-php-and-api-platform-apps/">The Best of Both Worlds: Go-Powered gRPC for Your PHP and API Platform Apps</a> first appeared on <a href="https://dunglas.dev">Kévin Dunglas</a>.]]></content:encoded>
					
					<wfw:commentRss>https://dunglas.dev/2025/09/the-best-of-both-worlds-go-powered-grpc-for-your-php-and-api-platform-apps/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">7484</post-id>	</item>
		<item>
		<title>Unleash the Monster: The FrankenPHP elePHPant is Born</title>
		<link>https://dunglas.dev/2025/09/unleash-the-monster-the-frankenphp-elephpant-is-born/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=unleash-the-monster-the-frankenphp-elephpant-is-born</link>
					<comments>https://dunglas.dev/2025/09/unleash-the-monster-the-frankenphp-elephpant-is-born/#respond</comments>
		
		<dc:creator><![CDATA[Kévin Dunglas]]></dc:creator>
		<pubDate>Tue, 02 Sep 2025 09:44:19 +0000</pubDate>
				<category><![CDATA[FrankenPHP]]></category>
		<category><![CDATA[PHP]]></category>
		<guid isPermaLink="false">https://dunglas.dev/?p=7478</guid>

					<description><![CDATA[<p>It&#8217;s alive! After months of meticulous stitching, we&#8217;re thrilled to announce the official release of the FrankenPHP elePHPant plushie! This isn&#8217;t your average plushie—it&#8217;s a grotesque yet charming creature, a patchwork of code and fluff, and the perfect companion for those late-night coding sessions. Dare to adopt this creature of the night? Here’s how to...</p>
The post <a href="https://dunglas.dev/2025/09/unleash-the-monster-the-frankenphp-elephpant-is-born/">Unleash the Monster: The FrankenPHP elePHPant is Born</a> first appeared on <a href="https://dunglas.dev">Kévin Dunglas</a>.]]></description>
										<content:encoded><![CDATA[<p>It&#8217;s alive!</p>



<p>After months of meticulous stitching, we&#8217;re thrilled to announce the official release of the <a href="https://frankenphp.dev" title="">FrankenPHP</a> elePHPant plushie! This isn&#8217;t your average plushie—it&#8217;s a grotesque yet charming creature, a patchwork of code and fluff, and the perfect companion for those late-night coding sessions.</p>



<p>Dare to adopt this creature of the night? Here’s how to get your very own FrankenPHP elePHPant:</p>



<h2 class="wp-block-heading">API Platform Conference Attendees</h2>



<p>The first batch of FrankenPHP elePHPants will be unleashed at <a href="https://api-platform.com/con/" title="the API Platform Conference">the API Platform Conference</a> in Lille. Come find us at our booth to claim one before they return to the shadows forever!</p>



<h2 class="wp-block-heading">Online Attendees</h2>



<p>For those attending the conference virtually, a limited number will be available to purchase online immediately following the in-person event. Check your conference attendee emails for the link to our crypt.</p>



<h2 class="wp-block-heading">General Availability</h2>



<p>If any of our monstrous creations remain after the conference, they will haunt our online shop a few weeks later. Stay tuned for updates.</p>The post <a href="https://dunglas.dev/2025/09/unleash-the-monster-the-frankenphp-elephpant-is-born/">Unleash the Monster: The FrankenPHP elePHPant is Born</a> first appeared on <a href="https://dunglas.dev">Kévin Dunglas</a>.]]></content:encoded>
					
					<wfw:commentRss>https://dunglas.dev/2025/09/unleash-the-monster-the-frankenphp-elephpant-is-born/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">7478</post-id>	</item>
		<item>
		<title>FrankenPHP has reached 10,000 stars: the elePHPant plush toy is coming!</title>
		<link>https://dunglas.dev/2025/08/frankenphp-has-reached-10000-stars-the-elephpant-plush-toy-is-coming/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=frankenphp-has-reached-10000-stars-the-elephpant-plush-toy-is-coming</link>
					<comments>https://dunglas.dev/2025/08/frankenphp-has-reached-10000-stars-the-elephpant-plush-toy-is-coming/#respond</comments>
		
		<dc:creator><![CDATA[Kévin Dunglas]]></dc:creator>
		<pubDate>Thu, 14 Aug 2025 12:34:27 +0000</pubDate>
				<category><![CDATA[API Platform]]></category>
		<category><![CDATA[FrankenPHP]]></category>
		<category><![CDATA[PHP]]></category>
		<guid isPermaLink="false">https://dunglas.dev/?p=7466</guid>

					<description><![CDATA[<p>FrankenPHP has just reached 10,000 ⭐️ on GitHub! This important milestone was reached just a few months after the project joined the PHP Foundation, thanks to the hard work of the maintainers and contributors, those who spread the word about the project, and everyone who tested it and reported bugs. A big thank you to...</p>
The post <a href="https://dunglas.dev/2025/08/frankenphp-has-reached-10000-stars-the-elephpant-plush-toy-is-coming/">FrankenPHP has reached 10,000 stars: the elePHPant plush toy is coming!</a> first appeared on <a href="https://dunglas.dev">Kévin Dunglas</a>.]]></description>
										<content:encoded><![CDATA[<p>FrankenPHP has just reached <a href="https://github.com/php/frankenphp" title=""><strong>10,000 <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /></strong> on GitHub</a>!</p>



<p>This important milestone was reached just a few months after the <a href="https://dunglas.dev/2025/05/frankenphp-is-now-officially-supported-by-the-php-foundation/" title="">project joined the PHP Foundation</a>, thanks to the hard work of the maintainers and contributors, those who spread the word about the project, and everyone who tested it and reported bugs. <strong>A big thank you to all of you!</strong></p>



<p>As promised, to celebrate, we have launched the production of stuffed ele(Franken)PHPants. <strong>The first specimen will be available exclusively at <a href="https://api-platform.com/con/" title="the API Platform conference">the API Platform conference</a></strong>, which will take place in September in my city of Lille.</p>



<p>A big party for the 10K stars and the 10th anniversary of <a href="https://api-platform.com" title="">API Platform</a> will also take place there.</p>



<p>Places are filling up fast, but <strong>there are still a few available</strong>. Hurry up and grab yours if you want to be part of it and get your little monster plush toy <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f9df.png" alt="🧟" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p></p>The post <a href="https://dunglas.dev/2025/08/frankenphp-has-reached-10000-stars-the-elephpant-plush-toy-is-coming/">FrankenPHP has reached 10,000 stars: the elePHPant plush toy is coming!</a> first appeared on <a href="https://dunglas.dev">Kévin Dunglas</a>.]]></content:encoded>
					
					<wfw:commentRss>https://dunglas.dev/2025/08/frankenphp-has-reached-10000-stars-the-elephpant-plush-toy-is-coming/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">7466</post-id>	</item>
		<item>
		<title>FrankenPHP’s New Features: Thread Autoscaling, Mostly Static Binaries, deb and RPM Packages, Caddy 2.10…</title>
		<link>https://dunglas.dev/2025/05/frankenphps-new-features-thread-autoscaling-mostly-static-binaries-deb-and-rpm-packages-caddy-2-10/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=frankenphps-new-features-thread-autoscaling-mostly-static-binaries-deb-and-rpm-packages-caddy-2-10</link>
					<comments>https://dunglas.dev/2025/05/frankenphps-new-features-thread-autoscaling-mostly-static-binaries-deb-and-rpm-packages-caddy-2-10/#comments</comments>
		
		<dc:creator><![CDATA[Kévin Dunglas]]></dc:creator>
		<pubDate>Mon, 19 May 2025 14:01:53 +0000</pubDate>
				<category><![CDATA[FrankenPHP]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[PHP]]></category>
		<guid isPermaLink="false">https://dunglas.dev/?p=7453</guid>

					<description><![CDATA[<p>FrankenPHP 1.5 and 1.6 (released today) contain many major features and fixes that greatly improve the usability and performance of the project! Let’s review some of them. Thread Autoscaling Until now, it was necessary to statically define the number of threads that FrankenPHP uses to handle PHP requests. By default, FrankenPHP starts two times more...</p>
The post <a href="https://dunglas.dev/2025/05/frankenphps-new-features-thread-autoscaling-mostly-static-binaries-deb-and-rpm-packages-caddy-2-10/">FrankenPHP’s New Features: Thread Autoscaling, Mostly Static Binaries, deb and RPM Packages, Caddy 2.10…</a> first appeared on <a href="https://dunglas.dev">Kévin Dunglas</a>.]]></description>
										<content:encoded><![CDATA[<p><a href="https://frankenphp.dev">FrankenPHP</a> <a href="https://github.com/dunglas/frankenphp/releases/tag/v1.5.0">1.5</a> and <a href="https://github.com/dunglas/frankenphp/releases/tag/v1.6.0">1.6</a> (released today) contain many major features and fixes that greatly improve the usability and performance of the project!</p>



<p>Let’s review some of them.</p>



<h1 class="wp-block-heading">Thread Autoscaling</h1>



<p>Until now, it was necessary to statically define the number of threads that FrankenPHP uses to handle PHP requests. By default, FrankenPHP starts two times more threads than the number of CPUs on the machine: this is often not optimal. The proper number of threads to start depends heavily on your application itself and your hardware. We provide <a href="https://frankenphp.dev/docs/performance/#number-of-threads-and-workers">extensive documentation explaining how to find the best suitable value</a>.</p>



<p>Starting with version 1.5, Alexander Stecher added a new way: thread autoscaling. When using this mode, FrankenPHP will automatically spawn additional threads at runtime up to a specified limit. This new <code>max_threads</code> directive can help you figure out how many threads you need to handle your traffic and can make the server more resilient to latency spikes. If set to auto, the limit will be estimated based on the <code>memory_limit</code> set in your <code>php.ini</code>. This new mode is similar to PHP FPM’s <code><code>pm.max_children</code></code>.</p>



<p><a href="https://frankenphp.dev/docs/performance/#max_threads">Read the related documentation</a></p>



<h1 class="wp-block-heading">Maximum Wait Time</h1>



<p>Alexander also added a new option to limit the time a request can be buffered, waiting for a PHP thread to be available. This helps the server to recover faster during latency spikes by not allowing an endless accumulation of queued requests.</p>



<p>When the new <code>max_wait_time</code> is set, if the timeout is reached, a 504 “<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status/504">Gateway Timeout</a>” error will be returned.</p>



<h1 class="wp-block-heading">Mostly Static, glibc-based Static Binaries</h1>



<p>One of the key features of FrankenPHP is that it can be downloaded as a fully static binary that contains FrankenPHP itself, a web server (Caddy), the PHP engine, the most popular PHP extensions, and their dependencies.</p>



<p>This means that you can execute FrankenPHP by downloading a single executable file containing everything without having any system dependencies.</p>



<p>This fully static binary is using the musl-libc and PHP has some known issues when using musl (especially <a href="https://github.com/php/php-src/issues/13648">with OpenSSL</a>). Also, musl is known to be slower than the GNU libc in some circumstances.</p>



<p><a href="https://static-php.dev">static-php-cli</a>, the tool that FrankenPHP uses under the hood to create its static builds, recently gained the ability to <a href="https://static-php.dev/en/guide/build-with-glibc.html">build “mostly static” versions of libphp</a>. This means that all required system libraries are statically linked (so they don’t have to be installed on the system), except the libc itself. Thanks to this trick, FrankenPHP will link against the local installation of the GNU libc, which is available by default in most popular GNU/Linux distributions.</p>



<p>Since FrankenPHP 1.5, thanks to Jerry Ma and Marc “henderkes” (who are also the authors of this feature in static-php-cli), we provide mostly static builds of FrankenPHP that can be <a href="https://github.com/dunglas/frankenphp/releases">downloaded directly from the GitHub releases</a> (the <code>frankenphp-linux-&lt;arch>-gnu</code> files).</p>



<p>In addition to better stability and performance, Mostly Static builds also have the benefit of being able to load dynamically built PHP extensions, including Xdebug and FFI, which are not supported by musl-based builds!</p>



<h1 class="wp-block-heading">Debian/Ubuntu and RedHat Packages</h1>



<p>Mostly Static binaries also unlocked another feature that has also been contributed by Marc “henderkes”: official RPM and deb packages!</p>



<p>In addition to <a href="https://github.com/dunglas/homebrew-frankenphp">the Homebrew packages</a>, starting from FrankenPHP 1.6, packages for Debian/Ubuntu and RedHat are built in the CI and provided in <a href="https://github.com/dunglas/frankenphp/releases">the GitHub releases</a>!</p>



<p>In the future, package repositories will be set up (help welcome!).</p>



<h1 class="wp-block-heading">Site-Specific Workers</h1>



<p>Marc (he’s on fire!) also added the ability to define workers for a specific site instead of globally for all sites. This enables us to write a <code>Caddyfile</code> like this:</p>



<pre class="wp-block-code"><code class="">{
    frankenphp
}

one.example.com {
    php_server {
        root /var/www/app-one
        env APP_NAME one
        worker index.php 16 # 16 instances of the worker script will run in parallel
    }
}
two.example.com {
    root /var/www/app-two
    php_server {
        env APP_NAME two
        worker {
            file index.php
            num 8 # 8 instances of the worker script will run in parallel
        }
    }
}</code></pre>



<h1 class="wp-block-heading">Caddy 2.10</h1>



<p>FrankenPHP 1.6 is now built on top of <a href="https://github.com/caddyserver/caddy/releases/tag/v2.10.0">Caddy 2.10</a>. This brand new version of our favorite web server comes with a bunch of new features, including <a href="https://support.mozilla.org/kb/faq-encrypted-client-hello">Encrypted Client Hello</a>, post-quantum (PQC) key exchange or global DNS providers.</p>



<h1 class="wp-block-heading">Support The Project</h1>



<p>This week, <a href="http://les-tilleuls.coop">Les-Tilleuls.coop</a>, <a href="https://thephp.foundation/">the PHP Foundation</a> and <a href="https://caddyserver.com">the Caddy team</a> announced that <a href="https://dunglas.dev/2025/05/frankenphp-is-now-officially-supported-by-the-php-foundation/">FrankenPHP is now officially supported by the PHP Foundation</a>.</p>



<p>Also, many talks about FrankenPHP have been announced at the <a href="https://api-platform.com/con/" title="">API Platform Conference</a>, in September in France. Be sure to be there, to meet some of the main contributors of the project will too!</p>



<p>To support the project, please contribute, <a href="https://github.com/dunglas/frankenphp">give it stars on GitHub</a>, and <a href="https://github.com/sponsors/dunglas">sponsor me</a>!</p>The post <a href="https://dunglas.dev/2025/05/frankenphps-new-features-thread-autoscaling-mostly-static-binaries-deb-and-rpm-packages-caddy-2-10/">FrankenPHP’s New Features: Thread Autoscaling, Mostly Static Binaries, deb and RPM Packages, Caddy 2.10…</a> first appeared on <a href="https://dunglas.dev">Kévin Dunglas</a>.]]></content:encoded>
					
					<wfw:commentRss>https://dunglas.dev/2025/05/frankenphps-new-features-thread-autoscaling-mostly-static-binaries-deb-and-rpm-packages-caddy-2-10/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">7453</post-id>	</item>
		<item>
		<title>FrankenPHP Is Now Officially Supported by The PHP Foundation</title>
		<link>https://dunglas.dev/2025/05/frankenphp-is-now-officially-supported-by-the-php-foundation/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=frankenphp-is-now-officially-supported-by-the-php-foundation</link>
					<comments>https://dunglas.dev/2025/05/frankenphp-is-now-officially-supported-by-the-php-foundation/#respond</comments>
		
		<dc:creator><![CDATA[Kévin Dunglas]]></dc:creator>
		<pubDate>Thu, 15 May 2025 09:33:17 +0000</pubDate>
				<category><![CDATA[DevOps]]></category>
		<category><![CDATA[FrankenPHP]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Caddy]]></category>
		<category><![CDATA[PHP Foundation]]></category>
		<guid isPermaLink="false">https://dunglas.dev/?p=7447</guid>

					<description><![CDATA[<p>FrankenPHP, a modern high-performance PHP application server created by Kévin Dunglas and sponsored by Les-Tilleuls.coop, is now officially supported by the PHP Foundation. FrankenPHP integrates PHP directly into Go and Caddy, simplifying deployment, improving performance, and reducing costs. It powers real-time features, supports advanced hosting scenarios, and offers a performance-boosting “worker mode” already integrated by...</p>
The post <a href="https://dunglas.dev/2025/05/frankenphp-is-now-officially-supported-by-the-php-foundation/">FrankenPHP Is Now Officially Supported by The PHP Foundation</a> first appeared on <a href="https://dunglas.dev">Kévin Dunglas</a>.]]></description>
										<content:encoded><![CDATA[<p>FrankenPHP, a modern high-performance PHP application server created by <a href="https://dunglas.dev">Kévin Dunglas</a> and sponsored by <a href="http://les-tilleuls.coop">Les-Tilleuls.coop</a>, is now officially supported by the PHP Foundation. FrankenPHP integrates PHP directly into Go and Caddy, simplifying deployment, improving performance, and reducing costs. It powers real-time features, supports advanced hosting scenarios, and offers a performance-boosting “worker mode” already integrated by Laravel, Symfony, and Yii. The PHP Foundation will actively contribute to FrankenPHP’s development and host its code on the official PHP GitHub, marking a major step toward modernizing the PHP ecosystem while keeping governance with the original maintainers.</p>



<p>PHP is a programming language used by around 70% of websites and applications, and by key software and frameworks such as <a href="https://wordpress.org">WordPress</a>, <a href="https://laravel.com">Laravel</a>,and <a href="https://symfony.com">Symfony</a>.</p>



<p>FrankenPHP offers a host of new features that allow to:</p>



<ul class="wp-block-list">
<li>simplify the development of applications written in PHP;</li>



<li>drastically improve performance, while considerably reducing hosting costs (FinOps) and energy consumption (GreenOps);</li>



<li>facilitate deployment in production, whether on bare-metal servers or in cloud-native environments;</li>



<li>easily develop real-time features thanks to native <a href="https://mercure.rocks">Mercure</a> protocol support;</li>



<li>extend PHP apps with Go, C, and C++ programming languages;</li>



<li>support the PHP programming language in any application written in Go (server, proxy, in-house development&#8230;).</li>
</ul>



<p>Specifically, FrankenPHP integrates the official PHP interpreter as a module for Go and <a href="https://caddyserver.com">Caddy</a>, the popular next-generation web server that supports the latest web platform innovations in terms of performance, security, and DevOps: HTTP/3, compression with Zstandard, 103 Early Hints, automatic generation and renewal of HTTPS certificates, Encrypted Client Hello, structured logs, OpenMetrics/Prometheus metrics… Caddy is also co-maintained by Kévin and sponsored by Les-Tilleuls.coop.</p>



<p>Thanks to its innovative architecture, FrankenPHP lets you install a complete PHP environment (interpreter, web server, extensions, etc.) optimized for performance and security, by downloading a standalone statically compiled executable or a Docker image.</p>



<p>FrankenPHP also offers a performance-optimized mode called “worker mode”, which takes advantage of the capabilities of the Go programming language. When this optional mode is used, the PHP application will be able to retain in memory those elements that can be reused to process other HTTP requests instead of being completely reset to process each incoming HTTP request (“share nothing” model). Worker mode is especially useful for frameworks such as Symfony and Laravel that can prevent rebuilding their kernels and services again and again for nothing.</p>



<p>Using this mode requires minimal adaptations to the code of modern PHP applications in line with good programming practice. The Laravel, Symfony and Yii frameworks already offer official integrations of FrankenPHP&#8217;s worker mode, enabling worker mode to be activated without modifying the application code.</p>



<p>According to <a href="https://sylius.com/blog/ecosystem/month-of-sylius-august-2024/#frankenphp">an analysis carried out this summer by Sylius</a>, the publisher of the eponymous e-commerce platform, the use of FrankenPHP&#8217;s worker mode reduces the software&#8217;s response times by 80%, while reducing by more than 6 the number of machines required to serve the same number of users.</p>



<p>FrankenPHP is now a reliable, mature solution used in production for an ever-increasing number of projects. The project now has <a href="https://github.com/dunglas/frankenphp">almost 8,000 stars on GitHub</a>, has passed the symbolic 100-contributor mark, and is officially supported by numerous hosting providers, including Upsun, Laravel Cloud, and Clever Cloud.</p>



<p>To get to this point, it was necessary to initiate close collaboration between the development teams of FrankenPHP, the PHP interpreter itself, the Caddy web server, and even the Go programming language.</p>



<p>Today, we&#8217;re proud to announce that, with the aim of intensifying this collaboration, enabling the project to gain momentum, and modernizing the entire PHP ecosystem, <strong>the FrankenPHP project is now officially supported by the PHP Foundation</strong>.</p>



<p>In concrete terms, FrankenPHP&#8217;s source code will be transferred to the PHP project&#8217;s GitHub organization, and the PHP Foundation team will contribute to the maintenance and development of FrankenPHP to ensure its reliability, durability, and compatibility with the latest language innovations.</p>



<p>Part of the FrankenPHP documentation will also be transferred to the PHP website.</p>



<p>The governance of the project remains unchanged, and the current team of maintainers (Kévin Dunglas, Robert Landers, Alexander Stecher) will continue to be in charge of releases, as well as code reviews. They will be actively collaborating with the PHP Foundation team in charge of the language development.</p>



<p>In addition to the support provided by the foundation, Les-Tilleuls.coop will continue to sponsor FrankenPHP (as well as PHP and Caddy) by providing developers and contributing financially.</p>



<p>FrankenPHP is already <a href="https://caddyserver.com/#:~:text=4x%20faster%20PHP%20apps">promoted by Caddy</a> as the official, modern solution for using PHP with this server.</p>



<p>In the future, to simplify the PHP development experience (one-line installation of a complete development environment) and to promote a solution that, for projects requiring it, considerably improves the performance and efficiency of PHP applications, FrankenPHP may be highlighted on the PHP website as one of the ways to use the language (other SAPIs such as PHP-FPM will continue to be fully supported solutions).</p>



<p>To find out more about FrankenPHP and the many new possibilities it offers, take a look at <a href="https://frankenphp.dev">its documentation</a>. To meet the software&#8217;s authors and find out how it is used in production, don&#8217;t miss <a href="https://api-platform.com/con/">the API Platform conference</a> (by the same authors as FrankenPHP) taking place on September 18 and 19 in France (Lille).&nbsp;</p>



<p>Also, join us online for <a href="https://lp.jetbrains.com/phpverse-2025/"><strong>PHPverse on June 17</strong></a> — a special event celebrating PHP’s 30th anniversary.</p>



<p>Finally, to help keep the PHP ecosystem innovating, <a href="https://thephp.foundation/sponsor/">support the foundation</a>!</p>



<p><a href="http://les-tilleuls.coop">Les-Tilleuls.coop</a><br><a href="https://thephp.foundation/">The PHP Foundation</a><br><a href="https://caddyserver.com">The Caddy team</a></p>



<p></p>The post <a href="https://dunglas.dev/2025/05/frankenphp-is-now-officially-supported-by-the-php-foundation/">FrankenPHP Is Now Officially Supported by The PHP Foundation</a> first appeared on <a href="https://dunglas.dev">Kévin Dunglas</a>.]]></content:encoded>
					
					<wfw:commentRss>https://dunglas.dev/2025/05/frankenphp-is-now-officially-supported-by-the-php-foundation/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">7447</post-id>	</item>
		<item>
		<title>Develop Faster With FrankenPHP</title>
		<link>https://dunglas.dev/2025/03/develop-faster-with-frankenphp/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=develop-faster-with-frankenphp</link>
					<comments>https://dunglas.dev/2025/03/develop-faster-with-frankenphp/#comments</comments>
		
		<dc:creator><![CDATA[Kévin Dunglas]]></dc:creator>
		<pubDate>Fri, 28 Mar 2025 15:42:27 +0000</pubDate>
				<category><![CDATA[FrankenPHP]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[SymfonyLive]]></category>
		<guid isPermaLink="false">https://dunglas.dev/?p=7440</guid>

					<description><![CDATA[<p>One of Symfony&#8217;s strengths is its caching mechanism (the files stored in &#8220;var/cache&#8221;), which enables framework components such as the dependency injection container and the router, as well as numerous bundles, to be ultra-fast in production. However, during development, regeneration of this cache can cause slowness and make the work of programmers tedious. Each time...</p>
The post <a href="https://dunglas.dev/2025/03/develop-faster-with-frankenphp/">Develop Faster With FrankenPHP</a> first appeared on <a href="https://dunglas.dev">Kévin Dunglas</a>.]]></description>
										<content:encoded><![CDATA[<figure class="wp-block-embed is-type-rich is-provider-speaker-deck wp-block-embed-speaker-deck wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="Develop Faster With FrankenPHP" id="talk_frame_1347515" class="speakerdeck-iframe" src="//speakerdeck.com/player/523245fe753748c48dc3b5d71827ec15" width="640" height="360" style="aspect-ratio:640/360; border:0; padding:0; margin:0; background:transparent;" frameborder="0" allowtransparency="true" allowfullscreen="allowfullscreen"></iframe>
</div></figure>



<p>One of Symfony&#8217;s strengths is its caching mechanism (the files stored in &#8220;var/cache&#8221;), which enables framework components such as the dependency injection container and the router, as well as numerous bundles, to be ultra-fast in production.</p>



<p>However, during development, regeneration of this cache can cause slowness and make the work of programmers tedious. Each time a PHP file, configuration file or Twig template is modified, all or part of the cache must be regenerated.</p>



<p>The latest version of FrankenPHP contains a new feature which, coupled with worker mode, can change all that: watchers.</p>



<p>After presenting how Symfony&#8217;s caching mechanism works, and how to take advantage of it in our applications and bundles, we&#8217;ll discover how to use watchers and FrankenPHP&#8217;s worker mode to ensure that changes made to our code are reflected almost instantaneously in our browser, and thus avoid the frustration of long loading times in dev.</p>



<p>I gave this presentation at <a href="https://live.symfony.com/2025-paris/schedule/developper-plus-vite-grace-a-frankenphp" title="">SymfonyLive Paris 2025</a>.</p>The post <a href="https://dunglas.dev/2025/03/develop-faster-with-frankenphp/">Develop Faster With FrankenPHP</a> first appeared on <a href="https://dunglas.dev">Kévin Dunglas</a>.]]></content:encoded>
					
					<wfw:commentRss>https://dunglas.dev/2025/03/develop-faster-with-frankenphp/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">7440</post-id>	</item>
		<item>
		<title>HTTP compression in PHP (new Symfony AssetMapper feature)</title>
		<link>https://dunglas.dev/2024/12/http-compression-in-php-new-symfony-assetmapper-feature/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=http-compression-in-php-new-symfony-assetmapper-feature</link>
					<comments>https://dunglas.dev/2024/12/http-compression-in-php-new-symfony-assetmapper-feature/#respond</comments>
		
		<dc:creator><![CDATA[Kévin Dunglas]]></dc:creator>
		<pubDate>Thu, 05 Dec 2024 15:59:01 +0000</pubDate>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Caddy]]></category>
		<category><![CDATA[compression]]></category>
		<category><![CDATA[FrankenPHP]]></category>
		<guid isPermaLink="false">https://dunglas.dev/?p=7430</guid>

					<description><![CDATA[<p>Compressing HTTP responses can significantly improve the performance of your PHP and Symfony applications. But you must still navigate the jungle of standards and formats. In this presentation, we&#8217;ll discover how HTTP compression works, the different formats supported by modern web browsers (deflate, gzip, Brotli, and the brand-new Zstandard), and how to use them correctly....</p>
The post <a href="https://dunglas.dev/2024/12/http-compression-in-php-new-symfony-assetmapper-feature/">HTTP compression in PHP (new Symfony AssetMapper feature)</a> first appeared on <a href="https://dunglas.dev">Kévin Dunglas</a>.]]></description>
										<content:encoded><![CDATA[<figure class="wp-block-embed is-type-rich is-provider-speaker-deck wp-block-embed-speaker-deck wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title=" HTTP compression in PHP and Symfony apps" id="talk_frame_1290224" class="speakerdeck-iframe" src="//speakerdeck.com/player/834eb81b601d4527bab3093402c75ba1" width="640" height="360" style="aspect-ratio:640/360; border:0; padding:0; margin:0; background:transparent;" frameborder="0" allowtransparency="true" allowfullscreen="allowfullscreen"></iframe>
</div></figure>



<p>Compressing HTTP responses can significantly improve the performance of your PHP and Symfony applications. But you must still navigate the jungle of standards and formats.</p>



<p>In this presentation, we&#8217;ll discover how HTTP compression works, the different formats supported by modern web browsers (deflate, gzip, Brotli, and the brand-new Zstandard), and how to use them correctly.</p>



<p>We&#8217;ll also look at which formats to compress, which not to, when to use dynamic compression, and when (and how) to pre-compress responses that can be compressed for even better performance.</p>



<p>After that, I&#8217;ll introduce <a href="https://github.com/symfony/symfony/pull/59020" title="">a new feature I just added to the Symfony AssetMapper component</a>: pre-compression.</p>The post <a href="https://dunglas.dev/2024/12/http-compression-in-php-new-symfony-assetmapper-feature/">HTTP compression in PHP (new Symfony AssetMapper feature)</a> first appeared on <a href="https://dunglas.dev">Kévin Dunglas</a>.]]></content:encoded>
					
					<wfw:commentRss>https://dunglas.dev/2024/12/http-compression-in-php-new-symfony-assetmapper-feature/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">7430</post-id>	</item>
	</channel>
</rss>
