# DeerFlow per-user memory: issue #1772 is open, but main already isolates memory

*Disclosure: I work on MemorySync (I'm Mohammed, the founder). I drafted this page with AI assistance and checked it against the source issue and the DeerFlow source on its main branch (commit* `d4ed400`*, Oct 28, 2026). I read the code; I didn't run DeerFlow for this page.*

## The question

[bytedance/deer-flow#1772](https://github.com/bytedance/deer-flow/issues/1772), "Support per-user memory isolation for multi-tenant deployment", reports that DeerFlow's `memory.json` is global and shared across all users, and asks for per-user storage such as `memory/{user_id}.json`. A maintainer replied that memory shared across users "can easily get mixed up" in a multi-user setup and assigned it.

**Status (checked Oct 28, 2026):** the issue is still **open**, last updated Apr 3, 2026. But the code has moved on. If you're reading the issue and assuming every user still shares one file, check your version first.

> **Skip the memory plumbing around this fix.** Once the fix below is in, the [MemorySync agent memory guide](https://docs.memorysync.io/guides/agent-memory?utm_source=hashnode&utm_medium=organic_page&utm_campaign=v5_oct25&utm_content=pseo_deerflow-per-user-memory-isolation) shows how to add per-user memory with MemorySync. MemorySync doesn't fix this error itself. When you're ready, [see MemorySync](https://memorysync.io/?utm_source=hashnode&utm_medium=organic_page&utm_campaign=v5_oct25&utm_content=pseo_deerflow-per-user-memory-isolation). Founding offer: use code FOUNDING30 for 30% off Starter for your first 3 months (Settings → Billing).

## What current main does

From the memory module's `AGENTS.md` and the DeerMem config in the repo (main, Oct 28, 2026):

- The default backend (`manager_class: deermem`) stores memory per user:

```text
{base_dir}/users/{user_id}/memory.json
{base_dir}/users/{user_id}/agents/{agent_name}/facts/...
```

- `memory.backend_config.storage_path` is a root **directory**. Empty means DeerFlow's base dir. A non-empty value becomes the root, with per-user memory still under `{storage_path}/users/{uid}/memory.json`. If it points at an existing file (for example an old `memory.json` path from before), config validation raises and tells you to point it at a directory.
- The user comes from server-side identity, not from the client. In order: the LangGraph Agent Server's authenticated user, `langgraph_auth_user_id`, the gateway's auth-validated `runtime.context["user_id"]`, the auth middleware's context variable, and finally `"default"`. The Gateway strips client-supplied `langgraph_auth_user` and `langgraph_auth_user_id` before the graph is built.
- Background memory updates capture `user_id` when the work is queued, so the identity survives the debounce timer.

## The catch: no-auth mode is still one shared user

Per `AGENTS.md`, no-auth mode uses `DEFAULT_USER_ID`, which is `"default"`. If you run DeerFlow as a service without authentication, every caller resolves to the same user and shares the same `users/default/` memory, which is the behaviour the issue describes. Per-user isolation only helps once requests carry an authenticated identity.

## Checklist for a multi-user deployment

1. **Turn on authentication** so the gateway or LangGraph server supplies a real user. Without it, you're on `"default"`.
2. **Check** `storage_path`**.** Leave it empty or point it at a directory. Don't point it at a `.json` file.
3. **Migrate old global data.** The repo ships `backend/scripts/migrate_user_isolation.py`. Run it with `--dry-run` first. It assigns legacy `memory.json`, `agents/`, `skills/` and the global `USER.md` to `--user-id` (default `default`), and moves `threads/` to their recorded owner. Pick the `--user-id` deliberately, because that user inherits everything that used to be shared.
4. **Verify on disk.** After two different signed-in users chat, you should see two directories under `users/`. If you see only `users/default/`, identity isn't reaching memory.
5. **Mind multiple workers.** A separate open RFC, [#2283](https://github.com/bytedance/deer-flow/issues/2283), describes a last-writer-wins race when several worker processes write the same `memory.json`. Per-user files narrow it to one user's concurrent turns, but don't remove it.

## Common questions

**Is DeerFlow memory shared between users?** On current main, not if requests are authenticated: memory lives under `users/{user_id}/`. In no-auth mode everyone is `"default"`, so it is shared.

**Why is issue #1772 still open?** The issue thread doesn't say. As of Oct 28, 2026 it has no closing comment, and its last update was Apr 3, 2026. Treat the source on your installed version as the answer, not the issue state.

**How do I move existing global memory to a user?** Use `backend/scripts/migrate_user_isolation.py --dry-run`, then run it without `--dry-run` and with the `--user-id` you want the legacy data assigned to.

## Skip the plumbing with MemorySync

If you want per-user memory in a managed memory service instead of files on the gateway's disk, MemorySync scopes every user-scoped memory call by an end-user ID (`X-End-User-ID` / `end_user_id`), and its docs recommend a stable opaque ID, not an email address. There's no DeerFlow integration, so you'd call it from your own code. Read the [MemorySync authentication and scoping guide](https://docs.memorysync.io/api/authentication?utm_source=hashnode&utm_medium=organic_page&utm_campaign=v5_oct25&utm_content=pseo_deerflow-per-user-memory-isolation) first. For an overview of MemorySync, see [the MemorySync homepage](https://memorysync.io/?utm_source=hashnode&utm_medium=organic_page&utm_campaign=v5_oct25&utm_content=pseo_deerflow-per-user-memory-isolation).

From the guide:

```python
import os
from memorysync import MemorySyncClient

client = MemorySyncClient(
    api_key=os.environ["MEMORYSYNC_API_KEY"],
    base_url="https://api.memorysync.io",
    project_id=os.environ.get("MEMORYSYNC_PROJECT_ID") or None,
    end_user_id="user-123",
)

result = client.query("What constraints and prior decisions matter for this task?", k=5)
for memory in result.memories:
    print(memory.text)
```

*Snippet adapted from the* [*MemorySync agent memory guide*](https://docs.memorysync.io/guides/agent-memory?utm_source=hashnode&utm_medium=organic_page&utm_campaign=v5_oct25&utm_content=pseo_deerflow-per-user-memory-isolation)*; unverified (not run) for this page. It keeps the guide's* `base_url` *line because* `MemorySyncClient` *requires it.*

Starter template: [memorysyncio/memorysync-first-memory](https://github.com/memorysyncio/memorysync-first-memory?utm_source=hashnode&utm_medium=organic_page&utm_campaign=v5_oct25&utm_content=pseo_deerflow-per-user-memory-isolation).

## Sources

- bytedance/deer-flow#1772, "Support per-user memory isolation for multi-tenant deployment" (open; read 2026-10-28)
- bytedance/deer-flow#2283, "RFC: Single-Writer Memory Queue" (open; read 2026-10-28)
- DeerFlow main @ d4ed400 (2026-10-28): `backend/packages/harness/deerflow/agents/memory/AGENTS.md`, `.../backends/deermem/deermem/config.py`, `.../runtime/user_context.py`, `backend/scripts/migrate_user_isolation.py`, `config.example.yaml`
- MemorySync docs: [docs.memorysync.io/api/authentication](http://docs.memorysync.io/api/authentication)

**Next step:** read the [MemorySync agent memory guide](https://docs.memorysync.io/guides/agent-memory?utm_source=hashnode&utm_medium=organic_page&utm_campaign=v5_oct25&utm_content=pseo_deerflow-per-user-memory-isolation), then [see MemorySync](https://memorysync.io/?utm_source=hashnode&utm_medium=organic_page&utm_campaign=v5_oct25&utm_content=pseo_deerflow-per-user-memory-isolation). Founding offer: use code FOUNDING30 for 30% off Starter for your first 3 months (Settings → Billing).
