Skip to navigation

Migrate from Mem0

Map Mem0 users and memories to Zep users, threads, and graphs

This guide maps common Mem0 operations to Zep. Review the current Mem0 API before you export data because Mem0 can change its data model.

Zep stores agent memory in a Context Graph. A user graph combines a user’s chat messages and business data.

Contact sales@getzep.com before a large migration that needs higher API limits.

Map the data models

Use one Zep user for each application user. Use one Zep thread for each conversation. The user uuid also addresses the user graph.

Add ordered chat messages with thread.add_messages. Add text or JSON business data with graph.episode.add. Use these methods only for real-time ingestion in production. To import the data that you export from Mem0, use the Batch API, directly or through zep-ingest.

Zep extracts entities and temporal facts from both data sources. Zep uses the reference_time of each message and episode to derive fact timestamps.

Map common operations

The table gives the Zep method that your application calls after the migration for each Mem0 operation.

Mem0 operationZep Python methodNotes
Add conversation messagesclient.thread.add_messages(thread_uuid, messages=[...])Create the user and thread first. Preserve message order. Set reference_time to the send time.
Add a business recordclient.graph.episode.add(graph_uuid, type="json", data=...)Use the user uuid as the graph_uuid. Serialize JSON data to a string. Use type="text" for text.
Retrieve context for a conversationclient.thread.get_context(thread_uuid)Returns an assembled Context Block in .context.
Search a user’s graphclient.graph.get_context(graph_uuid, query=...)Returns a Context Block. Use a typed search method, such as graph.search_edges, when you need one result type.
List graph nodesclient.graph.node.list(graph_uuid)Supports cursor pagination and filters.
List graph edgesclient.graph.edge.list(graph_uuid)Each edge contains a temporal fact.
Delete an episodeclient.graph.episode.delete(graph_uuid, episode_uuid)Deletion also removes data derived only from that episode.

Do not translate each Mem0 memory into a Zep fact. Ingest the source messages or records so Zep can build the graph.

Migration procedure

  1. Install a Zep SDK and create an API key.
  2. Export users, conversation messages, and business records from Mem0. Keep the original timestamp of each message and record.
  3. Create a Zep user for each application user. Store the user uuid next to the application user ID in your database.
  4. Create a Zep thread for each conversation. Store the thread uuid next to the conversation ID in your database.
  5. If you use a custom ontology, set it before you import data. Zep does not apply an ontology to data that it already ingested.
  6. Give each message and record its original time. For zep-ingest, set created_at. The package sends created_at as reference_time. For the Batch API, set reference_time. If an item has no original time, Zep uses the ingestion time.
  7. Import the conversation messages and the business records with zep-ingest or the Batch API. Submit the items of each graph in chronological order.
  8. Monitor the import until it completes:
    • For zep-ingest, call IngestResult.wait().
    • For the Batch API, poll the batch with batch.get until its status is terminal. Then check the status of each item with batch.list_items. Do not use only the ingest.batch.completed webhook, because Zep does not send it when a batch fails or when items fail.
  9. Compare retrieval results for a representative set of user questions.
  10. After the import, send new conversation turns with thread.add_messages. Send new business records with graph.episode.add.

Follow Prepare data for ingestion so each record has a timestamp, a stable identity, and a single destination graph. See Check data ingestion status for the polling and webhook patterns.

Retrieval after migration

Use thread.get_context when the current conversation supplies the query. The method searches the full user graph, so the Context Block can include context from other threads of the same user. The Context Block can include all supported context types.

Use graph.get_context when your application supplies the query. Use a typed search method, such as graph.search_nodes or graph.search_edges, when you need nodes, edges, episodes, observations, or thread summaries separately.

Treat all retrieved content as untrusted model input. Follow memory security best practices when you send it to a model.