Skip to content

Resource limits

Limits are set by the operator through environment variables and apply to every task. A request cannot raise them. GET /info reports the effective values, so clients can check before sending work.

ResourceDefaultSet withEnforced by
Memory (whole process tree)256 MiBMEMORY_MAXcgroup memory.max; swap is disabled
Processes and threads64PIDS_MAXcgroup pids.max
CPU bandwidthhalf a core (50000 100000)CPU_MAXcgroup cpu.max; the task is throttled, not killed
CPU time5 sCPU_TIME_LIMIT_SECSRLIMIT_CPU per process
Wall time5 sWALL_TIMEOUT_MSSupervisor timer; the whole task cgroup is killed
Output1 MiB per streamOUTPUT_LIMIT_BYTESSupervisor; the task is killed when stdout or stderr exceeds it
File size64 MiBfixedRLIMIT_FSIZE
Open files256fixedRLIMIT_NOFILE
Stack8 MiBfixedRLIMIT_STACK
Core dumpsnonefixedRLIMIT_CORE
LimitDefaultSet with
Steps64MAX_STEPS_PER_REQUEST
Tasks in one parallel step8MAX_PARALLEL_TASKS
Whole request deadline30 sOVERALL_TIMEOUT_MS
Output kept across all tasks16 MiBREQUEST_OUTPUT_LIMIT_BYTES
Request body1 MiBEXECUTE_BODY_LIMIT_BYTES
Workspace /faber128 MiBfixed
/tmp128 MiBfixed

Too many steps or too wide a step is rejected up front with 422 (limits_exceeded); a body over the size limit gets 413.

Deadline. Each step’s wall timeout is clipped to whatever is left of the request deadline. When the deadline passes, the running tasks are killed and the remaining steps are returned with outcome not_started, alongside the results of the steps that did finish. If the request still overruns (a stuck jailer), a hard backstop answers 504 (deadline_exceeded).

Output budget. Output is kept per stream up to OUTPUT_LIMIT_BYTES, and across the request up to REQUEST_OUTPUT_LIMIT_BYTES: later tasks get what is left, then nothing. Truncation is reported in stats.stdout_truncated and stats.stderr_truncated.

MAX_CONCURRENCY (default 10) is the number of task slots: sandboxed tasks that may run at once across all requests. A request reserves one slot per task of its widest step and holds them until its sandbox is gone, even if the client disconnects. A request that does not fit is refused immediately with 503 (capacity_exhausted) and a Retry-After header; Faber does not queue.

Faber’s own cgroup is capped so that every admitted task can reach its own limit at the same time, plus the supervisors’ allowance. Sizing has the formula.

A task that hits a limit is still a normal result with HTTP 200. Look at stats.outcome. When several causes apply, the first row that matches wins:

OutcomeCauseDetails
timed_outWall time exceededThe task cgroup was killed
output_limitstdout or stderr exceeded OUTPUT_LIMIT_BYTESThe task was killed; the truncation flag is set
out_of_memoryThe task’s own memory.maxoom_kill_count > 0
ancestor_out_of_memoryA memory limit above the task (request, service, container or host)Usually means the deployment is undersized
pids_limitpids.max was reached at least oncepids_limit_hit_count > 0. The program may have handled the failed fork and exited normally; check exit_code
policy_violationA denied syscalltermination_signal is 31 (SIGSYS), exit_code 159
signaledKilled by another signal: a crash, abort(), or the CPU time limittermination_signal holds the signal number, exit_code is 128 + signal
exitedThe process exited by itselfexit_code is its status. A non-zero code is still exited
not_startedThe deadline passed, or an earlier step failed with stop_on_failureThe result has error instead of output
infrastructure_failureFaber could not set up the task (for example, working_dir does not exist)The result has error

A cmd that cannot be executed (not found, not executable) is reported as exited with exit code 127 and a line starting with faber: on stderr.

Every result carries stats, measured from the task’s cgroup:

FieldMeaning
memory_peak_bytesPeak memory of the task’s process tree
cpu_usage_usecCPU time used, in microseconds
cpu_nr_throttled, cpu_throttled_usecHow often and how long cpu.max throttled the task
pids_peakMost processes and threads alive at once
execution_time_msWall time from start to exit
oom_kill_count, pids_limit_hit_countLimit events seen by the cgroup
cleanup_succeededWhether the task’s cgroup was removed cleanly

Use cpu_usage_usec rather than execution_time_ms to compare the speed of submissions: wall time depends on throttling and host load.