# PHP 8.3 JIT tracing — recurring crash at theme.php:325 (4GB allocation)

**URL:** https://discourse.roots.io/t/php-8-3-jit-tracing-recurring-crash-at-theme-php-325-4gb-allocation/30241
**Category:** trellis
**Created:** 2026-03-18T15:19:04Z
**Posts:** 4

## Post 1 by @dominikkuen — 2026-03-18T15:19:04Z

Dear community,  
I’ve been dealing with a recurring production crash for over a week that takes down the entire site for 1–2 minutes at a time. After extensive debugging I’ve narrowed it down to what appears to be a PHP 8.3 JIT issue, but I’d like to hear if anyone else has encountered this. Here’s what we found:

* * *

Environment

- Trellis (latest), Bedrock, WordPress 6.8.3, PHP 8.3.28
- Ubuntu 24.04, Nginx, 4 vCPUs, 16GB RAM
- No persistent object cache, single site
- ACF Pro 6.6.0 (via private Composer repo)
- vinkla/extended-acf 14.0.0

The crash

All PHP-FPM workers crash simultaneously with:  
PHP Fatal error: Allowed memory size of 536870912 bytes exhausted  
(tried to allocate 4295229440 bytes) in wp-includes/theme.php on line 325  
The allocation size (0x100040000 = 2^32 + 256KB) is always identical.  
Site self-recovers after 1–2 minutes via Monit noticing and restarting PHP-FPM  
Started March 10, escalated to 5 incidents/day by March 17.

What we investigated and ruled out

- wp\_options / autoloaded options: 152 options, 42KB total — not the cause
- ACF options data: Largest option value: 603 bytes — not the cause
- System memory / OOM killer: 15GB available, no OOM events
- Custom filters on template hook: None
- Specific URL trigger: All URLs affected equally during crash
- OPcache shared memory: Healthy during crash — cache not full, no oom\_restarts, plenty of free memory (verified via standalone diagnostic endpoint)

Key finding: standalone PHP works, WordPress doesn’t

We deployed a standalone opcache-diag.php (no WordPress bootstrap, localhost-only) that calls opcache\_get\_status(). During crashes, this endpoint succeeded through PHP-FPM with completely healthy OPcache stats. Only WordPress requests crashed. This ruled out OPcache shared memory corruption.

What we changed

1. Interned strings buffer was exhausted

opcache.interned\_strings\_buffer was set to 8MB (Trellis default). Production had 8 bytes free. Increased to 32MB along with other OPcache settings:

php\_opcache\_interned\_strings\_buffer: 32  
php\_opcache\_memory\_consumption: 256  
php\_opcache\_max\_accelerated\_files: 50000

Crash continued after this change.

1. Disabled JIT

php\_opcache\_jit\_buffer\_size: 0

Crash stopped immediately. The crash was reproducible on demand by visiting ACF options pages (/wp/wp-admin/admin.php?page=global-settings) — not every time, but intermittently. After disabling JIT, no crashes so far.

Staging (same code, 1/2 hardware, minimal traffic) never reproduced the crash

Status: monitoring. It’s been hours, not days. We’re not yet certain JIT is the root cause vs. masking something else.

Related PHP bugs

- php/php-src#16856 — Memory corruption with JIT
- php/php-src#13817 — Segfault with JIT tracing
- php/php-src#15497 — Crash with file\_cache + JIT

Question

Anyone else experienced something like that on PHP 8.3.x with Trellis/Bedrock?

---

## Post 2 by @ben — 2026-03-18T15:32:01Z

Thanks for reporting this! Made a PR to disable JIT by default:

> <https://github.com/roots/trellis/pull/1653>
>
> ## Summary
> 
> - Disable JIT by default (`php_opcache_jit: 'disable'`, `php_opcache…_jit_buffer_size: 0`)
> - Consolidate JIT directives into `10-opcache.ini.j2` (previously split across `10-opcache.ini.j2` and `php-fpm.ini.j2`)
> 
> ## Context
> 
> PHP 8.3's JIT tracing mode has known memory corruption bugs that cause recurring PHP-FPM worker crashes. The crash signature is a consistent ~4GB allocation attempt (`0x100040000`), which is a JIT corruption artifact — not real application memory demand.
> 
> Reported here: https://discourse.roots.io/t/php-8-3-jit-tracing-recurring-crash-at-theme-php-325-4gb-allocation/30241
> 
> Since Trellis defaults to PHP 8.3 with JIT tracing enabled, all sites on default configuration carry this risk. WordPress workloads are overwhelmingly I/O-bound and see negligible real-world performance benefit from JIT, making it a poor tradeoff.
> 
> OPcache bytecode caching remains fully enabled and unaffected.
> 
> ## Re-enabling JIT
> 
> Users who want JIT can opt in via `group_vars`:
> 
> ```yaml
> php_opcache_jit: 'tracing'
> php_opcache_jit_buffer_size: 256M
> ```
> 
> 🤖 Generated with [Claude Code](https://claude.com/claude-code)

---

## Post 3 by @joshf — 2026-03-18T15:59:23Z

Just wanted to drop a note and say thanks for sharing this.

I had issues with a site in a client’s AWS environment, of which we had no access… We could only deploy via trellis through a convoluted series of VPNs and tunnels. Don’t get me started on the back-and-forth required to get it provisioned initially. :person_facepalming:

I was never able to pin it down due to limited log access and the inability to work with the client in general, but you’re describing pretty much exactly what we experienced.

The fact you were able to pinpoint this to JIT is amazing.

---

## Post 4 by @dominikkuen — 2026-03-24T10:24:36Z

**Update — 6 days later, no further incidents**  
Disabling JIT has held up across multiple deploys and varying traffic. No crashes since March 18.  
At this point I’m fairly confident JIT tracing was the root cause.  
Marking this as resolved for now. Will update if anything changes.
