diff --git a/web/ons-demo/js/iperf.js b/web/ons-demo/js/iperf.js
new file mode 100644
index 0000000..c2abaa7
--- /dev/null
+++ b/web/ons-demo/js/iperf.js
@@ -0,0 +1,178 @@
+var enableIPerfLog = false;
+
+function iperfLog(message) {
+	if (enableIPerfLog) {
+		console.log(message);
+	}
+}
+
+function hasIPerf(flow) {
+	return flow && flow.iperfFetchTimeout;
+}
+
+function clearIPerf(flow) {
+	iperfLog('clearing iperf interval for: ' + flow.flowId);
+	clearTimeout(flow.iperfFetchTimeout);
+	delete flow.iperfFetchTimeout;
+	clearInterval(flow.iperfDisplayInterval);
+	delete flow.iperfDisplayInterval;
+	delete flow.iperfData;
+}
+
+function startIPerfForFlow(flow) {
+	var duration = 10000; // seconds
+	var interval = 100; // ms. this is defined by the server
+	var updateRate = 3000; // ms
+	var pointsToDisplay = 1000;
+
+	function makeGraph(iperfData) {
+		var d = 'M0,0';
+
+		var now = flow.iperfData.startTime + (Date.now() - flow.iperfData.localNow)/1000;
+
+		if (iperfData.samples && iperfData.samples.length) {
+
+			var lastX;
+			var i = iperfData.samples.length - 1;
+			while (i) {
+				var sample = iperfData.samples[i];
+
+				var x = (1000 - (now - sample.time)*10);
+				// workaround for discontinuity in iperf data
+				if (x < 0) {
+					i -= 1;
+					continue;
+				}
+
+				var y = 28 * sample.value/1000000;
+				if (y > 28) {
+					y = 28;
+				}
+				if (i == iperfData.samples.length - 1) {
+					d = 'M' + x + ',30';
+				}
+
+				// handle gaps
+				// 1.5 for rounding error
+				if (lastX && lastX - x > 1.5) {
+					d += 'L' + lastX + ',30';
+					d += 'M' + x + ',30'
+				}
+				lastX = x;
+
+				d += 'L' + x + ',' + (30-y);
+
+				i -= 1;
+			}
+			d += 'L' + lastX + ',30';
+		}
+		return d;
+	}
+
+	if (flow.flowId) {
+		iperfLog('starting iperf for: ' + flow.flowId);
+		startIPerf(flow, duration, updateRate/interval);
+		flow.iperfDisplayInterval = setInterval(function () {
+			if (flow.iperfData) {
+				var iperfPath = d3.select(document.getElementById(makeSelectedFlowKey(flow))).select('path');
+				iperfPath.attr('d', makeGraph(flow.iperfData));
+			}
+
+
+		}, interval);
+
+		var animationTimeout;
+		flow.iperfData = {
+			samples: []
+		}
+
+		var lastTime;
+		function fetchData() {
+			iperfLog('Requesting iperf data');
+			var fetchTime = Date.now();
+			getIPerfData(flow, function (data) {
+				var requestTime = Date.now() - fetchTime;
+				var requestTimeMessage = 'iperf request completed in: ' + requestTime + 'ms';
+				if (requestTime > 1000) {
+					requestTimeMessage = requestTimeMessage.toUpperCase();
+				}
+				iperfLog(requestTimeMessage);
+
+				if (!flow.iperfData) {
+					iperfLog('iperf session closed for flow: ' + flow.id);
+					return;
+				}
+
+				try {
+					var iperfData = JSON.parse(data);
+
+//				iperfLog(iperfData.timestamp);
+
+					// if the data is fresh
+					if (!(flow.iperfData.timestamp && iperfData.timestamp != flow.iperfData.timestamp)) {
+						if (!flow.iperfData.timestamp) {
+							iperfLog('received first iperf buffer');
+						} else {
+							iperfLog('received duplicate iperf buffer with timestamp: ' + iperfData.timestamp);
+						}
+					} else {
+						iperfLog('received new iperf buffer with timstamp: ' + iperfData.timestamp);
+
+						var flowSelection = d3.select(document.getElementById(makeFlowKey(flow)));
+						startFlowAnimation(flowSelection);
+						clearTimeout(animationTimeout);
+						// kill the animation if iperfdata stops flowing
+						animationTimeout = setTimeout(function () {
+							stopFlowAnimation(flowSelection);
+						}, updateRate*1.5);
+
+						var endTime = Math.floor(iperfData['end-time']*10)/10;
+
+						var startTime = endTime - (iperfData.samples.length * interval/1000);
+						// set now on the first buffer
+						if (!flow.iperfData.startTime) {
+							flow.iperfData.startTime = startTime;
+							flow.iperfData.localNow = Date.now();
+						}
+
+						iperfLog('iperf buffer start time: ' + startTime);
+						if (lastTime && (startTime - lastTime) > updateRate/1000) {
+							iperfLog('iperf buffer gap: ' + (startTime - lastTime) );
+						}
+						lastTime = startTime;
+
+						// clear out the old data
+						while (flow.iperfData.samples.length > pointsToDisplay + iperfData.samples.length) {
+							flow.iperfData.samples.shift();
+						}
+
+						// if the client gets too out of sync, resynchronize
+						var clientNow = flow.iperfData.startTime + (Date.now() - flow.iperfData.localNow)/1000;
+						if (Math.abs(clientNow - startTime) > (updateRate/1000) * 2) {
+							iperfLog('resynchronizing now: ' + clientNow + ' => ' + startTime);
+							flow.iperfData.startTime = startTime;
+							flow.iperfData.localNow = Date.now();
+						}
+
+						var time = startTime;
+						iperfData.samples.forEach(function (s) {
+							var sample = {
+								time: time,
+								value: s
+							};
+							flow.iperfData.samples.push(sample);
+							time += interval/1000;
+						});
+					}
+					flow.iperfData.timestamp = iperfData.timestamp;
+				} catch (e) {
+					iperfLog('bad iperf data: ' + data);
+				}
+				flow.iperfFetchTimeout = setTimeout(fetchData, updateRate*.25); // over sample to avoid gaps
+//				iperfLog(data);
+			});
+		}
+		fetchData();
+
+	}
+}
\ No newline at end of file
