Skip to content

Sync across devices

Sync keeps the same aven tasks available across laptops, agents, and other devices. Each client writes to its own local SQLite database first, so task capture and updates stay fast and offline-friendly.

When you run aven sync, local changes are pushed to a self-hosted server and changes from other clients are pulled back down. The server stores the shared operation log; each local database applies that log to its own task store.

Use Configuration for sync.* and daemon.* settings. See Back up and restore when you need to preserve, move, or recover local data.

Terminal window
aven server --bind 127.0.0.1:0 --data /tmp/aven-server.sqlite

The server stores sync data in the SQLite file passed with --data and prints a listening URL:

listening url=http://127.0.0.1:<port> scope=loopback

Network requirements depend on the bind address:

Scope Use Requirements
Loopback Local testing Authentication optional
Private address LAN, VPN, or another private network sync.auth_token on the server and matching client tokens
Public address Internet-facing service --unsafe-public-bind, sync.auth_token, and TLS or a reverse proxy

Aven does not create or manage the VPN. The server and every client must already be connected to the same private network. This example uses 10.0.0.1 as the server’s VPN address.

First, generate a shared authentication token:

Terminal window
openssl rand -hex 32

Store the generated value in ~/.config/aven/config.yaml on the server:

sync:
auth_token: "<generated-token>"

Start the server on its VPN address, not its loopback address:

Terminal window
mkdir -p ~/.local/state/aven
aven server \
--bind 10.0.0.1:3746 \
--data ~/.local/state/aven/sync-server.sqlite

Run this command under your operating system’s service manager after confirming that sync works. The service must start after the VPN interface is available.

On each client, store the same token and use the server’s VPN address:

sync:
enabled: true
server_url: "http://10.0.0.1:3746"
auth_token: "<generated-token>"
interval_seconds: 30

Verify the network path before testing Aven:

Terminal window
ping 10.0.0.1
nc -vz 10.0.0.1 3746
aven sync

Configure sync with a server your iPhone can reach and a shared sync.auth_token. If using a VPN, connect both devices first.

On your desktop, run:

Terminal window
aven sync pair

Scan the QR code during Aven iOS onboarding. In the TUI, you can also open the command panel with : and choose :pair-mobile.

To pair without a camera, run aven sync pair --copy on your local desktop, transfer the clipboard to your iPhone, and tap Paste during onboarding.

If your desktop’s configured server address is not reachable from your iPhone, override it for the invitation:

Terminal window
aven sync pair --server http://10.0.0.1:3746

Treat the QR code and copied invitation like a password: both contain your shared sync token.

Terminal window
aven sync --server http://127.0.0.1:<port>

When sync.server_url is configured, aven sync can omit --server:

Terminal window
aven sync

Check local health and remaining work without contacting the server:

Terminal window
aven sync status
aven sync status --json

The status report shows whether sync is disabled, unconfigured, healthy, degraded, blocked, or failed. It also shows server pinning, pending changes and images, conflicts, cursor progress, and last attempt and success times. JSON is a versioned report intended for scripts and omits authentication values, task content, sync payloads, and raw server responses.

Images sync automatically but may arrive after their tasks. If an image shows pending download or sync reports complete=false, run aven sync again or let the running daemon finish in the background.

If sync reports attachment-quota-exceeded, increase the relevant storage limit: quota_bytes on the device or server_workspace_quota_bytes on the server.

The daemon performs background sync for the configured local SQLite database.

Terminal window
aven daemon

Daemon sync requires sync.enabled = true and sync.server_url. The wake address must be loopback.

The daemon wakes after successful local mutations when possible, syncs periodically, reschedules incomplete sync quickly, and backs off after failures.

Inspect service installation, configuration, executable consistency, runtime, and log paths without changing the service:

Terminal window
aven daemon status
aven daemon status --json

On macOS, install it as a user LaunchAgent:

Terminal window
aven daemon install
aven daemon restart
aven daemon uninstall

Package scripts can refresh an installed LaunchAgent after replacing the binary:

Terminal window
aven daemon repair --if-installed --program /path/to/aven

The repair command succeeds without changes when the LaunchAgent is absent.

Backup, restore, export, and import guidance lives in Back up and restore.

Conflicts happen when multiple clients edit the same task field between syncs. They are explicit and field based. Inspect conflicts before resolving them.

Terminal window
aven conflict list
aven conflict show APP-7KQ9 --field description
aven conflict diff APP-7KQ9 description
aven conflict export APP-7KQ9 description --dir conflicts
aven conflict resolve APP-7KQ9 description --use local

Use --value, --value-file, or --value-stdin when neither variant is the desired final value.

The TUI also has a conflicts view and conflict actions for human review.

Terminal window
aven doctor
aven doctor --integrity
aven doctor --json

For sync specifically, doctor reports the configured server, sync cursor, pending changes, conflicts, daemon wake validity, and integrity status when requested. A missing current recurring task is repairable by running aven recur list. Other recurring-task integrity failures require preserving the database and recovering from a known-good backup.

Task origins are cli, tui, api, ios, android, and unknown. New iOS queue captures use ios; generic API creation uses api. The android value is reserved as a known client origin, not an indication that an Android app ships. Existing sources stay unchanged because their original client cannot be reliably inferred. Missing source values in older sync records and exports default to unknown. Unrecognized values are rejected.

Sync protocol 18 requires an upgraded server and all participating clients to understand android. Older protocol versions are rejected before changes are exchanged. Upgrade clients before opening an upgraded database or importing an export with an unsupported source. Keep a backup before upgrading if you need to return to an older release. Source is immutable, not an editable field or a dedicated list filter. Metadata named source is independent of task origin.