Re: [Pre-RFC] Deprecating NTS and making ZTS the default build mode

From: Date: Sat, 11 Jul 2026 21:08:51 +0000
Subject: Re: [Pre-RFC] Deprecating NTS and making ZTS the default build mode
References: 1  Groups: php.internals 
Request: Send a blank email to internals+get-131873@lists.php.net to get a copy of this message
At work, I maintain a PHP distribution on a non-mainstream platform shipping NTS. No real reason other than that's the way we've always built it; there's no urgency to switch since 99.9% of the users aren't using threaded SAPIs. I can try ZTS builds and see what (or really if it) breaks down for me. FWIW as an RM, we run the basic tests for a release in both NTS and ZTS, so any low-hanging fruit with CLI/CGI should be caught at least. > On Jul 11, 2026, at 12:52 PM, Marc Henderkes <m@pyc.ac> wrote: > > Hi internals, > > > > > > > > Before I sit down and write a full RFC, I'd like to get a feel for where people stand on > something I've been working toward for a while: deprecating not passing --enable-zts, and > removing the NTS mode entirely in the next major version. > First a very important clarification: I’m not looking to deprecate the way FPM or other > process managers work. All the existing NTS functionality, including hard timeouts (which do not yet > have ZTS equivalent) can keep working in a single threaded ZTS run. > > The reasons, listed by importance: > 1. the current split introduces a lot of unnecessary builds and poor availability (especially > for FrankenPHP and other emerging projects that require thread safety): > OS distributions generally only package NTS > Remi used to ship cli-only ZTS php, but stopped because it meant twice the maintenance. > Ondrej doesn’t want to take on ZTS builds because NTS is the default, again citing twice the > work > Shivam’s Homebrew does ship both NTS and ZTS, but only extensions for NTS. PIE exists, but > extension providers suffer from the same problems: most either don’t do prebuilt binaries at all > or only do NTS. > I ship ZTS packages only because there’s no other availability for them. In order not to > conflict with users’ regular system packages and their dependencies, I build everything into a > different name. > php-src’s GitHub CI would shrink significantly by getting rid of NTS > Most users don’t even know that a ZTS build with ext-parallel capabilities exists, if they > do, it mostly just confuses them on which to get > Tl;dr: nobody wants to maintain two builds and even having a necessary split is making things > hard. > 2. maintenance cost in php-src itself: ~420 #ifdef ZTS results and ~30 for #ifndef ZTS from a > quick search. > 3. NTS as the default disincentivises any first-class threading story > 4. there’s no significant advantage NTS has. It gets rid of a tiny bit of mutex locking or > per-thread copying, but most of the other cost doesn’t have to exist. Worst case performance cost > of ZTS in php 8.5 was ~5%, will be ~1.5% in php 8.6, likely ~0.5% after my last open PRs. This > doesn’t have to stay the case - the last bits of performance penalty could be resolved if we > convince the compiler to stop rederiving TLS addresses after function calls. > > Generally, no large code changes are needed. Removing a lot of duplication in php-src is good. > > Potential blockers > The JIT doesn’t work for ZTS builds on arm64 macOS. > Thread unsafe extensions like ext-imap will continue working in the single-threaded execution > of fpm. The only extension I’m aware of that doesn’t support ZTS builds at all currently is new > relics. > > ZTS jit on arm64 macOS is the only part I couldn’t do myself (don’t have arm64 apple > silicon at hand). Everything else I would implement myself. > > I think it would really benefit the health of php distributions and evolution in the future. > Given the small change surface for extension or build providers, and users, I would like to land the > removal in PHP 9.0. > Best regards, > Marc Henderkes

« previous php.internals (#131873) next »