npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@agendajs/mongo-backend

v3.2.0

Published

MongoDB backend for Agenda job scheduler

Readme

@agendajs/mongo-backend

MongoDB backend for Agenda job scheduler.

Installation

npm install agenda @agendajs/mongo-backend
# or
pnpm add agenda @agendajs/mongo-backend
# or
yarn add agenda @agendajs/mongo-backend

Requirements:

  • Node.js 18+
  • MongoDB 4+

Usage

import { Agenda } from 'agenda';
import { MongoBackend } from '@agendajs/mongo-backend';

// Via connection string
const agenda = new Agenda({
  backend: new MongoBackend({
    address: 'mongodb://localhost/agenda'
  })
});

// Or via existing MongoDB connection
import { MongoClient } from 'mongodb';

const client = await MongoClient.connect('mongodb://localhost');
const db = client.db('agenda');

const agenda = new Agenda({
  backend: new MongoBackend({ mongo: db })
});

// Define jobs
agenda.define('send-email', async (job) => {
  const { to, subject } = job.attrs.data;
  await sendEmail(to, subject);
});

// Start processing
await agenda.start();

// Schedule jobs
await agenda.every('1 hour', 'send-email', { to: '[email protected]', subject: 'Hello' });

Configuration Options

interface IMongoBackendConfig {
  /** MongoDB connection string */
  address?: string;

  /** Existing MongoDB database instance */
  mongo?: Db;

  /** Collection name for jobs (default: 'agendaJobs') */
  collection?: string;

  /** MongoDB client options */
  options?: MongoClientOptions;

  /** Name to identify this Agenda instance (stored as lastModifiedBy) */
  name?: string;

  /** Whether to create indexes on connect (default: true) */
  ensureIndex?: boolean;

  /** Sort order for job queries */
  sort?: { [key: string]: SortDirection };
}

Full Example with Options

const agenda = new Agenda({
  backend: new MongoBackend({
    address: 'mongodb://localhost/agenda',
    collection: 'jobs',           // Custom collection name
    sort: { nextRunAt: 'asc', priority: 'desc' }
  }),
  processEvery: '30 seconds',     // Job polling interval
  maxConcurrency: 20,             // Max concurrent jobs
  defaultConcurrency: 5           // Default per job type
});

Real-Time Notifications

MongoBackend provides storage only and uses polling to check for new jobs. For real-time job processing across distributed systems, you have several options:

Option 1: MongoDB Change Streams (Native)

If your MongoDB deployment is a replica set (even a single-node replica set works), you can use MongoChangeStreamNotificationChannel for native real-time notifications without any external dependencies:

import { Agenda } from 'agenda';
import { MongoBackend, MongoChangeStreamNotificationChannel } from '@agendajs/mongo-backend';

const agenda = new Agenda({
  backend: new MongoBackend({ mongo: db }),
  notificationChannel: new MongoChangeStreamNotificationChannel({ db })
});

// Jobs are processed immediately when created (no polling delay)
await agenda.start();
await agenda.now('myJob'); // Triggers instant processing

Requirements:

  • MongoDB replica set (single-node replica sets work fine)
  • WiredTiger storage engine (default since MongoDB 3.2)

Configuration options:

const channel = new MongoChangeStreamNotificationChannel({
  db: mongoDb,                    // Required: MongoDB database instance
  collection: 'agendaJobs',       // Optional: collection name (default: 'agendaJobs')
  resumeToken: savedToken,        // Optional: resume from specific point
  fullDocument: true              // Optional: include full document on updates (default: true)
});

Option 2: In-Memory (Single Process)

import { Agenda, InMemoryNotificationChannel } from 'agenda';
import { MongoBackend } from '@agendajs/mongo-backend';

// For single-process apps (testing/development)
const agenda = new Agenda({
  backend: new MongoBackend({ mongo: db }),
  notificationChannel: new InMemoryNotificationChannel()
});

Option 3: Redis Pub/Sub (Multi-Process)

import { Agenda } from 'agenda';
import { MongoBackend } from '@agendajs/mongo-backend';
import { RedisBackend } from '@agendajs/redis-backend';

// For production: use Redis for notifications
const redisBackend = new RedisBackend({ connectionString: 'redis://localhost:6379' });
const agenda = new Agenda({
  backend: new MongoBackend({ mongo: db }),
  notificationChannel: redisBackend.notificationChannel
});

Database Index

By default, MongoBackend automatically creates the findAndLockNextJobIndex index on connect for optimal job query performance. The index includes:

{
  "name": 1,
  "nextRunAt": 1,
  "priority": -1,
  "lockedAt": 1,
  "disabled": 1
}

To disable automatic index creation (e.g., if you manage indexes separately):

const backend = new MongoBackend({
  mongo: db,
  ensureIndex: false  // Skip automatic index creation
});

Additional Indexes

If you use Agendash, add this index for better dashboard performance:

db.agendaJobs.createIndex({
  "nextRunAt": -1,
  "lastRunAt": -1,
  "lastFinishedAt": -1
}, { name: "agendash" })

If you have job definitions with thousands of instances, this index can improve lock queries:

db.agendaJobs.createIndex({
  "name": 1,
  "disabled": 1,
  "lockedAt": 1
}, { name: "findAndLockDeadJobs" })

Job Logging

MongoBackend includes a built-in MongoJobLogger that stores structured job lifecycle events in a dedicated MongoDB collection (agenda_logs by default). The logger is lightweight and only creates its collection on first use.

Automatic Usage

When you enable logging in Agenda, the backend's built-in logger is used automatically:

const agenda = new Agenda({
  backend: new MongoBackend({ mongo: db }),
  logging: true  // Uses MongoJobLogger automatically
});

Standalone Usage

You can also use MongoJobLogger independently — for example, to log to MongoDB while using a different backend for storage:

import { MongoJobLogger } from '@agendajs/mongo-backend';

const logger = new MongoJobLogger({
  mongo: db,                        // Required: MongoDB database instance
  logCollection: 'agenda_logs'      // Optional: collection name (default: 'agenda_logs')
});

// Use with any backend
import { RedisBackend } from '@agendajs/redis-backend';
const agenda = new Agenda({
  backend: new RedisBackend({ connectionString: 'redis://...' }),
  logging: logger
});

Querying Logs

const { entries, total } = await agenda.getLogs({
  jobName: 'send-email',
  level: 'error',
  limit: 50,
  sort: 'desc'
});

// Clear old logs
await agenda.clearLogs({ to: new Date(Date.now() - 30 * 86400000) });

See the Agenda README for full logging documentation.

Related Packages

License

MIT