The RAM and Disk usage pages were designs that no code carried out. Both monitors now run beside the CPU one and, like it, record only the start and the end of a sustained high-usage period: - Memory: RAM from /proc/meminfo's MemAvailable - os.freemem() is MemFree, which counts the page cache as used and shows a healthy server as full - and swap, which alone also starts a period. Without /proc/meminfo it uses what Node reports. Settings WEKAN_RAM_* and WEKAN_SWAP_HIGH_PERCENT. - Disk: each filesystem WeKan writes to - the files root, its temp directory for uploads and the snap's data directory - measured once per device, with an episode of its own. WEKAN_DISK_WATCH_PATHS replaces the paths. - Each report has a live line above its rows and a URL (/admin/problems/ram, /admin/problems/disk). The menu and titles use the existing memory-usage and sandstorm-disk-usage keys, which every language translates, and the Summary names the cpu, ram and disk streams. Observe and report only, as designed. The three monitors share one event recorder (server/lib/resourceLog.js) and one intEnv (models/lib/intEnv.js), which three files had each defined. The pure halves are tested without Meteor, and resourceMonitorsWiring checks the wiring and that no copy of either shared piece returns. Thanks to xet7 !
5.8 KiB
RAM-usage monitor and Admin Panel → Problems → Memory Usage
Status: Implemented (2026-10-17) · Owner: xet7 · Files:
server/lib/ramMonitor.js, server/lib/ramLog.js (through the shared
server/lib/resourceLog.js), models/lib/ramHighTracker.js, the ram stream in
models/eventLog.js, Admin Panel → Problems → Memory Usage
(/admin/problems/ram). Tests: tests/ramHighTracker.test.cjs,
tests/resourceMonitorsWiring.test.cjs.
Sibling of the CPU-usage monitor. WeKan and FerretDB on the same machine can use enough RAM (and push the machine into swap) to starve or crash other software — and swapping makes everything slow. This subsystem watches system-wide memory + swap usage and records only the start and end of each sustained high-usage period to an Admin Panel → Problems → RAM usage report, so operators can see when memory pressure began, how bad it got, and when it cleared — without a flood of rows.
1. Requirements
- While WeKan (and FerretDB alongside it) run, watch how much RAM and swap are used.
- Add an Admin Panel → Problems → RAM usage report.
- Log when high usage starts and when high usage ends — only those two rows per episode, so the report never floods.
- Each row records how much RAM and swap were used (used / total and percentages), the peak during the episode, its duration, and what WeKan/FerretDB were doing at the time (the same coarse activity label the CPU monitor uses).
- Best-effort and never throws; a no-op where the numbers are unavailable (e.g. a
sandbox with no
/proc/meminfo).
2. Design
Mirrors the CPU-usage subsystem so the three Problems monitors (CPU, RAM, Disk) share one shape, one event-stream mechanism, and one report template.
Measurement — system-wide, includes FerretDB
server/lib/ramMonitor.js samples on an interval (WEKAN_RAM_SAMPLE_INTERVAL_MS,
default 5s):
- RAM: on Linux,
MemTotalandMemAvailablefrom/proc/meminfo; used RAM% =(total − available) / total × 100.MemAvailablecounts the page cache the kernel can drop as available -os.freemem()(MemFree) does not, and would show a healthy server with a full cache as out of memory. Without/proc/meminfo(not Linux, or an old kernel) the monitor usesos.totalmem()andos.freemem(). Measured at the OS level, so it includes WeKan, FerretDB and every other process — the true "is the machine low on memory" signal. - Swap: on Linux, read
SwapTotalandSwapFreefrom/proc/meminfo; used swap% =(SwapTotal − SwapFree) / SwapTotal × 100. When/proc/meminfois unreadable or there is no swap, swap is reported as unavailable and only RAM drives the episode. (Node'sprocess.memoryUsage()— WeKan's own RSS — is recorded in the detail for context but is not the trigger; the trigger is system-wide.)
Start/end only — models/lib/ramHighTracker.js
A pure, unit-tested state machine (identical shape to cpuHighTracker.js) turns the
sample stream into just two events per episode, with hysteresis to prevent
flapping:
- enter the high state after
WEKAN_RAM_HIGH_SAMPLES(3) consecutive samples at/aboveWEKAN_RAM_HIGH_PERCENT(default 90% RAM used) OR at/aboveWEKAN_SWAP_HIGH_PERCENT(default 25% swap used — any real swapping is already a performance problem); - leave it after
WEKAN_RAM_LOW_SAMPLES(3) consecutive samples with RAM belowWEKAN_RAM_LOW_PERCENT(default 80%) and swap below the swap threshold; - it tracks the peak RAM% and peak swap% seen during the episode for the end row.
Report — Admin Panel → Problems → Memory Usage
Episodes are written to the eventLog collection on the ram stream (a new
securityCategories-style stream alongside cpu), and shown by the existing
eventStreamReport template (paginated, searchable, read-only). Two rows per episode:
- start (
detected):high RAM usage started (>= 90%): RAM 7.4/8.0 GB (92%), swap 0.6/2.0 GB (30%), load …, WeKan: <activity> - end (
remediated):high RAM usage ended after 42s (peak RAM 96%, peak swap 41%, back under 80%): RAM 5.1/8.0 GB (64%), swap 0.1/2.0 GB (5%)
Severity: high when RAM is at ≥ 95% or swap is at/above its threshold when the
period starts, else medium. The end row is info, so it does not count as a new
problem.
Above the rows, a live line shows the current RAM use (percentage and used / total
GB) and swap when the machine has any, refreshed every 5 seconds. The menu entry and
the page title use the existing memory-usage translation, so every language
already has them.
3. Environment variables
| Variable | Default | Meaning |
|---|---|---|
WEKAN_RAM_MONITOR |
true |
Master on/off. |
WEKAN_RAM_SAMPLE_INTERVAL_MS |
5000 |
Sampling interval. |
WEKAN_RAM_HIGH_PERCENT |
90 |
Enter high state at/above this RAM used %. |
WEKAN_RAM_LOW_PERCENT |
80 |
Leave high state below this RAM used %. |
WEKAN_SWAP_HIGH_PERCENT |
25 |
Also enter high state at/above this swap used %. |
WEKAN_RAM_HIGH_SAMPLES |
3 |
Consecutive high samples to enter. |
WEKAN_RAM_LOW_SAMPLES |
3 |
Consecutive low samples to leave. |
4. Notes
- The tracker and the
/proc/meminfoparser are pure functions unit-tested without Meteor, exactly likecpuHighTracker.jsand its tests, so the enter/leave hysteresis and the meminfo parsing (including missing/zero swap) are covered by positive and negative tests. - This is intentionally observe-and-report only: unlike CPU, WeKan cannot safely "free" RAM on demand, so there is no governor here — the value is visibility (a self-describing start→end record) so an operator can size the host or cap concurrency. See CPU-usage for the governed sibling and Disk-usage for the disk sibling.