
Sendfile: a system call for web developers to know about - Symmetry
http://jvns.ca/blog/2016/01/23/sendfile-a-new-to-me-system-call/
======
tyingq
Related...Apache, nginx, and probably other web servers can be coerced into
handling sendfile() for you.

[https://tn123.org/mod_xsendfile/](https://tn123.org/mod_xsendfile/)
[https://www.nginx.com/resources/wiki/start/topics/examples/x...](https://www.nginx.com/resources/wiki/start/topics/examples/xsendfile/#)

~~~
mixmastamyk
That nginx config is hard to grok. Is it really that complicated and not just
"sendfile = on" ?

~~~
dividuum
If you have a public url for a file, then you can just point your users to
that url and use sendfile=on. Nginx will then use sendfile.

But consider the usecase where you have a bigger download hidden behind some
kind of authentication. You'd do that authentication in your normal backend
and return the X-Accel-Redirect header in your response. Nginx will then take
over and send the data using sendfile.

------
luckydude
This is really old but the article mentions splice() and here's the original
thinking on that syscall. Linux didn't take all the ideas but they took some:

[http://www.mcvoy.com/lm/bitmover/lm/papers/splice.pdf](http://www.mcvoy.com/lm/bitmover/lm/papers/splice.pdf)

~~~
joveian
Or even earlier there is "Exploiting In-Kernel Data Paths to Improve I/O
Throughput and CPU Availability" by Fall and Pasquale:
[https://cseweb.ucsd.edu/~pasquale/Research/Papers/usenix93.p...](https://cseweb.ucsd.edu/~pasquale/Research/Papers/usenix93.pdf)

------
amelius
Seems quite useless to me. For, what if you want to prefix the file with a
header first, or add a trailer? Or what if you want to escape certain parts,
or zip the file before sending? Or if you want to send the file incrementally?

It is better (more powerful) to have simple primitives, and work up from them.

If you really want something like sendfile, you could also just find the right
library.

~~~
luckydude
Any well written server application eventually comes down to how fast can you
copy the data. This avoids a copy so it can double performance.

As for headers/trailers, it's a file descriptor, nothing prevents you from
writing to it before or after the sendfile() call.

Simple primitives are fine but this is faster. Unless you are going to do the
page flipping tricks that Irix did, you can't approach this speed (and Irix
tricks aren't as fast as this, better than the bcopy() but not as fast as
this).

~~~
Matthias247
Reality is sometimes a bit different from theory here. Let's say you want to
send a small amount of data (1k) from a file to network, some header before it
and some trailer behind it. With sendfile you would do three system calls, two
normal writes and a sendfile. Without it you would read the file, copy the
content, the header and the trailer into a single buffer and issue a single
write syscall with it (of course you have the read call before). Due to the
lower number of write calls this __could __be faster then sendfile, as copying
a small amount of data might yield a lower overhead then multiple write
requests. Of course that situation will change depending on the amount of data
- so I think sendfile is one possible optimization that should be benchmarked
for the particular application before using it everywhere.

~~~
paulddraper
Three syscalls instead of one will probably not make a difference. Copying a
50mb file multiple times will.

~~~
ryanpetrich
But they aren't free and if the file size is sufficiently small, the overhead
of the constant overhead of the additional syscalls will dwarf the variable
overhead of the extra copy. FreeBSD/OS X's sendfile allows specifying a header
and trailer in a single syscall to avoid this limitation.

~~~
paulddraper
I'd be interested in reading how small the file has to be for this to be
necessary.

