ResourceLimits Type
Resource limits applied at group creation. Most are enforced on the group **as a whole** by its kernel container; `CpuTimeMax` is the deliberate POSIX exception and is applied per spawned process through `RLIMIT_CPU` before exec. Whole-tree enforcement needs a real container — a **Windows Job Object** or a **Linux cgroup v2**. On macOS and the Linux process-group fallback, requesting memory/process/quota/affinity limits fails fast with `ProcessError.ResourceLimit`; CPU-time alone remains available through the per-child rlimit. On Linux the cgroup v2 controllers can only be enabled when this process runs at the real cgroup-v2 hierarchy root (not under a systemd scope, nor in an ordinary container); when they cannot, group creation fails fast for the same reason.
Instance members
| Instance member |
Description
|
|
The CPU cores the tree is pinned to, in ascending order, or `None` when it may run on every core (the default). A fresh list each read, so a caller can never mutate the limit set through it.
|
Full Usage:
this.CpuQuota
Returns: float option
|
CPU quota as a fraction of a single core (`0.5` = half a core, `2.0` = two cores). `None` leaves CPU unbounded. On Windows this is approximate (converted against the host core count).
|
|
Maximum CPU time consumed by the contained run. Windows enforces this for the Job as a whole; POSIX applies `RLIMIT_CPU` independently to each spawned process before it execs.
|
|
The directional disk I/O ceiling for one explicit device/volume, or `None` when no I/O cap is requested. The target and rates are preserved exactly so `ProcessGroup.Options` reflects the full limit set that the backend accepted.
|
Full Usage:
this.MaxProcesses
Returns: int option
|
Maximum number of live processes in the tree. `None` leaves the count unbounded.
|
Full Usage:
this.MemoryMax
Returns: int64 option
|
Maximum total memory for the tree, in bytes. `None` leaves memory unbounded.
|
Full Usage:
this.OomGroupKill
Returns: bool
|
Whether a Linux cgroup v2 OOM event kills the whole contained tree atomically. This is a cgroup-only policy; requesting it on another mechanism is refused with `ProcessError.Unsupported`.
|
|
The Windows Job Object UI restrictions imposed on the tree (`WindowsUiRestrictions.None` — the default — imposes none). Windows-only: any other value fails `ProcessGroup.Create`/ `UpdateLimits` with `ProcessError.Unsupported` off Windows, never a silent drop.
|
|
A copy pinning the whole tree to `cores` — the CPU cores (zero-based logical processor indices) its processes may be scheduled on. The complement of `WithCpuQuota`: the quota bounds *how much* CPU the tree gets, this bounds *which* cores it gets it from, so a noisy child can be kept off the cores a latency-critical workload runs on. The set REPLACES any previous one, like every other dimension here; leave it unset for "every core". Rejected at the builder rather than deep in a native call: a `null` set (`ArgumentNullException`), an empty one (`ArgumentException` — no core to run on could never let anything run, so it is a misconfiguration rather than a limit), a negative index (`ArgumentOutOfRangeException`), and a repeated index (`ArgumentException` — an affinity set is a set, and a repeat is far more likely a typo in a generated list than an intent). The accepted set is stored in ascending order, so `[2; 0]` and `[0; 2]` are the same limit. **Needs a limit-capable mechanism**, like every other cap here: the Windows Job Object's affinity mask (`JOB_OBJECT_LIMIT_AFFINITY`) or the Linux cgroup v2 `cpuset` controller (`cpuset.cpus`). On macOS and the Linux process-group fallback there is no whole-tree primitive to pin with, so the group fails with `ProcessError.ResourceLimit` rather than running everywhere unpinned. Two platform limits are reported the same honest way at apply time rather than guessed at here (the machine that builds the limit set need not be the one it runs on): the Windows mask is a single pointer-sized word covering one processor group, so an index at or beyond its width (64 on x64) has no representation; and every requested core must actually exist on the host and be available to this process.
|
|
A copy with the CPU quota (in cores) set. `cores` must be a finite, strictly positive number — zero, negative, `NaN`, or `PositiveInfinity`/`NegativeInfinity` is rejected (`ArgumentOutOfRangeException`): a non-positive quota could never let anything run, and an infinite one has no meaningful cgroup encoding. Also rejected: a value whose conversion into a cgroup v2 `cpu.max` "quota period" string would overflow `int64` once rounded to microseconds. The shared conversion validates this before a `ProcessGroup` is even created, rather than only surfacing later and only on the Linux backend.
|
|
A copy limiting CPU time. `duration` must be finite and strictly positive. POSIX rounds the soft `RLIMIT_CPU` up to whole seconds and gives the hard limit one additional second so the process can observe `SIGXCPU`; Windows uses the Job Object's 100-nanosecond tick precision.
|
Full Usage:
this.WithIoMax
Parameters:
string
readBytesPerSecond : int64
writeBytesPerSecond : int64
readOperationsPerSecond : int64
writeOperationsPerSecond : int64
Returns: ResourceLimits
|
Convenience overload for callers that use zero as the unbounded sentinel. Positive values set a ceiling; zero removes that directional ceiling. Negative values are rejected.
|
Full Usage:
this.WithIoMax
Parameters:
string
readBytesPerSecond : int64 option
writeBytesPerSecond : int64 option
readOperationsPerSecond : int64 option
writeOperationsPerSecond : int64 option
Returns: ResourceLimits
|
A copy applying directional disk I/O ceilings to one explicit device or volume. `target` is a Linux cgroup v2 `major:minor` key or a Windows NT volume device name. A `None` rate leaves that direction unbounded; at least one rate must be supplied. `Some` rates must be positive. Linux can enforce all four directions independently. Windows has one aggregate bandwidth and one aggregate IOPS field, so it accepts the request only when read/write pairs are equal.
|
|
A copy with the live-process cap set. `count` must be positive — zero or negative is rejected (`ArgumentOutOfRangeException`): the tree always has at least its own leader process, so a non-positive cap could never be satisfied.
|
|
A copy with the memory cap set. `bytes` must be positive — zero or negative is rejected (`ArgumentOutOfRangeException`): a non-positive cap could never let anything run, so it is a misconfiguration rather than a meaningful limit, and previously degraded silently (e.g. a negative value converting to a huge `unativeint` on Windows — effectively "unlimited").
|
|
A copy that asks Linux cgroup v2 to treat the cgroup as one OOM unit (`memory.oom.group=1`), so the kernel kills the whole tree instead of selecting one victim. Unsupported outside cgroup v2.
|
Full Usage:
this.WithUiRestrictions
Parameters:
WindowsUiRestrictions
Returns: ResourceLimits
|
A copy imposing the given Windows Job Object UI restrictions on the whole tree (see `WindowsUiRestrictions`). `WindowsUiRestrictions.None` clears them again — the set REPLACES the one in force, like every other dimension here. A value carrying bits outside the defined set is rejected (`ArgumentOutOfRangeException`): those bits have no meaning to `SetInformationJobObject` and would otherwise be written to the Job as an undefined restriction class, which is a misconfiguration rather than a limit. **Windows-only.** Off Windows there is no Job Object (and no analogous primitive on POSIX or cgroup v2), so a group asked for any restriction fails at `ProcessGroup.Create`/`UpdateLimits` with `ProcessError.Unsupported` rather than running unrestricted — the same honest refusal `Command.Uid`/`Setsid`/`Umask` give on Windows.
|
Static members
| Static member |
Description
|
|
No limits — the default.
|
ProcessKit API Reference