Skip to main content
Baileys is a stateless WebSocket client. It processes and emits events but does not store anything between socket restarts. There is no built-in database, no message history cache, and no contact list that persists on disk. Your application is responsible for building and maintaining that state from the events Baileys emits. This design is intentional: it lets you choose any storage backend — a Map in memory, SQLite, Redis, Postgres — without the library forcing a particular approach on you.

Why you need a store

Several Baileys features depend on your application being able to look up past messages:
  • Message retries — when a message fails to decrypt, WhatsApp asks the sender to resend it. Baileys calls the getMessage callback in your SocketConfig to retrieve the plaintext so it can re-encrypt and deliver it. Without this, retries silently fail and recipients see “This message took a while.”
  • Poll vote decryption — poll votes arrive as encrypted messages.update events. To aggregate votes you need the original poll creation message.
  • History queriessock.fetchMessageHistory loads older messages from the phone, delivering them via messaging-history.set. Your store needs to accept and persist these batches.

The in-memory store

makeInMemoryStore was available in earlier versions of Baileys but has been removed as of v7. If you are upgrading from v6 or earlier, you will need to implement your own store. The patterns in this guide show you how.
For a minimal starting point, you can manage state directly in JavaScript objects and populate them from events. This is fine for local development and testing, but not for production — process restarts lose everything.

Production: database-backed store

For a production deployment, replace the in-memory Maps with your database of choice. The structure of the store stays the same — you are just changing where data is read from and written to.

SQLite example (with better-sqlite3)

Then wire it into your socket config:

Redis example


Querying messages

Once you have a store, you can implement a loadMessages helper to retrieve recent messages for a given chat — useful for displaying chat history in a UI or processing a conversation thread.

Checklist

1

Implement getMessage in SocketConfig

This is the single most important step. Without it, message retries and poll vote decryption do not work.
2

Populate the store from messages.upsert

Every incoming and outgoing message fires this event. Store the full WAMessage object, not just the text.
3

Handle messaging-history.set for bulk inserts

History syncs can deliver thousands of messages at once. Use batch inserts to avoid hammering your database.
4

Keep chat and contact state up to date

Listen to chats.upsert, chats.update, chats.delete, contacts.upsert, and contacts.update to maintain an accurate local copy.
5

Persist auth state separately

Your message store and your auth state (useMultiFileAuthState) are different things. Both must survive restarts, but through separate mechanisms.
Never store authentication state (the contents of baileys_auth_info/) in the same database table as messages. Auth state contains long-lived Signal encryption keys. Treat it with the same care as an SSH private key.