Opening a shared folder over the VPN and waiting while the directory listing crawls is a familiar experience, and the first instinct is to blame bandwidth. Usually the link is mostly idle. The protocol spends its time waiting for replies, and each wait costs a full round trip the LAN never charged. Fix the shape of the work and the share becomes usable again.

The remote working copy is the wrong shape

SMB opens files, reads metadata and acknowledges in many small exchanges. A version-control working copy on a mapped drive assumes local filesystem latency and reads many small files. A desktop database pulls pages as the user works. Each of those turns delay into a multiplier, because the cost grows with how many exchanges the operation performs; a 40 ms tunnel therefore turns a few hundred operations into several seconds. Payload size is almost irrelevant in that arithmetic.

Encryption overhead is a small part of it; loss is worse, because one retransmission plus a collapsed congestion window costs far more than the bytes involved.

Count round trips before megabytes

Measure the delay before buying capacity. A single ping tells you what every exchange pays.

ping -c 10 fileserver.example.net

The summary gives minimum, average and maximum round-trip times, and the spread matters as much as the average. Multiply the average by the number of exchanges a directory listing performs, then compare it with the time you actually observe. If one large file transfers quickly while browsing is slow, latency and request count are the constraint. Adding ten times the capacity to a link that never saturates changes nothing at all.

Move the work, not the bytes

Change where the work happens instead of paying for more pipe. Serve the repository rather than mounting it, and copy in bulk with a tool that sends only differences.

rsync -av --info=progress2 ./project/ [email protected]:/srv/share/project/

Serving the repository, as hgweb or a Git remote does, lets the client work on a local clone so its filesystem calls never cross the tunnel. rsync walks both sides and ships changed blocks, eliminating most of the exchanges a naive copy pays for. A desktop database belongs on a server-side engine with the client reduced to a front end, or the whole client runs on an internal host. Each option changes how much latency the protocol is exposed to, which is the point.

Hangs near the same size are an MTU symptom

Large transfers that stall after roughly the same amount of data, while pings and small pages work, point at packet size rather than bandwidth.

ping -M do -s 1400 -c 3 fileserver.example.net

A successful probe means a 1428-byte IP packet crosses the path unfragmented, since ICMP and IP headers add 28 bytes. A failure with the do-not-fragment flag suggests the tunnel's usable MTU is smaller than the server assumes. A server sending 9000-byte buffers onto a 1500-byte path forces fragmentation or drops, and path MTU discovery can fail silently when ICMP is filtered. Lower the tunnel MTU, enable mssfix on OpenVPN, or shrink the server buffers, then rerun the same transfer to confirm.

Measure the gap that matters

Run the same operation three ways where policy allows: locally, across the tunnel and over a direct internet path. For each, note the round-trip time, the rate of one large stream, and how long a directory listing or an application open takes. Comparing the local run with the tunnel run shows which cost dominates. A copy that finishes slowly suggests a rate or delay problem, while a copy that dies at a consistent point suggests packet size or a stateful device in the path.

When just the opening megabytes drag, look at authentication and metadata; when everything crawls, look at capacity and loss. Fix the matching cause, and stop expecting a WAN link to behave like a LAN cable.

Nsɛm a ɛfa ho