13

I have an application using NodeJS, Express, MongoDB and connect-mongo.

My issue is that sessions don’t seem to be automatically deleted from MongoDB when they expire, so the db size grows until the disk is full.

The developer of connect-mongo wrote a comment:

connect-mongo will ask MongoDB to remove all the sessions that have expired before the current date.

But this doesn’t seem to be happening in my case.

My configuration is:

var express = require('express');
var MongoStore = require('connect-mongo');

var sessionStore = new MongoStore({db: 'myappsession'});

var app = express.createServer();

app.configure(function(){
    app.set('views', __dirname + '/views');
    app.set('view engine', 'ejs');
    app.use(express.bodyParser());
    app.use(express.methodOverride());
    app.use(express.cookieParser());
    app.use(express.session({ secret: "myappsecret", store:sessionStore }));
    app.use(app.router);
    app.use(express.static(__dirname + '/public'));
});

And I’m currently running the following versions:

  • node: 0.7.0-pre
  • connect-mongo: 0.1.7
  • express: 2.5.2
  • connect: 1.8.5
Chenmunka
  • 685
  • 4
  • 21
  • 25
Kevan Stannard
  • 977
  • 7
  • 12

2 Answers2

27

You haven't set a clear_interval for your sessions .. the connect-mongo default is -1 (or "never"):

clear_interval Interval in seconds to clear expired sessions (optional, default: -1). Values <= 0 disable expired session clearing.

Example of removing expired sessions every hour (3600s):

var sessionStore = new MongoStore({
     db: 'myappsession',
     clear_interval: 3600
});

You should also make sure you have set a maxAge on your sessions to they actually expire (eg using 1 day):

app.use(express.session({
    secret: "myappsecret",
    cookie: { maxAge: 24 * 60 * 60 * 1000 },
    store:sessionStore
}));
Stennie
  • 63,885
  • 14
  • 149
  • 175
  • Thanks Stennie, that's a great help. Regarding the maxAge setting, should that be specified in seconds or milliseconds? For example, new Date(Date.now() + 86400) or new Date(Date.now() + 86400 * 1000)? – Kevan Stannard Aug 23 '12 at 08:03
  • @KevanStannard: Sorry, botched the maxAge .. corrected example above. You're right, it should be milliseconds. I got sidetracked thinking of expiry date. – Stennie Aug 23 '12 at 08:41
  • 2
    `connect-mongo`'s new default is 2 weeks, not "never". And the setting lives under `ttl` https://www.npmjs.com/package/connect-mongo – steampowered Aug 13 '16 at 22:38
6

I don't know from where the clear_interval options was taken but I'm looking at the code of the latest version:

class MongoStore extends Store {
 constructor(options) {
  options = options || {}

  /* Fallback */
  if (options.fallbackMemory && MemoryStore) {
    return new MemoryStore()
  }

  super(options)

  /* Options */
  this.ttl = options.ttl || 1209600 // 14 days
  this.collectionName = options.collection || 'sessions'
  this.autoRemove = options.autoRemove || 'native'
  this.autoRemoveInterval = options.autoRemoveInterval || 10
  this.transformFunctions = computeTransformFunctions(options, true)

  // ...

setAutoRemoveAsync() {
  const removeQuery = {expires: {$lt: new Date()}}
  switch (this.autoRemove) {
    case 'native':
      return this.collection.createIndex({expires: 1}, {expireAfterSeconds: 0})
    case 'interval':
      this.timer = setInterval(() => this.collection.remove(removeQuery, {w: 0}), this.autoRemoveInterval * 1000 * 60)
      this.timer.unref()
      return Promise.resolve()
    default:
      return Promise.resolve()
  }
}

So the correct way to set auto remove based on that code seems to be:

const store = new MongoStore({
  url: "put db connection string here ...",
  autoRemove: 'interval',     
  autoRemoveInterval: 60 * 24 // In minutes. Default
})

I dont see any trace of a clear_interval option, so it seems to me the suggested solution would have no effect ...

Felipe
  • 4,325
  • 1
  • 14
  • 19
  • 1
    My original answer was for the current `connect-mongo` version in 2012. Things have definitely changed since then, but the answer worked at the time :) – Stennie Mar 26 '20 at 09:34