mirror of
https://github.com/fosrl/pangolin.git
synced 2026-07-16 06:08:33 -05:00
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/fosrl/pangolin/pull/3267
Author: @Josh-Voyles
Created: 6/13/2026
Status: 🔄 Open
Base:
dev← Head:memfix1-1.18.4📝 Commits (2)
d94af2bfix(sqlite): remove cache_size and mmap_size PRAGMAs (#2120)522ca67fix: remove no-op autoFinalizeStatement wrapper and redundant busy_timeout (#2120)📊 Changes
1 file changed (+12 additions, -50 deletions)
View changed files
📝
server/db/sqlite/driver.ts(+12 -50)📄 Description
Community Contribution License Agreement
By creating this pull request, I grant the project maintainers an unlimited,
perpetual license to use, modify, and redistribute these contributions under any terms they
choose, including both the AGPLv3 and the Fossorial Commercial license terms. I
represent that I have the right to grant this license for all contributed content.
Description
Preface
I'm a cloud engineer with experience in Python and Bash; I do not have much experience with JS/TS. This is a follow-up to my previous #2120 fix. After 3 days of A/B testing in production on a t3a.micro with Claude, the previous fix turned out to be net-negative on small instances. This PR reverts those specific changes after empirical validation. No code or comments are left over from the previous attempt.
Summary
autoFinalizeStatementprepare()wrapper. better-sqlite3 11.x exposes noStatement.finalize()— the wrapper threw aTypeErroron every query (silently swallowed by its owntry/catch) and freed nothing, while adding +122% per-statement overhead.busy_timeout = 5000PRAGMA. better-sqlite3 already armssqlite3_busy_timeout(db, 5000)via its defaulttimeoutconstructor option, so the pragma is redundant.cache_size = -65536(64 MB) andmmap_size = 268435456(256 MB) PRAGMAs. On small (~1 GB) instances they inflate RSS and cause page-cache thrashing — the exact shape that hits #2120.journal_mode = WAL+synchronous = NORMALwhenENABLE_SQLITE_WAL_MODE=true).journal_modeis sticky in the DB file, so removing the block would strand databases that opted in.Context
The previous fix assumed unbounded native
sqlite3_stmtaccumulation was the cause of #2120 and added a finalize-on-execute wrapper plus aggressive PRAGMA tuning. Re-investigation showed:Statement.finalize()does not exist on better-sqlite3 11.x. Verified by loggingStatement.finalize exists: undefinedfrom the runner image — the wrapper's call landed in itscatchblock on every execution.sqlite3_stmtin the Statement destructor at GC, so statements cannot accumulate.With
ENABLE_SQLITE_WAL_MODEunset, the driver is now runtime-identical to pre-1.18.3.Changes
server/db/sqlite/driver.ts— removeautoFinalizeStatementwrapper, removebusy_timeout/cache_size/mmap_sizePRAGMAs, keep env-gated WAL block.Verification
Ran the wrapper-OFF build for 3 days on a t3a.micro (1 GB / 2 vCPU) with the same traffic profile as the prior wrapper-ON deployment (normal usage, 7 day request retention, Uptime Kuma checks). Container memory stable around ~335 MB with no PRAGMA tuning. No memory growth, no event-loop stalls, no OOM. No memory limits set in compose file.
Recommendation for small instances
Even with this fix, 1 GB of RAM is tight when host OS tasks spike alongside Pangolin's working set. I'd recommend enabling swap on instances at or below 1 GB — I added 1 GB of swap and it has been more than enough; less is likely fine. Without swap, transient OS pressure has nowhere to go and can OOM the Node process even when Pangolin itself is steady.
How to test?
Build docker container community version using sqlite database.
1GB 2vCPU AWS t3a.micro instance.
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.