#StackBounty: #javascript #node.js #memory-leaks Memory leak with setInterval running in a Node.js Process

Bounty: 50

I’m having an issue with setInterval() causing a memory leak in my Node.js application. The app is simple: it wakes up every half hour, looks in a MongoDB table to see if there’s any work to do (most times it does not), and then sends an email to the records found that meet the criterion. Over time (a few days), the memory goes from 100MB to over 1GB.

I tried moving the variables outside of the setInteveral to get GC’d but no luck. Am I missing something?

I’m using New Relic to monitor the transaction, but this issue persisted prior to me adding this instrumentation.

const transactionName = 'email-scheduler';
let invokeTransaction = newrelic.createBackgroundTransaction(transactionName,
    function () {
      sendEmail(function (error) {
        log.info("Job completed; ending transaction.");
        newrelic.endTransaction();
      });
    }); //must be outside of setInterval to be GC'd
if (RUN_SCHEDULER) {
  setInterval(invokeTransaction, JOB_INTERVAL_MINUTES * 1000 * 60);
}

function sendEmail(callback) {
  log.info('Scheduler woke up to send emails (set to send every ' + JOB_INTERVAL_MINUTES + ' minutes)');
  mongo.findUsersSince(180, function (err, result) {
    if (err) {
      log.error("Welcome emails could not be sent: " + err);
      callback(err);
    }
    else if (result && result instanceof Array) {
      api.sendEmail(resutlt);
    } else {
      callback(null);
    }
  });
}

Here’s the alternative version when I’m using a package like Cron instead of setInterval(). Suffers from the same issue:

function sendEmail(callback) {
  log.info('Scheduler woke up to send emails (set to send every ' + JOB_INTERVAL_MINUTES + ' minutes)');

  try {
    new CronJob('0 */' + JOB_INTERVAL_MINUTES + ' * * * *', function () {
      log.info('Scheduler woke up to send emails (set to send every ' + JOB_INTERVAL_MINUTES + ' minutes)');
      mongo.findUsersSince(OKTA_WAIT_MINUTES, function (err, result) {
        if (err) {
          log.error("Welcome emails could not be sent: " + err);
          callback(err);
        }
        else if (result && result instanceof Array) {
          api.sendEmail(resutlt);
        } else {
          callback(null);
        }
      });
    }, function () {
      log.info('Scheduler completed job.');
    }, RUN_SCHEDULER, "America/Los_Angeles");
  } catch (ex) {
    log.error("cron job pattern not valid");
  }
}


Get this bounty!!!