To launch a WhatsApp bot on a VPS via the Baileys library, a server with 1 vCPU, 2 GB RAM, and Ubuntu OS is sufficient, allowing you to completely eliminate payments starting from $0.005 per message, typical for the official WhatsApp Business API (WABA) or providers like Twilio.
Why use a WhatsApp bot on VPS instead of the official API
The official WhatsApp Business API (WABA) solution imposes many restrictions on businesses: from the need for company verification to strict moderation of message templates. Using wa bot self host solutions based on the Baileys library allows you to bypass these barriers, turning a regular phone number into a full-fledged automation gateway. The main advantage here is complete freedom in content choice and no fees for dialogues.
Economic benefits of self-hosted solutions
When using paid APIs such as Twilio or MessageBird, the cost of a single outgoing message can be around $0.005. For a mailing list of 10,000 contacts, the budget would be $50. Meanwhile, renting a VPS to run baileys whatsapp will cost $5-$10 per month with no limits on the number of messages. The difference in costs becomes colossal when scaling the project.
Technical advantages of Baileys
The Baileys library is written in TypeScript and is one of the most stable implementations of the WhatsApp Web protocol. Unlike Selenium or Puppeteer-based solutions, it does not run a full Chrome browser instance, which radically reduces server resource consumption. This allows running dozens of bots on a single budget VPS. If you have already set up a Telegram bot 24/7 on VPS, the principles of working with asynchronous events in Baileys will seem familiar to you.
Baileys WhatsApp architecture and system requirements
The operation of the whatsapp web api via Baileys is built on Multi-Device mode emulation. The server connects to WhatsApp servers using a WebSocket connection and exchanges encrypted data. The key point is session storage: after scanning the QR code, authentication keys are saved in a local folder or database, allowing the bot to automatically reconnect after a VPS reboot.
Minimum and recommended server specifications
For the stable operation of one or two bots, the simplest plans are sufficient; however, for high-load systems (mailings to thousands of numbers), it is worth allocating extra RAM.
| Specification |
Minimum (1-2 bots) |
Optimal (10+ bots) |
| CPU (vCPU) |
1 Core (2.0 GHz+) |
2-4 Cores |
| RAM |
1 GB |
4-8 GB |
| Disk (NVMe) |
10 GB |
40 GB+ |
| Operating System |
Ubuntu 22.04 LTS |
Ubuntu 22.04 / Debian 11 |
Why it is important to use NVMe disks
During active correspondence, Baileys constantly records the session state and caches media files. Using fast NVMe disks on a VPS prevents lags when processing incoming webhooks, especially when the bot handles hundreds of simultaneous dialogues. This is critical for ensuring an instant response comparable to wa-mate or other commercial gateways.
Looking for a reliable server for your projects?
VPS from $10/mo and dedicated servers from $9/mo with NVMe, DDoS protection, and 24/7 support.
View offers →
Step-by-step installation of wa bot self host on VPS
To get started, you need to prepare the Node.js execution environment. We recommend using the LTS version (currently 18 or 20), as Baileys actively uses modern JavaScript features and TypeScript typing.
Preparing the environment in Ubuntu
Connect to your VPS via SSH and update the packages:
sudo apt update && sudo apt upgrade -y
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install -y nodejs build-essential
After installing Node.js, create a project directory and initialize it:
mkdir wa-bot && cd wa-bot
npm init -y
npm install @whiskeysockets/baileys pino qrcode-terminal
Configuring authorization and QR login in /tmp
One of the features of working in Linux containers or on servers with limited access rights is choosing a location for session storage. Developers often use the /tmp directory for temporary keys, but for a permanent bot, it's better to create a dedicated auth_info folder in the project root. This ensures the session is preserved when the application restarts.
Example of basic code to launch and generate a QR code in the terminal:
const { default: makeWASocket, useMultiFileAuthState } = require('@whiskeysockets/baileys')
const qrcode = require('qrcode-terminal')
async function startBot() {
const { state, saveCreds } = await useMultiFileAuthState('auth_info')
const sock = makeWASocket({
auth: state,
printQRInTerminal: true
})
sock.ev.on('creds.update', saveCreds)
sock.ev.on('connection.update', (update) => {
const { connection, lastDisconnect } = update
if(connection === 'close') {
console.log('Connection closed, restarting...')
startBot()
} else if(connection === 'open') {
console.log('Bot connected successfully!')
}
})
}
startBot()
If you plan to integrate the bot with a CRM, check out Self-hosted Chatwoot. This will allow you to combine messages from WhatsApp and other channels into a single interface on your own server.
Implementing WhatsApp Web API: webhooks and message processing
To make your whatsapp bot vps useful, it must be able to react to incoming messages and forward them to external systems (for example, to your database or CRM via webhooks). Baileys provides a convenient event system for monitoring new messages.
Processing incoming text
To filter spam and process commands, use the messages.upsert event listener. It's important to note that WhatsApp sends messages in batches, so the code must be able to iterate through the incoming data array.
sock.ev.on('messages.upsert', async m => {
const msg = m.messages[0]
if (!msg.key.fromMe && m.type === 'notify') {
const text = msg.message.conversation || msg.message.extendedTextMessage?.text
const remoteJid = msg.key.remoteJid
console.log(`Message received from ${remoteJid}: ${text}`)
if (text === 'Hello') {
await sock.sendMessage(remoteJid, { text: 'Hello! How can I help you?' })
}
}
})
Integration with n8n for automation
To create complex chains without writing hundreds of lines of Node.js code, you can use Self-hosted n8n. You can configure the bot to send every incoming message as a POST request to n8n, where the processing logic will occur (for example, a request to ChatGPT or a search in Google Sheets), and return the response back to WhatsApp.
Ban risks and bypassing wa-mate restrictions
The main risk when using an unofficial whatsapp web api is a number ban. WhatsApp actively fights automation using machine learning algorithms to identify bots. If your number is blocked, it will be extremely difficult to restore it for API use.
How to avoid bans during mailings
- Number warming: Do not start mass mailings from a new number. During the first 7-14 days, use it for regular correspondence with "trusted" contacts who have added you to their address book.
- Using proxies: If you run multiple bots on one VPS, WhatsApp might block them all by IP. It is recommended to use an individual residential or mobile proxy for each bot. This is especially relevant if you are engaged in tasks like parsing Wildberries/OZON/Avito on VPS, where anti-ban technologies play a key role.
- Randomizing delays: Never reply instantly. Add a random delay of 2-5 seconds before sending a message to mimic human actions.
- Limits: Do not send more than 50-100 messages per hour to unknown users. If users start clicking the "Report" button, a ban will arrive instantly.
Comparison with wa-mate and other gateways
Services like wa-mate are essentially wrappers around the same Baileys or similar libraries, providing a convenient HTTP API for a monthly subscription. By deploying the solution yourself on a VPS, you get the same functionality but maintain full control over the data and save $30 to $100 per month on subscriptions.
Cost comparison: Baileys on VPS vs Twilio API
For businesses, the choice between a self-hosted solution and the official API often comes down to math and risk assessment. Below is a table of approximate costs for a volume of 50,000 messages per month.
| Expense Item |
Twilio (WABA) |
Baileys (VPS) |
| Server Rent / Subscription |
$0 (but there are minimum charges) |
$10 (Valebyte VPS) |
| Cost of 50k messages |
~$250 (depends on the country) |
$0 |
| Company verification (FB Business) |
Mandatory |
Not required |
| Ban risk |
Low (if rules are followed) |
Medium/High (depends on spam) |
| Total per month |
$250+ |
$10 |
As seen from the table, wa bot self host is 25 times more profitable. However, you should consider the costs of technical support and monitoring the script's health. To ensure 99.9% uptime, it is recommended to use the PM2 process manager.
Deployment and 24/7 monitoring
To prevent your bot from "crashing" after closing the SSH session, you need to use PM2. This is the industry standard for Node.js applications, allowing the script to automatically restart on errors or server reboots.
Configuring PM2
sudo npm install -g pm2
pm2 start index.js --name "whatsapp-bot"
pm2 save
pm2 startup
Now the bot will run in the background. To view logs in real-time, use the command pm2 logs whatsapp-bot. This will allow you to quickly track authorization errors or problems with the WebSocket connection.
Resource monitoring
Although Baileys consumes few resources, a memory leak may occur with a large number of dialogues. It is recommended to set a RAM limit in PM2 so that the process restarts when it reaches, for example, 500 MB RAM:
pm2 start index.js --max-memory-restart 500M
For more advanced error tracking, you can integrate Self-hosted Sentry, which will allow you to receive notifications about bot code failures before customers start complaining about the lack of responses.
Conclusions
Using Baileys on a VPS is the most effective way to launch a WhatsApp bot for small and medium-sized businesses without the huge costs of the official API. For stable operation, a server with 2 GB RAM and compliance with number "warming" rules is sufficient, ensuring uninterrupted communication with customers with minimal infrastructure investment.
Ready to choose a server?
VPS and dedicated servers in 72+ countries with instant activation and full root access.
Start now →