{ "module": "memory-pressure", "version": "1", "capabilities": [ "package-manager", "service-manager" ], "emits": [ "pressure.high", "pressure.cleared" ], "tools": [ "memory_status", "memory_top", "memory_oom_history", "memory_zram", "memory_oomd", "memory_guard" ], "resources": [ { "id": "zram-generator", "type": "package", "package": "zram-generator" }, { "id": "zram", "type": "file", "path": "/etc/systemd/zram-generator.conf", "mode": "0644", "content": "# Managed by the mesh (module memory-pressure). Replaced on every push; edit the catalogue instead.\n#\n# Compressed swap in RAM: fast, at a higher priority than any swap on disk, so it takes the everyday\n# pressure before anything spills to a disk. Half the RAM, at most 16 GiB, compressed with zstd.\n# The swap on disk, its size and whether one exists at all are the machine's, not this module's.\n#\n# Read by the generator at boot: a change applies at the next boot.\n[zram0]\nzram-size = min(ram / 2, 16384)\ncompression-algorithm = zstd\nswap-priority = 100\n" }, { "id": "sysctl-drop-ins", "type": "directory", "path": "/etc/sysctl.d", "mode": "0755" }, { "id": "swap-tunables", "type": "file", "path": "/etc/sysctl.d/90-memory-pressure.conf", "mode": "0644", "content": "# Managed by the mesh (module memory-pressure). Replaced on every push; edit the catalogue instead.\n#\n# Swap-in reads one page, not eight: read-ahead exists to amortise a disk's seek, and compressed swap in\n# RAM has none — the speculation only costs decompression and memory.\nvm.page-cluster = 0\n#\n# vm.swappiness is deliberately left alone. The usual zram advice (150-180) holds only while the\n# compressed swap has room; once it is full, a higher swappiness moves pages to the disk swap, the thing\n# being avoided. Raise it only together with zram-size.\n" }, { "id": "sysctl", "type": "service", "unit": "systemd-sysctl.service", "restart-on": [ "swap-tunables" ] }, { "id": "oomd-drop-ins", "type": "directory", "path": "/etc/systemd/oomd.conf.d", "mode": "0755" }, { "id": "oomd-limits", "type": "file", "path": "/etc/systemd/oomd.conf.d/memory-pressure.conf", "mode": "0644", "content": "# Managed by the mesh (module memory-pressure). Replaced on every push; edit the catalogue instead.\n#\n# systemd-oomd kills the worst unit before the kernel's OOM killer freezes the machine: when swap is\n# 90 % used, or when a watched unit stalls on memory for 20 s above its limit.\n[OOM]\nSwapUsedLimit=90%\nDefaultMemoryPressureLimit=60%\nDefaultMemoryPressureDurationSec=20s\n" }, { "id": "root-slice-drop-ins", "type": "directory", "path": "/etc/systemd/system/-.slice.d", "mode": "0755" }, { "id": "root-slice", "type": "file", "path": "/etc/systemd/system/-.slice.d/10-oomd.conf", "mode": "0644", "content": "# Managed by the mesh (module memory-pressure). Replaced on every push; edit the catalogue instead.\n#\n# systemd-oomd may act on swap exhaustion across the whole machine.\n[Slice]\nManagedOOMSwap=kill\n" }, { "id": "user-manager-drop-ins", "type": "directory", "path": "/etc/systemd/system/user@.service.d", "mode": "0755" }, { "id": "user-manager", "type": "file", "path": "/etc/systemd/system/user@.service.d/10-oomd.conf", "mode": "0644", "content": "# Managed by the mesh (module memory-pressure). Replaced on every push; edit the catalogue instead.\n#\n# systemd-oomd may kill the worst unit in a person's service manager when its memory pressure stays\n# above 80 % — instead of the kernel freezing the machine.\n[Service]\nManagedOOMMemoryPressure=kill\nManagedOOMMemoryPressureLimit=80%\n" }, { "id": "oomd", "type": "service", "unit": "systemd-oomd.service", "state": "running", "boot": "enabled", "restart-on": [ "oomd-limits", "root-slice", "user-manager" ] } ], "build": { "artifacts": [ { "name": "tools-go", "kind": "bundle", "language": "go", "system": "arch", "from": "cmd/memory-pressure", "binary": "memory-pressure", "loads": [ "memory-pressure" ] } ] } }