---
title: "Cloud Sync Guide"
description: "Guide to syncing your local Basic Memory projects with Basic Memory Cloud."
canonical_url: "https://docs.basicmemory.com/cloud/cloud-sync"
---
# Cloud Sync Guide

> Guide to syncing your local Basic Memory projects with Basic Memory Cloud.

The Basic Memory Cloud CLI provides seamless integration between local and cloud knowledge bases using **project-scoped synchronization**. Each project can optionally sync with the cloud, giving you fine-grained control over what syncs and where.

---

## Overview

The cloud CLI enables you to:

- **Per-project routing** - Route individual projects through cloud with `bm project set-cloud`; the rest stay local
- **Project-scoped sync** - Each project independently manages its sync configuration
- **Explicit operations** - Sync only what you want, when you want
- **Team-safe push/pull** - Additive, git-style transfers that work on Personal and Team workspaces alike
- **Offline access** - Work locally, sync when ready

### The sync commands

<table>
<thead>
  <tr>
    <th>
      Command
    </th>
    
    <th>
      Direction
    </th>
    
    <th>
      Behavior
    </th>
    
    <th>
      Personal
    </th>
    
    <th>
      Team
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        bm cloud pull
      </code>
    </td>
    
    <td>
      cloud → local
    </td>
    
    <td>
      <strong>
        additive
      </strong>
      
       — never deletes local
    </td>
    
    <td>
      ✅
    </td>
    
    <td>
      ✅
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        bm cloud push
      </code>
    </td>
    
    <td>
      local → cloud
    </td>
    
    <td>
      <strong>
        additive
      </strong>
      
       — never deletes cloud
    </td>
    
    <td>
      ✅
    </td>
    
    <td>
      ✅
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        bm cloud prune
      </code>
    </td>
    
    <td>
      cloud cleanup
    </td>
    
    <td>
      Deletes cloud files matching this machine's <code>
        .bmignore
      </code>
    </td>
    
    <td>
      ✅
    </td>
    
    <td>
      ❌
    </td>
  </tr>
</tbody>
</table>

**push and pull are the supported sync workflow.** They are additive — they never delete files on the destination — and conflict-aware, so they are safe everywhere, including shared Team workspaces where a mirror operation could delete a teammate's files.

<warning>

