Answer
For a predictable low‑traffic, single‑instance Node.js application that uses Passport.js, the most balanced choice is a file‑based SQLite session store. It adds persistence across process restarts without any external server, keeps the implementation simple, and is cheaper than a dedicated Redis or cloud database.
Confirmed facts
- Passport.js relies on
express-session for session handling; the store is independent of Passport itself.
- The default
MemoryStore in express-session is volatile and loses all sessions on process restart or crash.
- Using SQLite via
connect-sqlite3 (or session-file-store) creates a local .sqlite file that survives restarts and is suitable for single‑process workloads.
- Stateless JWTs remove server‑side storage but require token revocation logic and expose the entire session payload to the client.
- Shared stores such as Redis are required only when the application runs in multiple processes or behind a load balancer; they add cost and operational overhead.
Likely explanation and trade‑offs
Low‑traffic workloads rarely saturate I/O, so the minimal overhead of file writes in SQLite is acceptable. The SQLite store serializes writes via file locking, which can become a bottleneck only if traffic spikes unexpectedly. Storing the database on an unreliable network mount can risk corruption; keeping it on local storage mitigates this risk.
JWTs are attractive for truly stateless architectures, but the need for revocation tables or short lifetimes increases complexity for a simple low‑traffic app. Unless the application must support massive horizontal scaling or strict statelessness, the added effort is not justified.
Steps for this case
- Install the SQLite session store adapter and express‑session:
npm install express-session connect-sqlite3
- Configure the store in your Express setup:
const session = require('express-session');
const SQLiteStore = require('connect-sqlite3')(session);
app.use(session({
store: new SQLiteStore({ db: 'sessions.sqlite', dir: './data' }),
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
cookie: { httpOnly: true, sameSite: 'lax' }
}));
- Ensure the
./data directory is writable by the application process and back it up as part of your deployment pipeline.
- Verify persistence: create a session, restart the Node process, and confirm the user remains authenticated.
Diagnostic question
Is your deployment already using multiple processes or a load balancer that would require a shared session store? If so, a central store like Redis would be the safer choice.