Resource limits

edit

Limit CPU, memory and processes

var result = await ProcessWrapper.Create("my-app")
    .WithLimits(new ProcessLimits
    {
        CpuPercentage = 50,            // 50% max CPU
        MemoryLimitInBytes = 512L * 1024 * 1024, // 512 MB
        ProcessCountLimit = 20,
    })
    .ExecuteAsync();
ProcessLimits propertyLimit
CpuPercentageThe maximum CPU usage, between 1 and 100
MemoryLimitInBytesThe maximum memory usage, in bytes
ProcessCountLimitThe maximum number of processes in the group: the process and its descendants

WithLimits(ProcessLimits) replaces the limits, and WithLimits(Action<ProcessLimits>) changes the current ones.

The limits are applied with a Job Object on Windows and with a cgroup v2 control group on Linux. Other operating systems, macOS included, throw a PlatformNotSupportedException when a limit is set. An out-of-range value throws an ArgumentOutOfRangeException when the process starts.

The limits are applied once the process is started. On Windows with .NET 11, the process is started suspended and resumed once the limits are applied, so it never runs without them.

Windows Job Objects

WithWindowsJobObject gives access to the JobObject (in the Meziantou.Framework.Win32 namespace) for the settings that ProcessLimits does not cover:

var result = await ProcessWrapper.Create("my-app")
    .WithLimits(limits => limits.MemoryLimitInBytes = 512L * 1024 * 1024)
    .WithWindowsJobObject(job =>
    {
        job.SetLimits(new JobObjectLimits
        {
            Flags = JobObjectLimitFlags.KillOnJobClose,
        });
    })
    .ExecuteAsync();

The callback runs on Windows only. Using WithWindowsJobObject on another operating system throws a PlatformNotSupportedException when the process starts.

Linux control groups

WithLinuxControlGroup gives access to the CGroup2 (in the Meziantou.Framework.Unix.ControlGroups namespace):

var result = await ProcessWrapper.Create("my-app")
    .WithLinuxControlGroup(cgroup =>
    {
        cgroup.SetMemoryHigh(256L * 1024 * 1024);
    })
    .ExecuteAsync();

The callback runs on Linux only. Using WithLinuxControlGroup on another operating system throws a PlatformNotSupportedException when the process starts.