/
/
/
Ansible role that sets up sane defaults based on a simple host configuration.
1---
2# Kernel tunables that apply to every host in this estate.
3#
4# **`vm.swappiness` is the one that matters, and 60 is wrong for all of these
5# machines.** The Debian/Raspbian default of 60 tells the kernel to page out
6# anonymous memory eagerly, well before there is any real pressure -- it is
7# tuned for spinning disks and a desktop workload, where paging is cheap and
8# reclaiming page cache is expensive.
9#
10# Neither assumption holds here. Every host boots from SD or SSD, where writes
11# are the scarce resource, and the edge nodes have no swap worth using anyway.
12#
13# **Measured 2026-08-30 on hifi-node-dining** (Pi Zero 2 W, 416 MB), sitting
14# idle at ~60% memory use -- so with headroom, not under pressure:
15#
16# 136 MB in swap
17# 42,385 pages swapped OUT in 18 minutes
18# 18,286 pages swapped back IN
19# kswapd0 continuously active
20#
21# That is gratuitous: the kernel was paging while memory was available, which
22# on an SD card is pure wear and I/O stall for no benefit. The sibling node
23# (Pi 3 B+, 906 MB, same software) held 1 MB of swap over five weeks -- the
24# difference being headroom, which the Zero does not have to spare.
25#
26# 10 rather than 0: 0 disables swap almost entirely and turns a transient
27# spike into an OOM kill, which is a worse failure than a slow moment. 10 says
28# "use swap when genuinely short, not as a matter of routine" -- and it is what
29# `runner` was already set to by hand after chronic swap exhaustion killed a
30# post-processing step (see the D&D docs, pitfall #15).
31#
32# **`vfs_cache_pressure` travels with it.** At the default 100 the kernel
33# reclaims dentry/inode cache as readily as page cache; on a machine reading
34# the same small set of files forever, keeping that metadata cached avoids
35# re-reading the card. 50 halves the eagerness.
36
37- name: Apply kernel memory tunables
38 ansible.posix.sysctl:
39 name: "{{ item.key }}"
40 value: "{{ item.value }}"
41 state: present
42 sysctl_file: /etc/sysctl.d/60-system-memory.conf
43 reload: true
44 loop: "{{ system_sysctl_memory | dict2items }}"
45 become: true
46