← Back to Blog
WhatsApp & Automation4 min read

Running Baileys in Production: The Advanced Guide

A deep dive into managing the Baileys WhatsApp Web library in production. Learn how to prevent memory leaks, avoid cluster mode pitfalls, and handle authentication scaling.

Naveen Gaur
Naveen Gaur
August 1, 2026

When developers first discover @whiskeysockets/baileys, the appeal is obvious. It’s a fast, headless, zero-cost alternative to the official WhatsApp Cloud API. You can get a bot running on your local machine in under 20 lines of code.

But transitioning from a local npm start script to a production-grade daemon handling thousands of concurrent messages is a brutal learning curve.

In this guide, we will bypass the generic "how to scan a QR code" tutorials and focus entirely on production engineering: memory management, state locking, and logging strategies necessary to keep Baileys running 24/7.


1. The Memory Leak Trap (Disable the Internal Store)

The most common reason a Baileys bot crashes in production is an Out of Memory (OOM) error.

By default, Baileys can bind an internal in-memory store (makeInMemoryStore) to track chat history, contacts, and presence updates. While this is incredibly useful for building desktop clients or read-receipt features, it is a fatal flaw for stateless bots.

If your bot acts as a gateway (receiving messages and passing them to an external API like Vercel or a Postgres database), you do not need Baileys to remember chat history.

The Fix: Stateless Socket Configuration

Do not instantiate makeInMemoryStore. Instead, configure the socket to explicitly ignore fetching chat history upon connection. This drops your idle RAM usage from >200MB down to ~35MB.

const sock = makeWASocket({
    auth: state,
    printQRInTerminal: false,
    // CRITICAL: Prevent Baileys from requesting full chat history on boot
    getMessage: async () => {
        return { conversation: '' };
    },
    // Optional: Only sync what is absolutely necessary
    syncFullHistory: false,
});

2. The Cluster Mode Pitfall (File Locking Conflicts)

When deploying Node.js apps, standard best practice is to use PM2's cluster mode (pm2 start app.js -i max) to utilize all CPU cores.

Do not do this with Baileys.

Baileys maintains its session using useMultiFileAuthState. It constantly reads and writes cryptographic keys to a local folder (e.g., ./auth_info). If you run Baileys in cluster mode, two Node.js processes will attempt to read and write to the same authentication files simultaneously.

This results in a race condition. The keys fall out of sync with WhatsApp's servers, the session is invalidated, and your bot will crash with a 401 Unauthorized error, forcing you to manually rescan the QR code.

The Fix: Single Instance with Async Queues

You must run Baileys as a single instance.

// ecosystem.config.js
module.exports = {
  apps: [{
    name: "whatsapp-gateway",
    script: "index.js",
    instances: 1, // NEVER USE 'max'
    exec_mode: "fork",
    max_memory_restart: "500M",
  }]
}

If you need to scale, you scale by offloading the work, not the socket. The Baileys instance should do nothing but receive the payload and immediately push it to a Redis queue or an external webhook. The heavy lifting (AI processing, DB writes) happens elsewhere.


3. Silencing the Logger

Baileys uses pino for internal logging. In development, it defaults to the trace level.

If you leave this default in production, your PM2 logs will balloon to dozens of gigabytes within days, eventually filling up your VPS disk space and crashing the server.

The Fix: Silent or Warn Level

Always explicitly inject a silent or warn-level logger into the socket configuration.

const pino = require('pino');

const sock = makeWASocket({
    auth: state,
    logger: pino({ level: 'silent' }), // or 'warn'
});

Manage your own application-level logging using standard console.log or a dedicated APM tool, rather than relying on the library's internal protocol traces.


Conclusion

Running Baileys in production is an exercise in constraint management. By treating the Baileys Node.js process as a "dumb pipe"—disabling memory stores, enforcing single-thread execution, and silencing verbose logs—you transform a fragile local script into an enterprise-grade message gateway.

Leave a Comment

Comments are moderated before appearing on the site.

Need help with your WordPress site?

I fix WordPress crashes, remove malware, and optimize performance for small businesses. Fast turnaround, direct access, no agency overhead.