Two further wins, both measured on a restored 28-widget board behind a real
demo session (scripts/benchmarks/stress-restore.mts).
--max-semi-space-size=4 in run.sh. --max-old-space-size only bounds the old
generation; V8 also sizes the young generation generously (16 MB per
semi-space) and that slack is pure resident memory. 4 MB cut idle anonymous
memory 120.0 -> 97.2 MiB and peak 710.6 -> 560.2 MiB. It costs CPU, as any
GC-space reduction does — 15.8 -> 17.1 CPU-seconds over the run, ~8% — with
no board-load latency regression (median 594 -> 570 ms). Overridable via
HOMARR_MAX_SEMI_SPACE_SIZE.
serverExternalPackages for the remaining server-only dependencies. Bundling
a package inlines its transitive graph into a chunk that is compiled at boot
even when the code path never runs; leaving it external makes it a lazy
require. Adding winston, drizzle-orm, ical.js, jszip, ldapts, node-unifi,
@kubernetes/client-node and linkedom took idle to 90.3 MiB and board-loaded
209.6 -> 164.6 MiB, with slightly lower CPU (16.3s) and latency (549 ms).
The trade-off is image size: 388 -> 401 MB, because those packages now ship
in node_modules instead of being tree-shaken into chunks.
Cumulative vs the merge-base: idle 141.7 -> 90.3 MiB (-36%), board loaded
257.8 -> 164.6 MiB (-36%), under load 392.7 -> 302.5 MiB (-23%).
The harness now proves the session rather than inferring it: it asserts an
anonymous request to the private board is denied, requires the Auth.js
session cookie after sign-in, and reports whether it had to modify the
restored data at all (now "none"). It also records cgroup CPU seconds and
board-load latency, so a memory win bought with CPU cannot hide.
pnpm test 144/144 files, 1795 tests; typecheck and lint clean.
* fix: rdb files can not be saved because of permission issues bug: redis can not save RDB files #318
* refactor: move db and redis dumps to /appdata directory
* feat: add user groups
* wip: add unit tests
* wip: add more tests and normalized name for creation and update
* test: add unit tests for group router
* fix: type issues, missing mysql schema, rename column creator_id to owner_id
* fix: lint and format issues
* fix: deepsource issues
* fix: forgot to add log message
* fix: build not working
* chore: address pull request feedback
* feat: add mysql migration and fix merge conflicts
* fix: format issue and test issue
* feat: make tasks script run in docker
* feat: make websocket server work in docker
* fix: format issue
* fix: broken lockfile
* fix: non matching typescript versions
* config: add dockerfile
* feat: add working dockerfile for nest and next app with sqlite migration
---------
Co-authored-by: Meier Lukas <meierschlumpf@gmail.com>