TL;DR: PHP 8.5 changed ini_set('memory_limit', ...) to throw an ErrorException when the requested value exceeds max_memory_limit. Previously it silently capped. The fix is either to lower your requested limit, configure max_memory_limit at the server level, or suppress the error when the cap is acceptable.
What happened
We upgraded a Laravel application to PHP 8.5 and a long-running Artisan import command immediately started failing with a cryptic error:
ErrorException: Failed to set memory_limit to 4294967296 bytes.
Setting to max_memory_limit instead (currently: 536870912 bytes)
File "app/Console/Commands/ImportDataCommand.php", line 12
ini_set('memory_limit', '4096M');
The command was requesting 4 GB of memory. The server's hard ceiling (max_memory_limit) is 512 MB. On PHP 8.4 that call silently set the limit to 512 MB and kept going. On PHP 8.5 it throws.
The PHP 8.5 change
PHP has two memory-related INI settings:
memory_limit— The per-request limit a script can raise or lower at runtime viaini_set(). Typically set inphp.inior a per-vhost config.max_memory_limit— A hard ceiling added in PHP 8.5. Only changeable at the system level (php.ini, not at runtime). Scripts cannot exceed it.
Before 8.5, setting memory_limit above the OS-level ceiling either worked (no hard enforcement) or was silently clamped. PHP 8.5 introduced max_memory_limit as a formal concept and made the runtime enforce it with an error — because silently ignoring the requested value is surprising and hard to debug.
Note: This is a silent-to-loud change. Code that appeared to work fine on 8.4 — because the limit was quietly capped — will now throw on 8.5 if the cap is exceeded.
The three real fixes
1. Raise max_memory_limit on the server (correct, if you own the server)
If the command genuinely needs 4 GB, the honest fix is to grant it at the system level. Add this to your php.ini or CLI php.ini:
max_memory_limit = 4096M
memory_limit = 4096M
Then remove the ini_set from the command entirely. Runtime limits belong in configuration, not in application code.
2. Pass the limit via the CLI (good for scheduled commands)
If you run the command from a scheduler or cron, set the limit as a CLI flag rather than from inside the script:
php -d memory_limit=4096M artisan import:data
This keeps the application code clean and makes the resource budget visible at the call site — right where your ops team or scheduler can see and change it.
3. Suppress the error and accept the cap (quick, pragmatic)
If the command works fine within the system's 512 MB ceiling, suppress the error with @:
// Requests 4096M, silently accepts the max if lower
@ini_set('memory_limit', '4096M');
Warning: Only use this if you are genuinely okay with whatever the server's ceiling is. If the command actually needs 4 GB and only gets 512 MB, you have suppressed a real warning and set yourself up for an OOM crash later.
4. Use -1 (unlimited)
Passing -1 removes the PHP-level cap entirely and relies on the OS to manage memory. This does not trigger the max_memory_limit check:
ini_set('memory_limit', '-1');
Warning: Unlimited memory is a footgun on shared hosts or containers with soft limits. Use it only for trusted CLI commands on dedicated infrastructure.
What we did
The command runs as a scheduled job on a dedicated server. We moved the memory configuration out of the PHP script and into the cron invocation:
# Scheduler entry (before)
php artisan import:data
# Scheduler entry (after)
php -d memory_limit=4096M artisan import:data
And removed the ini_set from the command's handle() method entirely. The command no longer makes assumptions about its own resource budget — that's the scheduler's job.
How to find this in your own codebase
Before upgrading to PHP 8.5, grep your codebase for runtime memory overrides:
grep -rn "ini_set.*memory_limit" app/ bootstrap/
Any hit that requests more than your server's max_memory_limit will throw. Check what your server's ceiling is with:
php -r "echo ini_get('max_memory_limit');"
If that returns empty or -1, no ceiling is currently configured and you are fine until an admin adds one.
The PHP 8.5 release notes cover this change under the INI settings section. The RFC that introduced max_memory_limit is wiki.php.net/rfc/max_memory_limit.
If this post was enjoyable or useful for you, please share it! If you have comments, questions, or feedback, you can email my personal email. To get new posts, subscribe use the RSS feed.