**bm cloud sync, bm cloud bisync, and bm cloud bisync-reset are deprecated as of v0.24** and will be removed in a future release. They are marked deprecated in `--help` and print a notice pointing at `pull`/`push` on every run. They still work on Personal workspaces; on Team workspaces they exit with that notice. Move scripts and habits to `bm cloud pull` / `bm cloud push` now. See [Upgrading to v0.24](https://docs.basicmemory.com/whats-new/v0-24-upgrade).

</warning>

---

## Prerequisites

Before using Basic Memory Cloud sync, you need:

- **Active Subscription**: An active Basic Memory Cloud subscription
- **Subscribe**: Visit [basicmemory.com/subscribe](https://basicmemory.com/subscribe?utm_source=docs&utm_medium=docs&utm_campaign=cloud-sync)
- **Basic Memory CLI**: See [Install Basic Memory locally](https://docs.basicmemory.com/local/local-install) for installation

<warning>

If you attempt to log in without an active subscription, you'll receive a "Subscription Required" error.

</warning>

### When to Use Sync

<tip>

**Sync is designed for hybrid workflows** where you want to edit files locally (in tools like Obsidian or VS Code) while keeping cloud in sync.

**Use sync when:**

- You want to edit notes locally in your preferred editor
- You want changes to flow both ways (pull cloud changes down, push local changes up)
- You're working with large knowledge bases
- You want offline access with periodic syncing

**Alternatives to sync:**

- **Web App**: Upload and edit files in the [Cloud web app](https://docs.basicmemory.com/cloud/web-app)
- **MCP Tools Only**: Use AI assistants to manage notes entirely in cloud

</tip>

---

## Architecture: Project-Scoped Sync

### How It Works

Projects can exist in three states:

1. **Cloud-only** - Project exists on cloud, no local copy
2. **Cloud + Local (synced)** - Project has a local working directory that syncs
3. **Local-only** - Project exists only on your machine (the default for `bm project add`)

**Example:**

```bash
# You have 3 projects on cloud:
# - research: wants local sync at ~/Documents/research
# - work: wants local sync at ~/work-notes
# - temp: cloud-only, no local sync needed

bm cloud sync-setup research ~/Documents/research
bm cloud sync-setup work ~/work-notes
# temp needs no setup — it stays cloud-only

# Now you can sync individually:
bm cloud pull --name research
bm cloud pull --name work
```

**What happens under the covers:**

- Config stores each project as an entry with a `local_sync_path` in `~/.basic-memory/config.json`
- Rclone transfers files using a tenant-scoped remote per workspace (`basic-memory-cloud` for your Personal workspace)
- Projects can live anywhere on your filesystem

---

## Quick Start

### 1. Sign in to Cloud

Authenticate the CLI:

```bash
bm cloud login
```

**What this does:**

1. Opens browser to Basic Memory Cloud authentication page
2. Stores authentication token
3. Validates your subscription status

Login doesn't change project routing or start syncing — projects stay local unless you route or sync them explicitly.

### 2. Set Up Sync

Install rclone and configure credentials:

```bash
bm cloud setup
```

**What this does:**

1. Installs rclone automatically (if needed)
2. Fetches your tenant information from cloud
3. Generates scoped S3 credentials for sync
4. Configures a tenant-scoped rclone remote for the workspace (`basic-memory-cloud` for your Personal workspace)

<note>

**Team workspaces skip this step.** `bm cloud setup` provisions the rclone remote used by Personal-workspace transfers. On a Team workspace, `push` and `pull` run over the cloud's permissioned WebDAV API instead — no rclone remote and no storage credentials — and every request is authorized against your access to that specific project: read access is enough to `pull`, edit access is required to `push`. New in v0.23; previously Team push/pull required owner-only storage credentials, so most members couldn't run them at all.

</note>

### 3. Add Projects with Sync

Create projects with optional local sync paths:

```bash
# Create cloud project without local sync
bm project add research --cloud

# Create cloud project WITH local sync
bm project add research --cloud --local-path ~/Documents/research

# Or configure sync for an existing cloud project
bm cloud sync-setup research ~/Documents/research
```

### 4. Pull the Project Down

Fetch the cloud copy into your local directory. **Preview with --dry-run first:**

```bash
# Step 1: Preview what would transfer
bm cloud pull --name research --dry-run

# Step 2: Fetch cloud files into your local directory
bm cloud pull --name research
```

`pull` is additive — it fetches new and changed files without deleting anything local.

### 5. Daily Workflow

Pull before you start, edit locally, push when you're done:

```bash
# Fetch changes made in the web app, by MCP tools, or by teammates
bm cloud pull --name research

# ... edit files locally ...

# Upload your changes to the cloud
bm cloud push --name research
```

**What happens on push:**

1. New and changed local files transfer to cloud
2. If a file differs on both sides, the command aborts and lists the conflicts
3. The cloud instance detects the new files and reindexes them automatically

<note>

**Reindexing after sync**: Basic Memory automatically reindexes all synced changes to update the knowledge graph.

</note>

### 6. Verify Setup

```bash
bm cloud status
```

You should see:

- `OAuth: token valid`
- `Cloud connected`

---

## File Synchronization

### Understanding the Sync Commands

<table>
<thead>
  <tr>
    <th>
      Command
    </th>
    
    <th>
      Direction
    </th>
    
    <th>
      Use Case
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        bm cloud pull
      </code>
    </td>
    
    <td>
      Cloud → Local
    </td>
    
    <td>
      Fetch cloud changes additively (Personal + Team)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        bm cloud push
      </code>
    </td>
    
    <td>
      Local → Cloud
    </td>
    
    <td>
      Upload local changes additively (Personal + Team)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        bm cloud prune
      </code>
    </td>
    
    <td>
      Cloud cleanup
    </td>
    
    <td>
      Delete files that match this machine's <code>
        .bmignore
      </code>
      
       (Personal only)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        bm cloud check
      </code>
    </td>
    
    <td>
      Verify
    </td>
    
    <td>
      Legacy checksum comparison (Personal only)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        bm cloud sync
      </code>
    </td>
    
    <td>
      Local → Cloud
    </td>
    
    <td>
      <strong>
        Deprecated
      </strong>
      
       one-way mirror (Personal only)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        bm cloud bisync
      </code>
    </td>
    
    <td>
      Both ways
    </td>
    
    <td>
      <strong>
        Deprecated
      </strong>
      
       bidirectional mirror (Personal only)
    </td>
  </tr>
</tbody>
</table>

### Push and Pull (Additive, Git-Style)

`push` and `pull` model `git push` / `git pull`:

```bash
# Preview what would transfer
bm cloud pull --name research --dry-run

# Fetch cloud changes into your local directory
bm cloud pull --name research

# Upload your local changes to the cloud
bm cloud push --name research
```

Both commands are additive — they never delete files on the destination. New and changed files transfer; if any file differs on both sides, the command aborts and lists the conflicts, like a rejected `git push`.

The transport depends on the workspace, but the commands and flags are identical. Personal-workspace transfers run through the tenant-scoped rclone remote configured by `bm cloud setup`. Team-workspace transfers (v0.23+) run over the cloud's WebDAV API, where each request is checked against your access to that project — members with read access can `pull`, members with edit access can `push`, and no `bm cloud setup` is needed.

<tip>

**Team push and pull are much faster in v0.24.** The project is listed with a single recursive request instead of one request per directory, eight files transfer at once, and file bodies stream to and from disk so memory use doesn't grow with file size. If the cloud rate-limits a transfer, the CLI waits out the `Retry-After` interval instead of aborting. If the project is too large to list in one request, the command stops with a message naming the cause.

</tip>

**Resolving conflicts:** re-run with `--on-conflict` to choose what survives. The value names what is kept, so it reads the same in both directions:

<table>
<thead>
  <tr>
    <th>
      Value
    </th>
    
    <th>
      Behavior
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        fail
      </code>
      
       (default)
    </td>
    
    <td>
      Abort and list conflicting files
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        keep-cloud
      </code>
    </td>
    
    <td>
      Take the cloud version (pull: overwrite local; push: skip those files)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        keep-local
      </code>
    </td>
    
    <td>
      Keep the local version (pull: skip those files; push: overwrite cloud)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        keep-both
      </code>
    </td>
    
    <td>
      Keep both versions, renaming one copy
    </td>
  </tr>
</tbody>
</table>

```bash
# A teammate edited notes you also changed locally — pull reports a conflict:
bm cloud pull --name research
# pull aborted: 1 file(s) differ between local and cloud.

# Take the cloud version:
bm cloud pull --name research --on-conflict keep-cloud

# Or keep both copies to merge by hand:
bm cloud pull --name research --on-conflict keep-both
```

<note>

`push`/`pull` are deliberately simple, conflict-aware transfers — not a full reconciler. They compare the current state of both sides without a sync baseline. Use `--dry-run` to preview differences before transferring (the legacy `bm cloud check` is Personal-only).

</note>

### Deprecated mirror commands

`bm cloud sync` (one-way mirror: make cloud identical to local, deleting cloud files missing locally), `bm cloud bisync` (bidirectional mirror), and `bm cloud bisync-reset` are deprecated as of v0.24. They still run on Personal workspaces and print a deprecation notice each time; on Team workspaces they exit with the notice. Use `pull` and `push` instead:

<table>
<thead>
  <tr>
    <th>
      If you ran
    </th>
    
    <th>
      Run instead
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        bm cloud sync --name research
      </code>
    </td>
    
    <td>
      <code>
        bm cloud push --name research
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        bm cloud bisync --name research
      </code>
    </td>
    
    <td>
      <code>
        bm cloud pull --name research
      </code>
      
      , then <code>
        bm cloud push --name research
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        bm cloud bisync-reset research
      </code>
    </td>
    
    <td>
      Nothing — <code>
        pull
      </code>
      
      /<code>
        push
      </code>
      
       keep no baseline to reset
    </td>
  </tr>
</tbody>
</table>

`push` never deletes cloud files. To remove cloud files that match a newly added `.bmignore` pattern, use `bm cloud prune` (below). To delete individual notes, delete them in the [web app](https://docs.basicmemory.com/cloud/web-app) or with the `bm_delete` MCP tool.

<warning>

Until it is removed, `bm cloud sync` still deletes a previously synced cloud file when it becomes ignored by `.bmignore` (v0.23 behavior). Preview with `--dry-run` if you still run it.

</warning>

### Prune newly ignored cloud files

Use `prune` when you want only the `.bmignore` cleanup without a full mirror sync:

```bash
# Show the exact remote paths that match this machine's ignore file
bm cloud prune --name research --dry-run

# Show the paths again, then ask for confirmation before deletion
bm cloud prune --name research

# Skip the confirmation prompt after reviewing a dry run
bm cloud prune --name research --yes
```

`prune` can run without a configured local sync directory because it inspects remote paths against `~/.basic-memory/.bmignore`. It is Personal-workspace-only and permanently deletes only the exact paths shown in its preview.

### Preview Changes (Dry Run)

```bash
bm cloud pull --name research --dry-run
bm cloud push --name research --dry-run
```

Shows what would transfer without actually syncing.

### Verify Integrity

```bash
bm cloud check --name research
```

Compares file checksums against the Personal-workspace mirror remote without making changes. This is a legacy command tied to the deprecated mirror workflow; `bm cloud pull --dry-run` and `bm cloud push --dry-run` are the preferred way to preview differences on any workspace.

---

## Multiple Projects

### Syncing Multiple Projects

```bash
# Setup multiple projects
bm project add research --cloud --local-path ~/Documents/research
bm project add work --cloud --local-path ~/work-notes
bm project add personal --cloud --local-path ~/personal

# Daily workflow: pull, edit, push
bm cloud pull --name research
bm cloud pull --name work
bm cloud pull --name personal

# ... edit locally ...

bm cloud push --name research
bm cloud push --name work
bm cloud push --name personal
```

### Mixed Usage

```bash
# Projects with sync
bm project add research --cloud --local-path ~/Documents/research
bm project add work --cloud --local-path ~/work

# Cloud-only projects
bm project add archive --cloud
bm project add temp-notes --cloud

# Sync only the configured ones
bm cloud pull --name research
bm cloud pull --name work
# archive and temp-notes stay cloud-only
```

---

## Filter Configuration

### Understanding .bmignore

Basic Memory uses `.bmignore` for global ignore patterns (similar to `.gitignore`).

**Location:** `~/.basic-memory/.bmignore`

**Default patterns:**

```gitignore
# Hidden files and version control
.*
.git

# Python
__pycache__
*.pyc
.venv

# Node.js
node_modules

# Basic Memory internals
*.db
*.db-shm
*.db-wal
config.json

# Editors and OS files
.obsidian
.DS_Store
*.tmp
```

<note>

Basic Memory also respects `.gitignore` files in your projects. Use `.bmignore` for global patterns across all projects.

</note>

Patterns follow `.gitignore` escaping: `\#*#` matches files that start with `#`, and a backslash keeps leading or trailing whitespace. Emacs autosave files (`#note.md#`) are never indexed.

<warning>

A file that was uploaded before you added a matching `.bmignore` rule stays in the cloud — `push` won't upload it again, but it won't delete it either. Remove it on demand with `bm cloud prune` (or the deprecated `bm cloud sync`). Always preview with `--dry-run` before deleting.

</warning>

---

## Troubleshooting

### Authentication Issues

**Problem:** Authentication failed or Invalid token

**Solution:**

```bash
bm cloud logout
bm cloud login
```

### Push or Pull Reports Conflicts

**Problem:** "pull aborted: N file(s) differ between local and cloud"

**Solution:** This is the conflict guard working as intended. Preview the differences, then choose what survives:

```bash
bm cloud pull --name research --dry-run
bm cloud pull --name research --on-conflict keep-both
```

### Project Not Configured for Sync

**Problem:** "Error: Project 'research' has no local sync path configured"

**Solution:**

```bash
bm cloud sync-setup research ~/Documents/research
bm cloud pull --name research
```

### Workspace Is Not Set Up for Sync

**Problem:** "Workspace '...' is not set up for sync."

**Solution:** A Personal workspace's rclone remote hasn't been provisioned yet:

```bash
bm cloud setup
```

Team workspaces never need `bm cloud setup` — their `push`/`pull` run over the permissioned WebDAV API, so this error only appears on the Personal path.

---

## Sign out

```bash
bm cloud logout
```

Logout removes your stored OAuth tokens (a saved API key survives and keeps routing cloud projects). It doesn't change project routing — to route a project locally again, use `bm project set-local <name> --local-path <path>`.

---

## Security

- **Authentication**: OAuth 2.1 with PKCE flow
- **Tokens**: Stored securely in `~/.basic-memory/basic-memory-cloud.json`
- **Transport**: All data encrypted in transit (HTTPS)
- **Credentials**: Personal transfers use scoped S3 credentials (read-write to your tenant only); Team transfers use your OAuth session over WebDAV with per-project access checks
- **Isolation**: Your data isolated from other tenants
- **Ignore patterns**: Sensitive files excluded via `.bmignore`

---

## Command Reference

### Cloud Mode Management

```bash
bm cloud login              # Authenticate and enable cloud mode
bm cloud logout             # Disable cloud mode
bm cloud status             # Check cloud mode and instance health
```

### Setup

```bash
bm cloud setup              # Install rclone and configure credentials
```

### Project Setup

```bash
bm project add <name> --cloud                     # Create cloud project (no sync)
bm project add <name> --cloud --local-path <path> # Create with local sync
bm cloud sync-setup <name> <path>                 # Add sync to an existing cloud project
```

Full project and auth commands (list, remove, login, status): [CLI Reference](https://docs.basicmemory.com/reference/cli-reference).

### File Synchronization

```bash
# Standard workflow (Personal + Team)
bm cloud pull --name <project>            # Fetch cloud changes (additive)
bm cloud push --name <project>            # Upload local changes (additive)
bm cloud pull --name <project> --dry-run
bm cloud push --name <project> --dry-run
bm cloud pull --name <project> --on-conflict keep-both

# Targeted deletion of cloud files matching ~/.basic-memory/.bmignore
bm cloud prune --name <project> --dry-run
bm cloud prune --name <project>

# Legacy integrity check (Personal only; prefer pull/push --dry-run)
bm cloud check --name <project>

# Deprecated (v0.24) — use pull/push instead
# bm cloud sync --name <project>
# bm cloud bisync --name <project>
# bm cloud bisync-reset <project>

# List remote files
bm project ls --name <project>
```

---

## Summary

**Basic Memory Cloud uses project-scoped sync:**

1. **Sign in** - `bm cloud login`
2. **Install rclone** - `bm cloud setup` (Personal workspaces; Team push/pull needs no setup)
3. **Add projects with sync** - `bm project add research --cloud --local-path ~/Documents/research`
4. **Preview the first pull** - `bm cloud pull --name research --dry-run`
5. **Pull the project down** - `bm cloud pull --name research`
6. **Daily workflow** - pull, edit locally, then `bm cloud push --name research`

**Key benefits:**

- Each project independently syncs (or doesn't)
- Projects can live anywhere on disk
- Explicit sync operations (no magic)
- Safe by design (additive transfers, conflict guard)
- Full offline access (work locally, sync when ready)

---

## Next Steps

<card-group>
<card icon="i-lucide-cloud" title="Cloud Guide" to="https://docs.basicmemory.com/cloud/cloud-guide">

Cloud features and setup options.

</card>

<card icon="i-lucide-terminal" title="CLI Reference" to="https://docs.basicmemory.com/reference/cli-reference">

Complete CLI command reference.

</card>

<card icon="i-lucide-hexagon" title="Obsidian Integration" to="https://docs.basicmemory.com/integrations/obsidian">

Use cloud sync with Obsidian.

</card>

<card icon="i-lucide-code" title="VS Code Integration" to="https://docs.basicmemory.com/integrations/vscode">

Use cloud sync with VS Code.

</card>
</card-group>


## Sitemap

See the full [sitemap](https://docs.basicmemory.com/sitemap.md) for all pages.
