Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Addition of a max memory limit ini setting #17951

Open
frederikmillingpytlick opened this issue Feb 28, 2025 · 12 comments
Open

Addition of a max memory limit ini setting #17951

frederikmillingpytlick opened this issue Feb 28, 2025 · 12 comments

Comments

@frederikmillingpytlick
Copy link

frederikmillingpytlick commented Feb 28, 2025

Description

I'd like a max_memory_limit (naming?) ini setting to ensure that PHP never raises the memory_limit ini setting higher than a certain point. This setting should not be editable using ini_set. I'd be open to placing the max_memory_limit setting somewhere else.

Example scenario:
Running a PHP application in Kubernetes you'd have set some resource constraints. Let's say you've allocated 256 MB to a pod running the application and set memory_limit to 128 MB in php.ini.

This setup means we'll have 128 MB available in PHP and a buffer of 128 MB for the rest of the pod. (Assuming only one PHP script will be executed simultaneously, since memory_limit is per script)

Now to the issue. PHP has support for changing the memory_limit setting using the ini_set function during runtime.

If the memory_limit is set to a value higher than the total allocated memory in the pod (256 MB in this scenario), then when the pod's memory of 256 MB has been exhausted by PHP, it will be the kernel OOM killer that handles the exhaustion instead of PHP. The OOM killer then sends PHP a SIGKILL signal which causes a non-graceful exit. (Meaning that potential shutdown handler(s) registered using register_shutdown_function() won't get to run)

Suggested behaviour

php.ini:

memory_limit = "128M"
max_memory_limit = "256M"

PHP code:

<?php

echo ini_get('memory_limit'); // Output: 128M

ini_set('memory_limit', '256M');

echo ini_get('memory_limit'); // Output: 256M

ini_set('memory_limit', '512M'); // Maybe this should cause a PHP notice?

echo ini_get('memory_limit'); // Output: 256M

// Attempt at working around by setting max_memory_limit
ini_set('max_memory_limit', '512M'); // Should have no effect. Maybe this should cause a PHP notice/warning/fatal?

ini_set('memory_limit', '512M'); // Maybe this should cause a PHP notice?

echo ini_get('memory_limit'); // Output: 256M
@NattyNarwhal
Copy link
Member

The alternative might be making memory_limit no longer PHP_INI_ALL to prevent it from being set at runtime.

@frederikmillingpytlick
Copy link
Author

The alternative might be making memory_limit no longer PHP_INI_ALL to prevent it from being set at runtime.

@NattyNarwhal that would be a great alternative and probably a lot easier to implement.

The whole idea of changing the memory_limit during runtime is absurd from a DevOps perspective.

@NattyNarwhal
Copy link
Member

It's unusual to me as well; I suspect it might have been locked down with safe mode in the before times, but that's since been long gone.

Making it per-dir/system is trivial, but it might be a breaking change and/or justify an RFC. I'll let others chime in on that (and the history too).

@kocoten1992
Copy link

Changing config at runtime is useful, I tend to keep all config at default and modify it at runtime as I see fit, it save me the trouble of changing config per script..

@frederikmillingpytlick
Copy link
Author

@kocoten1992
I see your point—being able to tweak config at runtime is definitely a time-saver for PHP developers. I often appreciate that flexibility myself. That said, I’m generally wary of runtime config changes as a whole and would prefer a world where they’re more locked down. Still, I’m fine with leaving that debate aside for now.

My concern specifically with memory_limit is that its runtime mutability makes it tough to ensure PHP application stability. Without a ceiling, it’s hard to predict or control resource usage reliably. That’s why I’m suggesting a max_memory_limit setting to cap any runtime changes to memory_limit, giving us a safety net. Alternatively, locking memory_limit to only be set in php.ini could work too—keeping it immutable once the script starts. Thoughts?

@kocoten1992
Copy link

Yes, more lock down would be better in enterprise or hosting service environment. In your case, would add ini_set to disable_functions in php.ini work? I'm a bit worry if there are too much config to begin with..

@frederikmillingpytlick
Copy link
Author

@kocoten1992 Adding ini_set to disable_functions isn’t a solution in my scenario. The application utilizes ini_set extensively for a wide range of settings, making that approach impractical.

That’s why I’m suggesting a max_memory_limit setting. It would maintain the flexibility of ini_set for other configs while capping memory_limit changes at runtime, offering stability without sweeping restrictions. Alternatively, making memory_limit only be able to be set in php.ini (and/or per dir) would also be a solution.

I see your concern that PHP already got a lot of config options. Perhaps you'd be more inclined to the alternative solution of making memory_limit immutable during runtime?

@kocoten1992
Copy link

I understand your problem better now, change config at runtime is fine, except when it come to resource allocation? It could be a new class of problem. You have better chance discuss on php mailing list and propose a solution for your problem (web interface at https://externals.io/).

@iluuu1994
Copy link
Member

The whole idea of changing the memory_limit during runtime is absurd from a DevOps perspective.

It's a valid strategy to keep memory limit as low as possible, and increase it for endpoints that need it (e.g. the ones opening large files). If those endpoints are hidden behind authentication, this can potentially protect you against certain DoS attacks. Locking down memory_limit would break this approach.

Generally, it's your own responsibility to set these values appropriately, whether globally or at runtime. If some vendor code sets it unreasonably high, IMO, this should be fixed on their part.

@bukka
Copy link
Member

bukka commented Mar 3, 2025

Agree we should not lock memory_limit. If anything, it should be a new INI.

@frederikmillingpytlick
Copy link
Author

@iluuu1994 that's why I initially suggested a new INI max_memory_limit to limit changes of memory_limit during runtime. The default could be unlimited to ensure no breaking changes. Am I understanding correctly that you'd be open to that solution?

@iluuu1994
Copy link
Member

Sure, I wouldn't object to an upper limit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants