Migrate WAHA WhatsApp sessions between PostgreSQL and SQLite storage backends.
WAHA (with the GOWS engine) can store session data in either PostgreSQL or SQLite. This tool copies session data between the two, enabling backend migrations without re-pairing devices.
uv tool install .Or run directly:
uv run waha-migrate --help# From PostgreSQL
waha-migrate discover -p "postgres://user:pass@host:5432/dbname"
# From SQLite
waha-migrate discover -d /path/to/sessions/gowswaha-migrate pg-to-sqlite \
-p "postgres://user:pass@host:5432/dbname" \
-o ./output \
--include-messages # optional: include message history
-s my_session # optional: specific session(s) onlywaha-migrate sqlite-to-pg \
-d /path/to/sessions/gows \
-p "postgres://user:pass@host:5432/dbname" \
--include-messages
-s my_sessionData is organized in three tiers:
| Tier | Contents | Default |
|---|---|---|
| 1 | Session identity & crypto keys (device, Signal sessions, pre-keys) | Always |
| 2 | Metadata (contacts, chat settings, privacy tokens, LID map) | Always |
| 3 | Application data (messages, groups, labels) | --include-messages |
Tiers 1 and 2 are always migrated. Tier 3 (dominated by message history, often hundreds of MB) is opt-in.
Session configuration (webhooks, metadata) is also migrated — converted between PostgreSQL's session_config table and SQLite's .waha.session.config.json files.
WAHA stores session data in 21 tables (15 from the whatsmeow library for WhatsApp protocol state, 6 from GOWS for application data). The schema is identical across both backends.
The tool streams rows directly from source to destination in 5000-row batches with minimal type coercion at the boundary (e.g., SQLite int → PG boolean, PG bytea memoryview → Python bytes). No intermediate representation is built.
PostgreSQL: One database per session, named waha_gows_<session_id>, plus a shared waha_gows database for metadata.
SQLite: One directory per session at <sessions_dir>/gows/<session_id>/, containing gows.db and .waha.session.config.json.
- Stop WAHA before migrating to avoid data inconsistency. The tool opens PostgreSQL connections as read-only (for the source direction) and SQLite with WAL mode.
- After migrating to SQLite, sessions need to be started via the WAHA API (
POST /api/sessions/<name>/start) — WAHA does not auto-start sessions from SQLite files on boot. - Signal protocol sessions may need to re-establish after migration (first few messages may fail to decrypt), but this resolves automatically.