You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A compiled Fastify + @perryts/mysql service (gscmaster-api) SIGSEGVs (exit 139, no JS error, PM2 restart) during a long-running background job that performs a large number of sequential await fetch() (HTTPS) interleaved with await mysql execute() in a single async invocation.
This looked like #1597 at first, but it is not that generational-GC bug:
i.e. ~7 awaited HTTPS round-trips per item × 37 ≈ ~260 sequential await fetch() per range, each followed by await execute("INSERT ... ON DUPLICATE KEY UPDATE", ...) writing JSON blobs up to ~15 KB via @perryts/mysql.
Observed boundary: one full range completes and persists all its DB writes; the process crashes near the start of the second range (the next fetch), ~40–43 s in. One range ≈ ~260 fetches + ~230 inserts = OK; two ranges reliably crash. The crash is silent (empty stderr at the crash point; PM2 sees a restart). Reducing the work to a single range avoids it.
This points at a resource that accumulates across many sequential awaited fetch/DB calls and isn't released (sockets/connections, async frames, or similar) rather than a single offending statement — the same token/site/code path works fine for the first ~260 calls and dies on the ~261st.
Compiled Fastify service (plain Fastify), @perryts/mysql (mysql2-compatible) pool connectionLimit: 10, await pool.execute(...).
fetch via the built-in fetchWithAuth / fetchPostWithAuth helpers.
Linux x86_64, run under PM2.
Asks
Is there a known cap / leak on the number of sequential fetch() (or awaited mysql execute()) in one async invocation? Any PERRY_* knob to test (e.g. fetch connection pooling)?
Happy to produce a trimmed standalone repro (loop of N await fetch() to a local server + N inserts) and bisect N — say the word and I'll attach it plus a core dump / PERRY_* trace if useful.
(Originally mis-attributed to #1597 — corrected: that fix and PERRY_GEN_GC=0 both leave this crash in place, so filing separately.)
Summary
A compiled Fastify +
@perryts/mysqlservice (gscmaster-api) SIGSEGVs (exit 139, no JS error, PM2 restart) during a long-running background job that performs a large number of sequentialawait fetch()(HTTPS) interleaved withawaitmysqlexecute()in a single async invocation.This looked like #1597 at first, but it is not that generational-GC bug:
main(includes fix(gc): barrier Promise pointer stores for async resumption #1715fix(gc): barrier Promise pointer stores) → still crashes.PERRY_GEN_GC_EVACUATE=0→ still crashes.PERRY_GEN_GC=0(full mark-sweep, generational GC fully disabled) → still crashes.So the GC fix and both GC-disable workarounds don't help — this is a distinct failure.
Shape of the workload
The job processes three "date ranges". For each range it does, for ~37 items, sequentially:
await fetchPostWithAuth(googleapis.com, ...)(stats)await fetchPostWithAuth(...)(daily)await fetchPostWithAuth(...)(dimensions)i.e. ~7 awaited HTTPS round-trips per item × 37 ≈ ~260 sequential
await fetch()per range, each followed byawait execute("INSERT ... ON DUPLICATE KEY UPDATE", ...)writing JSON blobs up to ~15 KB via@perryts/mysql.Observed boundary: one full range completes and persists all its DB writes; the process crashes near the start of the second range (the next
fetch), ~40–43 s in. One range ≈ ~260 fetches + ~230 inserts = OK; two ranges reliably crash. The crash is silent (empty stderr at the crash point; PM2 sees a restart). Reducing the work to a single range avoids it.This points at a resource that accumulates across many sequential awaited
fetch/DB calls and isn't released (sockets/connections, async frames, or similar) rather than a single offending statement — the same token/site/code path works fine for the first ~260 calls and dies on the ~261st.Environment
PerryTS/perrymain@c720d2a4(rebuilt 2026-05-25; includes fix(gc): barrier Promise pointer stores for async resumption #1715).@perryts/mysql(mysql2-compatible) poolconnectionLimit: 10,await pool.execute(...).fetchvia the built-infetchWithAuth/fetchPostWithAuthhelpers.Asks
fetch()(or awaited mysqlexecute()) in one async invocation? AnyPERRY_*knob to test (e.g. fetch connection pooling)?await fetch()to a local server + N inserts) and bisect N — say the word and I'll attach it plus a core dump /PERRY_*trace if useful.(Originally mis-attributed to #1597 — corrected: that fix and
PERRY_GEN_GC=0both leave this crash in place, so filing separately.)