fix: Respect container memory and CPU limits from cgroups - #2128
fix: Respect container memory and CPU limits from cgroups#2128Mantisus wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR makes Crawlee’s CPU and memory metrics container-aware on Linux by reading cgroup v1/v2 limits/usage (instead of relying solely on host-wide /proc/meminfo / psutil), so the autoscaler sizes budgets and CPU utilization against the resources actually available to the running process.
Changes:
- Add a new cgroup discovery + metrics reader (
src/crawlee/_utils/cgroup.py) that resolves controllers via/proc/self/mountinfo+/proc/self/cgroupand reads the tightest applicable limits. - Update
get_memory_info()/get_cpu_info()to prefer cgroup-scoped totals/usage when limits apply, falling back to host metrics otherwise. - Add comprehensive unit tests with a fake cgroup filesystem, and document autoscaling behavior under resource limits.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| tests/unit/_utils/test_cgroup.py | Adds unit tests covering cgroup v1/v2 discovery and limit/usage semantics, plus system.py integration behavior. |
| src/crawlee/_utils/system.py | Switches CPU/memory “system-wide” metrics to cgroup-aware readings when applicable; keeps host fallbacks. |
| src/crawlee/_utils/cgroup.py | Implements cgroup controller discovery and reads memory/cpu limits + usage from the most relevant hierarchy levels. |
| docs/guides/scaling_crawlers.mdx | Documents how autoscaling respects cgroup CPU/memory limits when running under container/systemd constraints. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
If I am correct, all the tests run against a fake cgroup filesystem. Is there a way to cover this end-to-end? e.g., running a crawler in a container with |
Description
get_memory_infoandget_cpu_inforeported the host machine even when the crawler ran under a container limit, because/proc/meminfois not namespaced. The autoscaler sized its budget from host RAM and kept scaling until the container got killed, and a container pinned to two cores read the load of the whole machine as idle. Both now come from the cgroup of the process, with nothing to configure.Two decisions worth a look:
/proc/self/mountinfoand/proc/self/cgroupinstead of assuming/sys/fs/cgroup, which is what makes this work under--cgroupns=host.Without a limit, and outside Linux, the host values are used as before. A crawler in a container whose limit is below the host RAM now gets a smaller
max_memory_size, so its concurrency drops.Issues
Testing