Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Working over flaky networks

devsync assumes the network will fail. This page lists what happens in each situation.

SituationWhat happens
Network down when you run push/execRetries with exponential backoff (0.5 s up to 30 s, with jitter) until it works, with a message on each retry. Set sync.retries to give up after N attempts
Connection drops during an uploadThe partial file stays staged on the remote; the next attempt resumes from where it stopped. Nothing half-written ever appears in the project
Connection drops while a command runsNothing happens to the command. Output collection pauses and resumes; no output is lost or duplicated
Laptop sleeps during a long jobSame as above: run devsync logs <id> when you’re back
Connection drops right as a command is being starteddevsync can’t know whether the request reached the remote, so it won’t risk starting it twice. It tells you to check devsync jobs --remote
devsync watch while offlineKeeps watching, marks changes pending, shows offline, and sends everything once the link is back
ssh hangs (half-open TCP)Keepalives detect a dead link in ~15 s; each response also has a timeout (ssh.response_timeout_secs)
Remote rebooted mid-jobThe job shows as lost
Wrong password, key or host keyNot retried; reported immediately with a hint

| The shared ssh connection breaks (network change, dead TCP, server session limit) | devsync closes it and opens a fresh one; if that fails too it connects directly for 5 minutes | | An agent upload is cut off | The upload is checked before it’s installed; a truncated agent already on the remote is detected by size and replaced. Uploads are gzip-compressed, and local devsync processes take turns uploading | | devsync is updated while VS Code’s auto sync runs | The extension notices the new binary and restarts auto sync on it |

On high-latency links (VPNs, Tailscale relays) each new ssh connection can take 10–20 s, while sessions on the shared connection cost one round trip. Keep ssh.multiplex = true and a long ssh.control_persist_secs (default 600) so the connection setup is paid rarely.

Retrying now

While offline, devsync watch says when it will try next. Press Enter in its terminal to retry immediately (VS Code: Retry now). One-off commands (push, pull, exec) retry on their own with backoff.

Seeing progress

In a terminal, pushes and pulls draw a live line with a progress bar, files and bytes done, speed, time left and the current file. Up to 200 files are also listed one per line (all of them with -v). Set DEVSYNC_NO_PROGRESS=1 to turn the live line off. With --json, progress events carry the same numbers.

Remote terminals

devsync shell (and Terminal in VS Code) is the one place an ssh session stays open, so on a bad link it will drop. When it does, devsync says so and reconnects into the same folder, waiting longer each time (Ctrl-C to stop).

To keep the shell itself, and whatever runs in it, alive across drops, set ssh.persistent_shell = true. With tmux installed on the remote, the shell runs in a tmux session (status bar hidden, mouse scrolling on) and reconnecting attaches to it again. For long jobs, devsync exec / devsync submit are still the most robust: they need no open connection at all.

Tuning

[ssh]
connect_timeout_secs = 60       # slow links / satellite (devsync also raises it by itself after a timeout)
response_timeout_secs = 300     # huge trees on slow disks
multiplex = true                # reuse one TCP connection for short sessions
control_persist_secs = 600      # keep that connection this long when idle

[sync]
retries = 0                     # 0 = keep trying; e.g. 5 to fail fast in scripts

Multiplexing saves an ssh handshake per operation. If your network kills idle connections aggressively, lower control_persist_secs; correctness never depends on it.

Mobile hotspots, VPNs, captive portals

  • If the IP changes (hotspot to Wi-Fi), the next session simply connects again. Running jobs are unaffected.
  • If ssh access needs a VPN, connect it first. While it’s down, devsync waits and retries.
  • Jump hosts work through ~/.ssh/config (ProxyJump) or ssh.options = ["ProxyJump=bastion"].