Mohammed Rafay, founder of MemorySync, published a detailed migration guide on Oct 27, 2026, outlining the technical steps for moving from Mem0 to MemorySync. The article, drafted with AI assistance but verified against official documentation, focuses on a reversible migration path using the memorysync-cli 1.6.1. Rafay emphasizes that the core architectural shift involves moving user identification from call arguments to request headers, a change that requires careful handling to avoid data scope errors.
The Header Shift
The most critical difference highlighted is how user scope is managed. In Mem0, developers pass user_id directly in add calls or use filters in search operations. MemorySync, however, relies on an X-End-User-ID header set once on the client via end_user_id. Rafay warns that a missing header in MemorySync does not raise an error but silently writes data to the wrong scope, making the initial setup step crucial for data integrity.
Dry Runs and CLI Behavior
The migration process begins with exporting data from Mem0, ensuring user_id is present on every record. The guide demonstrates using npx memorysync-cli migrate mem0 --file mem0_export.json --dry-run to preview the operation. In Rafay's testing, the dry run reports record counts and potential writes without modifying the database. If a record lacks a user_id, the CLI exits with code 2, refusing to guess the scope and prompting a re-export to ensure accuracy.
Import Mechanics and Metadata Mapping
When the actual import runs, the CLI groups records by Mem0 user_id and writes them under the corresponding end-user scope in MemorySync. It uses the original Mem0 id as a client_ref to prevent duplicate entries on re-runs. Categories are mapped to tags, while fields like agent_id, app_id, and run_id are preserved in metadata. Notably, the original timestamp is stored as metadata.mem0_created_at, requiring developers to sort on this field if chronological order from Mem0 is essential.
API Call Adjustments
Developers must update their code to match MemorySync's API structure. client.add becomes a POST to /memory/add with scope defined by the header. client.search transitions to POST /memory/query, where top_k is replaced by a k parameter (default 5). Updates use PATCH /memory/{memory_id} but notably do not allow editing the memory text itself, unlike Mem0's PUT. Deletions move to DELETE /memory/forget with a list of memory_ids, and MemorySync uses integer IDs instead of Mem0's strings.
Key Takeaways
- User scope moves from call arguments to the
X-End-User-IDheader; missing headers cause silent data misplacement. - The
memorysync-clidry run is essential for catching records withoutuser_idbefore writing. - MemorySync's
PATCHendpoint does not support editing memory text, a functional difference from Mem0. - Original Mem0 IDs are preserved as
client_refto enable idempotent re-runs and avoid duplicates. - Timestamps from Mem0 are stored in metadata (
mem0_created_at), requiring explicit sorting logic.
The Bottom Line
This is a vendor-penned tutorial, but the technical specificsβespecially the silent failure mode of missing headers and the inability to edit text via PATCHβare vital for any team planning a switch. The emphasis on dry runs and idempotency suggests a mature CLI, but the API surface differences require careful code review before cutover.