store-baileys
v1.0.6
Published
In-memory store for Baileys WhatsApp Web API - stores chats, contacts, messages, groups, and labels with advanced memory optimization
Maintainers
Readme
store-baileys
A storage implementation for Baileys - the WebSocket-based WhatsApp Web API library.
Compatible with Baileys v7.0.0-rc.9 and above.
Installation
npm install store-baileysNote: This package requires baileys as a peer dependency.
Features
- In-Memory Store for chats, contacts, messages, groups, labels
- Cache Manager Auth State for session persistence
- Automatic event binding with
bind()and cleanup withunbind() - Async file operations (
writeToFileAsync,readFromFileAsync) - Full TypeScript support
- Proper error handling for file operations and network requests
Important Notes
Contact Syncing Behavior
When using Baileys with syncFullHistory: false, contacts are not immediately available after connection. This is expected WhatsApp behavior:
- Labels and label associations sync immediately
- Contacts sync incrementally as you interact with chats or receive messages
- To get all contacts immediately, set
syncFullHistory: truein your Baileys socket configuration
// For immediate contact sync
const sock = makeWASocket({
syncFullHistory: true, // Loads all contacts on connection
// ... other config
})Usage
In-Memory Store
import makeWASocket from 'baileys'
import { makeInMemoryStore } from 'store-baileys'
const store = makeInMemoryStore({})
// Or configure what to persist to file
const store = makeInMemoryStore({
filePersist: {
chats: true, // Save chats (default: true)
contacts: true, // Save contacts (default: true)
messages: false, // Don't save messages (default: true)
groupMetadata: true, // Save group metadata (default: true)
labels: true, // Save labels (default: true)
labelAssociations: true // Save label associations (default: true)
}
})
// Bind store to socket events
store.bind(sock.ev)
// Access stored data
store.chats.all() // Get all chats
store.contacts // Get all contacts
store.messages['jid'] // Get messages for a JID
store.groupMetadata['jid'] // Get group metadata
store.labels.findAll() // Get all labels
// Load/save to file
store.readFromFile('./store.json')
store.writeToFile('./store.json')
// Or use async versions (non-blocking)
await store.readFromFileAsync('./store.json')
await store.writeToFileAsync('./store.json')
// Or use streaming version (lower memory usage for large stores)
await store.writeToFileStreaming('./store.json')
// Clean up before reconnecting (prevents memory leaks)
store.unbind(sock.ev)
// Clear all store data
store.clear()Cache Manager Auth State
import makeWASocket from 'baileys'
import { makeCacheManagerAuthState } from 'store-baileys'
// Create auth state with cache-manager store
// Note: sessionKey can only contain alphanumeric characters, underscores, and hyphens
const { state, saveCreds, clearState } = await makeCacheManagerAuthState(
cacheStore,
'my-session-key',
{ credsTTL: 63115200 } // Optional: TTL in seconds (default: 2 years)
)
const sock = makeWASocket({
auth: state
})
sock.ev.on('creds.update', saveCreds)Memory Optimization
Control memory usage and optimize performance with comprehensive memory management features:
import { makeInMemoryStore } from 'store-baileys'
// Basic memory optimization
const store = makeInMemoryStore({
memoryOptimization: {
enableMessageLimit: true, // Enable message limiting
maxMessagesPerChat: 100 // Keep only 100 messages per chat
}
})
// Result: Memory usage stays constant with automatic cleanup of old messagesFile Persistence Methods
Choose the right method for saving your store to file:
// writeToFile - Synchronous (blocks event loop)
// Use for: Simple scripts, small stores
store.writeToFile('./store.json')
// writeToFileAsync - Asynchronous (non-blocking)
// Use for: Most production use cases
await store.writeToFileAsync('./store.json')
// writeToFileStreaming - Asynchronous with streaming (low memory)
// Use for: Large stores (thousands of chats, millions of messages)
// Memory benefit: Reduces memory spike by ~66% during save
await store.writeToFileStreaming('./store.json')Memory comparison for a 100MB store:
writeToFile/writeToFileAsync: ~300MB peak memory (3x spike)writeToFileStreaming: ~101MB peak memory (minimal spike)
Recommendation: Use writeToFileStreaming if you have:
- More than 1000 chats
- More than 100,000 messages
- Limited server memory
- Experiencing out-of-memory errors during save
Advanced Memory Optimization
Comprehensive memory management and performance optimization features for high-volume applications:
Message Limiting Options
Control message storage with flexible limiting options:
// Per-chat message limiting
const store = makeInMemoryStore({
memoryOptimization: {
enableMessageLimit: true,
maxMessagesPerChat: 100 // Keep only 100 latest messages per chat
}
})
// Global total message limiting
const store = makeInMemoryStore({
memoryOptimization: {
enableTotalMessageLimit: true,
maxTotalMessages: 5000 // Keep max 5000 messages across ALL chats
// Use 'full' or -1 for unlimited: maxTotalMessages: 'full'
}
})
// Combined limits for maximum control
const store = makeInMemoryStore({
memoryOptimization: {
enableMessageLimit: true, // Per-chat limit
maxMessagesPerChat: 100,
enableTotalMessageLimit: true, // Global limit
maxTotalMessages: 5000
}
})Message Limiting Types:
- Per-Chat: Limits messages per individual chat (e.g., max 100 per conversation)
- Global: Limits total messages across ALL chats (e.g., max 5000 total)
- Combined: Both limits enforced independently for maximum memory control
- Unlimited: Set
maxTotalMessages: 'full'to keep all messages
IndexMap Optimization
Trade memory for performance with configurable index mapping:
const store = makeInMemoryStore({
memoryOptimization: {
enableIndexMap: false // Saves ~33% memory, slower lookups
}
})Contact Hash Caching
Dramatically improve contact update performance:
const store = makeInMemoryStore({
memoryOptimization: {
enableContactHashCache: true // Default: enabled for performance
}
})Benefits:
- 6-20x faster contact updates with large contact lists
- Eliminates expensive hash recalculation on every contact update
- Essential for bots with 500+ contacts, group management, business WhatsApp
Incremental Index Updates
Optimize index rebuilding with smart incremental updates:
const store = makeInMemoryStore({
memoryOptimization: {
enableIncrementalIndexing: true // Default: enabled for performance
}
})Benefits:
- 2-10x faster remove/prepend operations
- Smart index shifting instead of full rebuilds
- Optimal for high-frequency message updates and bulk operations
Complete Optimization Configuration
Combine all optimizations for your specific use case:
const store = makeInMemoryStore({
memoryOptimization: {
// Message limiting
enableMessageLimit: true, // Per-chat message limiting
maxMessagesPerChat: 100, // Keep only 100 messages per chat
enableTotalMessageLimit: true, // Global message limiting
maxTotalMessages: 5000, // Keep max 5000 messages total (use 'full' for unlimited)
// Performance vs Memory trade-offs
enableIndexMap: false, // Saves ~33% memory, slower lookups
enableContactHashCache: true, // Fast contact updates (recommended)
enableIncrementalIndexing: true // Fast index operations (recommended)
}
})Configuration Guidelines:
- Memory Priority: Set
enableIndexMap: falseto save ~33% memory per message dictionary - Performance Priority: Keep
enableContactHashCache: trueandenableIncrementalIndexing: true - Balanced Approach: Enable performance optimizations, adjust message limits based on needs
- Unlimited Messages: Use
maxTotalMessages: 'full'for complete message history
Using Environment Variables
# .env file
SAVE_CHATS=true
SAVE_CONTACTS=true
SAVE_MESSAGES=false
SAVE_GROUP_METADATA=true
SAVE_LABELS=true
SAVE_LABEL_ASSOCIATIONS=trueimport { makeInMemoryStore } from 'store-baileys'
const getEnvBoolean = (key: string, defaultValue: boolean = true): boolean => {
const value = process.env[key]
if (value === undefined) return defaultValue
return value.toLowerCase() === 'true'
}
const store = makeInMemoryStore({
filePersist: {
chats: getEnvBoolean('SAVE_CHATS'),
contacts: getEnvBoolean('SAVE_CONTACTS'),
messages: getEnvBoolean('SAVE_MESSAGES'),
groupMetadata: getEnvBoolean('SAVE_GROUP_METADATA'),
labels: getEnvBoolean('SAVE_LABELS'),
labelAssociations: getEnvBoolean('SAVE_LABEL_ASSOCIATIONS')
}
})Custom Store with MySQL/Database
import { makeInMemoryStore, StoreData } from 'store-baileys'
const store = makeInMemoryStore({})
// Load from database on startup
const data: StoreData = await loadFromDatabase()
if (data) {
store.fromJSON(data)
}
// Save to database on events
sock.ev.on('contacts.upsert', async () => {
const storeData: StoreData = store.toJSON()
await saveToDatabase(storeData)
})API Reference
makeInMemoryStore(config)
| Property | Type | Description |
|----------|------|-------------|
| chats | KeyedDB | All chats |
| contacts | Object | All contacts |
| messages | Object | Messages by JID |
| groupMetadata | Object | Group metadata by JID |
| labels | ObjectRepository | WhatsApp labels |
| labelAssociations | KeyedDB | Label-chat associations |
| state | ConnectionState | Current connection state |
| Method | Description |
|--------|-------------|
| bind(ev) | Bind to Baileys event emitter |
| unbind(ev?) | Remove all event listeners (ev optional, uses tracked emitter if not provided) |
| clear() | Clear all store data |
| toJSON() | Export store data (typed as StoreData) |
| fromJSON(data) | Import store data |
| loadMessage(jid, id) | Load a specific message |
| loadMessages(jid, count, cursor) | Load messages with pagination |
| mostRecentMessage(jid) | Get most recent message |
| fetchGroupMetadata(jid, sock) | Get/fetch group metadata |
| fetchImageUrl(jid, sock) | Get/fetch profile picture |
| getLabels() | Get all labels |
| getChatLabels(chatId) | Get labels for a chat |
| getMessageLabels(messageId) | Get labels for a message |
| writeToFile(path) | Save to file (sync, throws on error) |
| writeToFileAsync(path) | Save to file (async, throws on error) |
| writeToFileStreaming(path) | Save to file using streaming (async, lower memory usage for large stores) |
| readFromFile(path) | Load from file (sync, throws on corrupted JSON) |
| readFromFileAsync(path) | Load from file (async, throws on corrupted JSON) |
Configuration Options
BaileysInMemoryStoreConfig
| Option | Type | Description |
|--------|------|-------------|
| filePersist | FilePersistConfig | Configure which data to persist to file |
| chatKey | Comparable<Chat, string> | Custom chat sorting key |
| labelAssociationKey | Comparable<LabelAssociation, string> | Custom label association key |
| logger | ILogger | Custom logger instance |
| socket | WASocket | Socket instance for fetching profile pictures |
FilePersistConfig
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| chats | boolean | true | Save chats to file |
| contacts | boolean | true | Save contacts to file |
| messages | boolean | true | Save messages to file |
| groupMetadata | boolean | true | Save group metadata to file |
| labels | boolean | true | Save labels to file |
| labelAssociations | boolean | true | Save label associations to file |
MemoryOptimizationConfig
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| enableMessageLimit | boolean | false | Enable per-chat message limiting |
| maxMessagesPerChat | number | 1000 | Maximum messages per individual chat |
| enableTotalMessageLimit | boolean | false | Enable global message limiting across all chats |
| maxTotalMessages | number \| 'full' | 5000 | Maximum total messages across all chats ('full' for unlimited) |
| enableIndexMap | boolean | true | Enable index mapping for faster lookups (uses more memory) |
| enableContactHashCache | boolean | true | Enable contact hash caching for faster contact updates |
| enableIncrementalIndexing | boolean | true | Enable incremental index updates for faster operations |
Exports
import {
makeInMemoryStore,
makeCacheManagerAuthState,
waChatKey,
waMessageID,
waLabelAssociationKey,
ObjectRepository,
makeOrderedDictionary
} from 'store-baileys'
// Types
import type {
BaileysInMemoryStoreConfig,
FilePersistConfig,
MemoryOptimizationConfig,
StoreData,
CacheManagerAuthStateConfig
} from 'store-baileys'Migration from v1.x
If you're upgrading from v1.x, note that saveCreds has been renamed to filePersist for clarity. The old saveCreds option still works for backwards compatibility but is deprecated.
// Old (deprecated but still works)
const store = makeInMemoryStore({
saveCreds: { chats: true }
})
// New (recommended)
const store = makeInMemoryStore({
filePersist: { chats: true }
})Disclaimer
This project is not affiliated with WhatsApp. Use responsibly and in accordance with WhatsApp's Terms of Service.
License
MIT License - Copyright (c) 2025 JiqTech
