Copy a 200 MB file and it flies. Run git status in that same directory and the wait is long enough to context-switch away from it. Those two observations are not contradictory, because bulk transfer measures throughput while Git measures how many small filesystem questions it can ask per second, and a mounted remote tree turns every question into a round trip. Tuning the VPN will not fix a workload shaped wrong.

Why status is the wrong benchmark

Git has to learn about many files: which are modified, which are untracked, and whether cached index data still matches what sits on disk. Over SSHFS each of those observations can be a network operation. The unit of work here is the file count, not the megabytes.

That is why the first status after a clone is slow, and why later ones can be slower still in a tree full of build output. Untracked scanning walks directories you may not care about, and every walk step is another request across the link. On a 40 ms path a tree with a few thousand entries becomes a few thousand round trips. No packet capture is needed to confirm that arithmetic.

A download benchmark tells you the link is fine; it says nothing about whether a thousand small reads will finish this afternoon.

Move the working tree, not the tuning knobs

A local clone puts the working tree, the index and the Git operations on the same machine. A pull becomes a visible network step instead of every file check becoming one.

This fits whenever the developer can keep the required source locally, which is most of the time. It also sharpens the commit and deployment boundary, because editing a local file no longer changes a running remote service by accident; the change has to be pushed and deployed like anything else. The trade is that the code exists in two places, so decide which copy is authoritative and how a hotfix on the server gets back into the repository. That conversation is cheaper than a status command nobody wants to run.

If the workspace must stay remote, run Git there

Sometimes the workspace cannot move: the build needs that environment, the data is too big, or policy keeps the source on the host. Then run Git and the relevant development tools next to the files, through an approved remote shell or a remote-development environment. The editor can stay on the laptop while its backend works beside the working tree.

Expensive operations then happen locally on the remote host, and the network carries editor traffic instead of thousands of stat calls. It is the same fix as a local clone, expressed as a deployment choice rather than a migration.

Sync is a workflow with owners, not a cache

A synchronized workspace can cut repeated remote reads, but it is not a transparent cache. It needs an owner for each change, a rule for conflicts, and an agreement on generated files that both sides believe they own. Without those rules the arrangement creates disagreement rather than convenience.

A two-way synchronizer without them produces a different problem from the one it solved, usually a merge nobody can attribute. Avoid running two Git processes against one shared working tree unless you understand how they coordinate.

Then tune, and keep SSH sane

After the arrangement is right, two settings change how many files Git has to ask about: status.showUntrackedFiles and the untracked cache behind core.untrackedCache. Neither changes what each question costs across 40 ms; they only change how many questions there are. Pull a knob only once the round trips are local.

Time the command that annoys you rather than reasoning from a benchmark that copies one big file, and leave supported SSH encryption alone. An obsolete cipher does not shorten a round trip; it adds a second problem that outlives the first. The Git status reference is worth one read, because the command does far more work than its name suggests.

متعلقہ مضامین