sftp performance problem, cured by TCP_NODELAY

Miklos Szeredi miklos at szeredi.hu
Wed Jan 25 02:22:37 EST 2006

In certain situations sftp download speed can be much less than that
of scp.

After many days of trying to find the cause finally I found it to be
the tcp nagle algorithm, which if turned off with TCP_NODELAY
eliminates the problem.

Now I see it being discussed back in 2002, but it still unresolved in
openssh-4.2 :(

Simple solution would be to add a NoDelay option to ssh which sftp
would set.  The proprietary ssh seems to already have this option.

Attached an LD_PRELOAD hack to set TCP_NODELAY.  For me this hack
doubles the download speed of a 100MB file over a 100Mbps network.


/* gcc -Wall -W -o sshnodelay.so --shared -ldl sshnodelay.c */
#define _GNU_SOURCE
#include <dlfcn.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>

int connect(int sock, const struct sockaddr *addr, socklen_t addrlen)
    int (*next_connect)(int, const struct sockaddr *, socklen_t) =
        dlsym(RTLD_NEXT, "connect");
    int res = next_connect(sock, addr, addrlen);
    if (addr->sa_family == AF_INET) {
        int opt = 1;
        setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt));
    return res;

$ time sftp -b /tmp/big100M.b server
sftp> get big100M /dev/null
Fetching /tmp/big100M to /dev/null

real    0m18.231s
user    0m6.248s
sys     0m1.684s
$ time LD_PRELOAD=/tmp/sshnodelay.so sftp -b /tmp/big100M.b server
sftp> get big100M /dev/null
Fetching /tmp/big100M to /dev/null

real    0m9.001s
user    0m6.320s
sys     0m1.840s

More information about the openssh-unix-dev mailing list