From dc349a937359130e924867a57fd98ca14d772ddc Mon Sep 17 00:00:00 2001 From: Ole-Morten Duesund Date: Mon, 25 May 2026 17:50:06 +0200 Subject: [PATCH] chore(sessions): schedule periodic expired-session GC gcSessions() existed but only ran on signup. On low-volume instances the sessions table would grow forever as users logged in/out without ever triggering a sweep. Schedule it hourly from server boot via setInterval(...).unref() so it doesn't keep the process alive. Run once on boot too, to clean up whatever accumulated while the previous instance was down. Tests import individual route modules instead of server/index.ts, so this only fires in a real server boot. Surfaced by /audit simplify. Co-Authored-By: Claude Opus 4.7 --- server/index.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/server/index.ts b/server/index.ts index 7f55be5..b3f44c0 100644 --- a/server/index.ts +++ b/server/index.ts @@ -2,6 +2,7 @@ import { Hono } from 'hono'; import { serveStatic } from 'hono/bun'; import { getDb } from './db'; import { authRoutes } from './auth'; +import { gcSessions } from './session'; import { activitiesRoutes } from './activities'; import { tagsRoutes } from './tags'; import { usersRoutes } from './users'; @@ -75,6 +76,15 @@ if (process.env.NODE_ENV === 'production') { const port = parseInt(process.env.PORT ?? '3000', 10); +// Sweep expired sessions periodically so the table doesn't grow without +// bound on instances with low signup volume (signup was previously the only +// trigger). Hourly is plenty — session expiry is at day granularity. Tests +// import individual route modules instead of this file, so the interval +// only fires in a real server boot. +const SESSION_GC_INTERVAL_MS = 60 * 60 * 1000; +gcSessions(); +setInterval(gcSessions, SESSION_GC_INTERVAL_MS).unref(); + export default { port, fetch: app.fetch,