Hi everyone,
I'm happy to share my first RFC :) It proposes adding a small function
to retrieve the number of available processors; a feature that's
commonly found in other programming languages and one that I believe
would be a useful addition to PHP.
The related PR has already received a bit of early traction, and now
that the RFC is complete, I'm looking forward to your feedback!
RFC: https://wiki.php.net/RFC/num_available_processors
Patch: https://github.com/php/php-src/pull/11137
Best
Daniel
Hi
In my opinion, the return type should not be nullable.
Returning NULL
when the platform (or PHP on that platform) doesn't support getting this information is an anti-pattern.
Instead, availability of the necessary functionality should be checked at configure time and the function should be made conditionally available.
That way, the return type can just be "int".
Kind regards
Niels
Hi
In my opinion, the return type should not be nullable.
ReturningNULL
when the platform (or PHP on that platform) doesn't support getting this information is an anti-pattern.
Instead, availability of the necessary functionality should be checked at configure time and the function should be made conditionally available.
That way, the return type can just be "int".Kind regards
Niels
I’m curious why you say this is an “anti pattern”? I do agree that it should return a number or throw. There are various error conditions it should throw (at least on Linux) so having it throw an exception when there isn’t a way to count any processors makes more sense than returning null.
I also note the patch is using the sysconf method and not checking the error on a negative one result and not properly handling zero. Naturally, this means something might be catastrophically wrong, but it should still throw instead of returning null. It could also be someone patching libc to get around per-core licensing too. I’ve seen the latter more often than the former.
— Rob
Hi
In my opinion, the return type should not be nullable.
ReturningNULL
when the platform (or PHP on that platform) doesn't support getting this information is an anti-pattern.
Instead, availability of the necessary functionality should be checked at configure time and the function should be made conditionally available.
That way, the return type can just be "int".Kind regards
NielsI’m curious why you say this is an “anti pattern”? I do agree that it should return a number or throw.
If you make the function unconditionally available, yet specifying the return type as ?int, then you give the false impression that it can work even if your platform doesn't support it.
Also: IMO new APIs should fail hard with an exception if they can't do their main task, that's our error "channel".
There are various error conditions it should throw (at least on Linux) so having it throw an exception when there isn’t a way to count any processors makes more sense than returning null.
Throwing is indeed preferable.
What are the error conditions on Linux?
It could also be someone patching libc to get around per-core licensing too. I’ve seen the latter more often than the former.
I don't follow.
In any case, if you run a monkey patched libc and you're breaking the consumer expectations of said libc, then you deserve getting it blown up in your face imo.
Kind regards
Niels
Hi
In my opinion, the return type should not be nullable.
ReturningNULL
when the platform (or PHP on that platform) doesn't support getting this information is an anti-pattern.
Instead, availability of the necessary functionality should be checked at configure time and the function should be made conditionally available.
That way, the return type can just be "int".Kind regards
NielsI’m curious why you say this is an “anti pattern”? I do agree that it should return a number or throw.
If you make the function unconditionally available, yet specifying the return type as ?int, then you give the false impression that it can work even if your platform doesn't support it.
Also: IMO new APIs should fail hard with an exception if they can't do their main task, that's our error "channel".
There are various error conditions it should throw (at least on Linux) so having it throw an exception when there isn’t a way to count any processors makes more sense than returning null.
Throwing is indeed preferable.
What are the error conditions on Linux?It could also be someone patching libc to get around per-core licensing too. I’ve seen the latter more often than the former.
I don't follow.
In any case, if you run a monkey patched libc and you're breaking the consumer expectations of said libc, then you deserve getting it blown up in your face imo.Kind regards
Niels
I think we both agree it should blow up.
Error conditions (for Linux) using the current method in the patch are either -1 or 0. -1 is just a possible return for that function which could indicate that the kernel doesn’t have support for that sysconf value or there are infinite cores — you’d have to check errno.
It might also report 0, which technically isn’t an error (hotplugging cpus for instance). It could also just be a bug. This is a fun one: https://github.com/lxc/lxcfs/issues/469
Also, I wouldn’t be surprised to see a container with very small amounts of cpu allocated getting rounded to zero. But in any case, zero should probably be treated as an error IMHO.
— Rob
Hi
In my opinion, the return type should not be nullable.
ReturningNULL
when the platform (or PHP on that platform) doesn't support getting this information is an anti-pattern.
Instead, availability of the necessary functionality should be checked at configure time and the function should be made conditionally available.
That way, the return type can just be "int".Kind regards
NielsI’m curious why you say this is an “anti pattern”? I do agree that it should return a number or throw.
If you make the function unconditionally available, yet specifying the return type as ?int, then you give the false impression that it can work even if your platform doesn't support it.
Also: IMO new APIs should fail hard with an exception if they can't do their main task, that's our error "channel".
There are various error conditions it should throw (at least on Linux) so having it throw an exception when there isn’t a way to count any processors makes more sense than returning null.
Throwing is indeed preferable.
What are the error conditions on Linux?
Are you suggesting that the function itself not be available or that it
throws when you attempt to call it on a system that doesn't support it?
I don't like the idea of the function not being available if the system
doesn't support the functionality. Users would have to call
function_exists()
before using the function, in those cases.
Random thought: if the system doesn't support the functionality, would
it be wrong to respond with a default value of 1 or 0? Presumably, all
systems have at least 1 core (maybe that's a naïve assumption). (I'm not
in favor of this approach—it's just a random thought.)
IMO, it's best to throw an exception when calling the function if the
system doesn't support it.
Cheers,
Ben
Are you suggesting that the function itself not be available or that it throws when you attempt to call it on a system that doesn't support it?
I don't like the idea of the function not being available if the system doesn't support the functionality. Users would have to call
function_exists()
before using the function, in those cases.
This has been the accepted practise for years, if not decades.
If functionality isn't available, the function shouldn't exist. We do the same for posix (such as posix_getrlimit) and DNS related functions.
This also allows for polyfills.
cheers
Derick
Are you suggesting that the function itself not be available or that it throws when you attempt to call it on a system that doesn't support it?
I don't like the idea of the function not being available if the system doesn't support the functionality. Users would have to call
function_exists()
before using the function, in those cases.This has been the accepted practise for years, if not decades.
If functionality isn't available, the function shouldn't exist. We do the same for posix (such as posix_getrlimit) and DNS related functions.
This also allows for polyfills.
cheers
Derick
I see. Carry on, then. :-)
Cheers,
Ben
Hi,
Thanks for all your feedback on the RFC.
I've updated the RFC to incorporate most of your feedback:
https://wiki.php.net/rfc/num_available_processors
- The limitation, that the CPU affinity mask is ignored
- The naming discussion
- Function availability on unsupported platforms
- Return type
How do we continue? ;) I see there are various ideas how to approach it,
is that something you would vote (let's do a or b) on, or how does that
work?
Best
Daniel
Are you suggesting that the function itself not be available or that
it throws when you attempt to call it on a system that doesn't
support it?I don't like the idea of the function not being available if the
system doesn't support the functionality. Users would have to call
function_exists()
before using the function, in those cases.This has been the accepted practise for years, if not decades.
If functionality isn't available, the function shouldn't exist. We do
the same for posix (such as posix_getrlimit) and DNS related
functions.This also allows for polyfills.
cheers
DerickI see. Carry on, then. :-)
Cheers,
Ben
Hi
Am 2025-06-15 19:30, schrieb Daniel Kesselberg:
How do we continue? ;) I see there are various ideas how to approach
it, is that something you would vote (let's do a or b) on, or how does
that work?
Having secondary votes is generally frowned upon for this kind of simple
RFCs. It's mostly used when there are multiple equally-valid choices
(which I don't think is the case here). As the RFC author you are
expected to be the subject-matter expert and should make a decision that
is then voted on, rather than deciding every detail by an individual
vote.
Best regards
Tim Düsterhus
Hi,
Thanks for all your feedback on the RFC.
I've updated the RFC to incorporate most of your feedback:
https://wiki.php.net/rfc/num_available_processors
- The limitation, that the CPU affinity mask is ignored
This is something you need to decide on as the RFC author.
- The naming discussion
I don't care much about this topic, but possibly adding the sys_ prefix makes the most sense to "soft namespace" the function.
- Function availability on unsupported platforms
The function should not be available if it is unsupported,
as this how every other conditionally supported feature is handled.
- Return type
Arguably, this should always return an integer.
Which if my understanding is correct, when you make it conditionally available then it cannot fail.
How do we continue? ;) I see there are various ideas how to approach it,
is that something you would vote (let's do a or b) on, or how does that
work?
Small RFCs should only have a single yes/no vote.
As the RFC author, you can (and should) be opinionated.
Best regards,
Gina P. Banyard
PS: Minor list etiquette remainder, please do not top post, and only keep the relevant things while quoting.
Hello!
On Sun, Jun 15, 2025 at 1:33 PM Daniel Kesselberg
mail@danielkesselberg.de wrote:
Hi,
Thanks for all your feedback on the RFC.
I've updated the RFC to incorporate most of your feedback:
https://wiki.php.net/rfc/num_available_processors
- The limitation, that the CPU affinity mask is ignored
- The naming discussion
I'm curious, is there a reason why you feel that introducing a new
namespace should be under "Future Scope", instead of a part of this
RFC? I expect there would be some bikeshedding over the namespace
name, but there is / will be some bikeshedding around a non-namespaced
name in the first place, so it feels like a good opportunity to
embrace namespaces in the standard library.
I ask this because I've been very slightly interested in introducing a
Curl namespace since the "Throwable Hierarchy Policy for Extensions"
(https://wiki.php.net/rfc/extension_exceptions) RFC and my own
personal "Persistent curl share handle"
(https://wiki.php.net/rfc/curl_share_persistence_improvement) RFC.
How do we continue? ;) I see there are various ideas how to approach it,
is that something you would vote (let's do a or b) on, or how does that
work?
Relating to my above question, if you're open to it, I would be happy
to work with you on your RFC to (a) figure out a good namespace name
and (b) update the RFC to match.
Le samedi 24 mai 2025, 19:42:34 heure d’été d’Europe centrale Niels Dossche a écrit :
In my opinion, the return type should not be nullable.
ReturningNULL
when the platform (or PHP on that platform) doesn't support getting this information is an anti-pattern.
Instead, availability of the necessary functionality should be checked at configure time and the function should be made conditionally available.
That way, the return type can just be "int".
I strongly disagree here, having PHP function not always available is a mess, and forces function_exists checks all over the code. It feels archaic.
I get the idea of throwing instead of returning NULL
for errors, but the idea behind the nullable return is to get this nice thing:
$cpus = num_available_cpus() ?? 1;
If the function throws on error, this gets more convoluted. Maybe it can be replaced by a parameter $defaultNumber and only throw when no default is given?
Regarding the CPUs available for PHP or total number discussion, maybe that justifies the "available" keyword in the name and it returns only those available to PHP, and we add a second function for total number?
Or as some people suggested in the PR, we add a namespaced class with methods for this.
Côme
Hi everyone,
I'm happy to share my first RFC :) It proposes adding a small function
to retrieve the number of available processors; a feature that's
commonly found in other programming languages and one that I believe
would be a useful addition to PHP.The related PR has already received a bit of early traction, and now
that the RFC is complete, I'm looking forward to your feedback!RFC: https://wiki.php.net/RFC/num_available_processors
Patch: https://github.com/php/php-src/pull/11137Best
Daniel
Looks good!
My main question is: what is this actually counting? In the RFC it mentions "available processing units" ... which means, what? What counts as a "processing unit"? Are we talking about CPU Threads/cores; NPU cores; TPM cores; clocks? GPS? GPU? ... a modern computer has many "processing units" for different purposes and workloads. I’m assuming this is CPU Threads, not physical cores? I will refer to CPU Threads as "Logical Cores" so we all don’t get confused since most of us here are programmers and saying "thread" has a different meaning.
Secondly, how is it counting "available"? If I assign PHP to a specific CPU affinity mask (say one logical core), will it return 1, or the total number of logical cores available on my machine? I would expect it to be 1, since PHP only has access to 1, but I can also see the logic in returning the total number.
— Rob
Hi everyone,
I'm happy to share my first RFC :) It proposes adding a small function
to retrieve the number of available processors; a feature that's
commonly found in other programming languages and one that I believe
would be a useful addition to PHP.The related PR has already received a bit of early traction, and now
that the RFC is complete, I'm looking forward to your feedback!RFC: https://wiki.php.net/RFC/num_available_processors
Patch: https://github.com/php/php-src/pull/11137Best
DanielLooks good!
My main question is: what is this actually counting? In the RFC it mentions "available processing units" ... which means, what? What counts as a "processing unit"? Are we talking about CPU Threads/cores; NPU cores; TPM cores; clocks? GPS? GPU? ... a modern computer has many "processing units" for different purposes and workloads. I’m assuming this is CPU Threads, not physical cores? I will refer to CPU Threads as "Logical Cores" so we all don’t get confused since most of us here are programmers and saying "thread" has a different meaning.
Secondly, how is it counting "available"? If I assign PHP to a specific CPU affinity mask (say one logical core), will it return 1, or the total number of logical cores available on my machine? I would expect it to be 1, since PHP only has access to 1, but I can also see the logic in returning the total number.
— Rob
Hi Daniel,
I agree with Rob that "processor" is a bit too ambiguous. I'd use the phrase "cpu_core" instead. Yes, technically that's not entirely accurate when hyper-threading is used, but in most cases it's not trivial to distinguish physical cores from logical cores anyway, and "cpu_cores" provides the most understandable abstraction for the vast majority of use cases: deciding how many parallel processes one should use for optimal use of the CPU.
Also, is it really necessary to add "available" as a disambiguator? In other words: are there future plans to add a function that provides the "total" or "unavailable" number of processors? If not, I'd just drop the "available" part.
Finally, from a quick search in php-src there doesn't seem to be any existing function name that starts with num_
. For the sake of consistency with the existing PHP functions, and similar functionality in other languages, I suggest suffixing the function name with _count
instead.
So, to wrap this all up, I'd like to respectfully propose the following function name instead:
cpu_core_count()
Alwin
Hi everyone,
I'm happy to share my first RFC :) It proposes adding a small function
to retrieve the number of available processors; a feature that's
commonly found in other programming languages and one that I believe
would be a useful addition to PHP.The related PR has already received a bit of early traction, and now
that the RFC is complete, I'm looking forward to your feedback!RFC: https://wiki.php.net/RFC/num_available_processors
Patch: https://github.com/php/php-src/pull/11137Best
DanielLooks good!
My main question is: what is this actually counting? In the RFC it mentions "available processing units" ... which means, what? What counts as a "processing unit"? Are we talking about CPU Threads/cores; NPU cores; TPM cores; clocks? GPS? GPU? ... a modern computer has many "processing units" for different purposes and workloads. I’m assuming this is CPU Threads, not physical cores? I will refer to CPU Threads as "Logical Cores" so we all don’t get confused since most of us here are programmers and saying "thread" has a different meaning.
Secondly, how is it counting "available"? If I assign PHP to a specific CPU affinity mask (say one logical core), will it return 1, or the total number of logical cores available on my machine? I would expect it to be 1, since PHP only has access to 1, but I can also see the logic in returning the total number.
— Rob
Hi Daniel,
I agree with Rob that "processor" is a bit too ambiguous. I'd use the phrase "cpu_core" instead. Yes, technically that's not entirely accurate when hyper-threading is used, but in most cases it's not trivial to distinguish physical cores from logical cores anyway, and "cpu_cores" provides the most understandable abstraction for the vast majority of use cases: deciding how many parallel processes one should use for optimal use of the CPU.
Yes, that is why I was curious as to the method it was using to return the number. Using the sysconf method will just return the total number of available cores. However, in Linux there is also the sched_getaffinity method which returns the total number of cores allocated to the current process (which may be lower). For example, when sharing a webserver and a worker queue on a single system, I may only allocate 1/3 of my cores (via taskset
) to the worker queue, and 1/3 cores to the webserver and the last 1/3 for other tasks (such as a database). This prevents the worker queue from taking over the entire system and slowing down my web requests and database.
If we have 12 cores and I’ve only allocated 4 cores for PHP, I would want this function to tell my worker queue that it only has 4 cores, using the system above — not 12. This probably doesn’t matter too much when this is the only process on the machine. However, in any serious production environment, you want to be able to prevent a run-away process/job from harming other unrelated aspects of the system.
You can also see this behaviour with nproc:
❯ taskset -c 0 nproc
1
❯ nproc
16
— Rob
Hi Rob,
Thanks for your feedback. I've added a note, to the proposal section,
that the cpu affinity mask is currently not considered.
The current patch is rather small. Taking the CPU affinity mask into
account will require a more work and introduces different code paths for
linux, bsd and win.
I agree, it's more correct to take into account and wonder if it's
probably enough to just document for now. What do you think, is that
something that should go into the voting part (take cpu affinity mask
into account)?
RFC: https://wiki.php.net/rfc/num_available_processors
Hi everyone,
I'm happy to share my first RFC :) It proposes adding a small
function
to retrieve the number of available processors; a feature that's
commonly found in other programming languages and one that I believe
would be a useful addition to PHP.The related PR has already received a bit of early traction, and now
that the RFC is complete, I'm looking forward to your feedback!RFC: https://wiki.php.net/RFC/num_available_processors
Patch: https://github.com/php/php-src/pull/11137Best
DanielLooks good!
My main question is: what is this actually counting? In the RFC it
mentions "available processing units" ... which means, what? What
counts as a "processing unit"? Are we talking about CPU
Threads/cores; NPU cores; TPM cores; clocks? GPS? GPU? ... a modern
computer has many "processing units" for different purposes and
workloads. I'm assuming this is CPU Threads, not physical cores? I
will refer to CPU Threads as "Logical Cores" so we all don't get
confused since most of us here are programmers and saying "thread"
has a different meaning.Secondly, how is it counting "available"? If I assign PHP to a
specific CPU affinity mask (say one logical core), will it return 1,
or the total number of logical cores available on my machine? I would
expect it to be 1, since PHP only has access to 1, but I can also see
the logic in returning the total number.-- Rob
Hi Daniel,
I agree with Rob that "processor" is a bit too ambiguous. I'd use the
phrase "cpu_core" instead. Yes, technically that's not entirely
accurate when hyper-threading is used, but in most cases it's not
trivial to distinguish physical cores from logical cores anyway, and
"cpu_cores" provides the most understandable abstraction for the vast
majority of use cases: deciding how many parallel processes one should
use for optimal use of the CPU.Yes, that is why I was curious as to the method it was using to return
the number. Using the sysconf method will just return the total number
of available cores. However, in Linux there is also the
sched_getaffinity method which returns the total number of cores
allocated to the current process (which may be lower). For example,
when sharing a webserver and a worker queue on a single system, I may
only allocate 1/3 of my cores (viataskset
) to the worker queue, and
1/3 cores to the webserver and the last 1/3 for other tasks (such as a
database). This prevents the worker queue from taking over the entire
system and slowing down my web requests and database.If we have 12 cores and I've only allocated 4 cores for PHP, I would
want this function to tell my worker queue that it only has 4 cores,
using the system above -- not 12. This probably doesn't matter too much
when this is the only process on the machine. However, in any serious
production environment, you want to be able to prevent a run-away
process/job from harming other unrelated aspects of the system.You can also see this behaviour with nproc:
❯ taskset -c 0 nproc
1❯ nproc
16-- Rob
Hi
Am 2025-05-25 12:07, schrieb Alwin Garside:
Finally, from a quick search in php-src there doesn't seem to be any
existing function name that starts withnum_
. For the sake of
consistency with the existing PHP functions, and similar functionality
in other languages, I suggest suffixing the function name with_count
instead.So, to wrap this all up, I'd like to respectfully propose the following
function name instead:cpu_core_count()
Naming is a good point indeed and one that I also hinted at with my
comment on the PR:
https://github.com/php/php-src/pull/11137#issuecomment-2888977523
I very strongly disagree with adding more “randomly named” functions to
ext/standard, the times of doing that are over. I would also claim that
it violates the “Coding Standards and Naming Policy”
(https://github.com/php/policies/blob/main/coding-standards-and-naming.rst)
in spirit.
At the very least the function should have a clear “prefix”. sys
as in
sys_getloadavg()
or sys_get_temp_dir()
would probably work.
Alternatively get
as in getmyuid()
or getrusage()
would also work.
As I've indicated in the PR, my preference would be creating a new
namespace and moving over the matching functions together with a
discussion of some namespace structure, including matching exceptions
(see https://wiki.php.net/rfc/extension_exceptions).
Best regards
Tim Düsterhus
Hi everyone,
I'm happy to share my first RFC :) It proposes adding a small function
to retrieve the number of available processors; a feature that's
commonly found in other programming languages and one that I believe
would be a useful addition to PHP.The related PR has already received a bit of early traction, and now
that the RFC is complete, I'm looking forward to your feedback!RFC: https://wiki.php.net/RFC/num_available_processors
Patch: https://github.com/php/php-src/pull/11137Best
Daniel
I don't really have a problem with adding a function to expose this value, in concept. But what is the use case, exactly? The RFC mentions something about php-cs-fixer in passing in half a sentence, but doesn't explain it further. Please explain further what value this has for core, rather than the parallels extension. (In the RFC, not just here on list.)
--Larry Garfield
Hi Larry,
Thanks for your feedback.
I've reworked the introduction at
https://wiki.php.net/rfc/num_available_processors and hopefully the use
case is a bit clearer now.
Best
Daniel
Hi everyone,
I'm happy to share my first RFC :) It proposes adding a small function
to retrieve the number of available processors; a feature that's
commonly found in other programming languages and one that I believe
would be a useful addition to PHP.The related PR has already received a bit of early traction, and now
that the RFC is complete, I'm looking forward to your feedback!RFC: https://wiki.php.net/RFC/num_available_processors
Patch: https://github.com/php/php-src/pull/11137Best
DanielI don't really have a problem with adding a function to expose this
value, in concept. But what is the use case, exactly? The RFC
mentions something about php-cs-fixer in passing in half a sentence,
but doesn't explain it further. Please explain further what value this
has for core, rather than the parallels extension. (In the RFC, not
just here on list.)--Larry Garfield
Hi Larry,
Thanks for your feedback.
I've reworked the introduction at
https://wiki.php.net/rfc/num_available_processors and hopefully the use
case is a bit clearer now.Best
Daniel
It is, thanks.
For the name, I don't like the idea of this being the first num_
function. This feels like a place we want to start a namespace for such system information functions, where we can then name it in a contextually-informed way.
--Larry Garfield