## Thursday, December 26, 2013

### How big should a buffer be?

Following on free a previous post on buffer bloat, a good question is: how big should the socket buffer size be? Using my simple JStringServer code, I ran some tests and plotted some graphs and found a sweet spot (for me. YMMV).

As a bit of an aside, the R-language was used to generate the graphs, a task for which it is very well suited. I'm no R expert, so this can probably be done better. But this is what it looks like:

# Aggregate the data and calculate the mean and standard deviation.
# Note: the do.call is to make the data into the right type

attach(do.call(data.frameag <- aggregate(. ~ SO_RCVBU, mydata, function(x) c(mean = mean(x), sd = sd(x)))), warn.conflicts=FALSE)

# Plot the graph calls-per-second (cps) against the server-side SO_RCVBUF
# Note that the x-axis (SO_RCVBUF) uses a logarithmic scale
plot(SO_RCVBUcps.meanlog="x", ylim=c(3000, 5000), ylab="calls per second")

title(main="Mac Book Pro client calls/second vs. server-side SO_RCVBU")

# Add the standard deviations using simple lines
# see http://stat.ethz.ch/R-manual/R-devel/library/graphics/html/segments.html
segments (SO_RCVBU, cps.mean - cps.sd, SO_RCVBU, cps.mean + cps.sd)

# copy the screen to disk (don't forget to close the file handle)
# see http://stackoverflow.com/questions/7144118/how-to-save-a-plot-as-image-on-the-disk
dev.copy(jpeg,filename="~/Documents/Docs/bufferBloat_cps_vs_SO_RCVBU.jpg")
dev.off()

# Now much the same for call duration vs. SO_RCVBUF
plot(SO_RCVBUduration.meanlog="x", ylab="calls duration (ms)")
title(main="Mac Book Pro client call time vs. server-side SO_RCVBUF")
dev.copy(jpeg,filename="~/Documents/Docs/bufferBloat_duration_vs_SO_RCVBU.jpg")
dev.off()

Call times
 Call time (ms) vs SO_RCVBUF value

Throughput
 Number of calls per second vs. SO_RCVBUF
The results were taken from a (old-ish) Mac Book Pro while a (new-ish) Mac Book Air was also stressing the (Linux) server.

The results show that the optimal size for SO_RCVBUF for this application is about 5000. A buffer size too small cripples throughput. But the throughput peaks quite quickly and further increasing it does not seem to help throughput.

Note: significantly increasing the buffer size does not terribly impact performance but I noticed that the client would occasionally throw this nasty exception:

java.io.IOException: Connection reset by peer

(Cause to be determined).

This only happened for large buffer sizes.

R-Statistics blog.
StatMethods