Skip to content

Instantly share code, notes, and snippets.

@mbostock
Last active October 19, 2020 23:31
Show Gist options
  • Save mbostock/5503544 to your computer and use it in GitHub Desktop.
Save mbostock/5503544 to your computer and use it in GitHub Desktop.
Gist API Latency
license: gpl-3.0

This histogram shows the distribution of GitHub Gist API response times (in milliseconds) for a sample of 10,000 requests as observed by bl.ocks.org.

The distribution roughly follows a log-normal distribution, which is unsurprising for a complex process that has multiple independently-random sources of delay. The mode response time was in the range 120-140ms, while the median response time was 206ms. The middle 80% of requests were in the range 114-527ms. About 11% of requests took longer than 500ms, and 5% of requests took longer than one second. (The rightmost bin in the histogram includes these long requests.)

Since API endpoints vary dramatically in their computational cost, the distribution of response times is likely multimodal. In this dataset, 96% of requests were for a single gist (/gists/42), while the remaining 4% of requests were to list a user’s gist (/users/fred/gists). By separating the API requests for a single gist (shown in light blue) from listing a user’s gists (shown in dark blue), we see that the cause for the slow requests is not random but a function of the endpoint! The response time distribution to list a user’s gists is significantly slower than querying a single gist.

This data was collected by from the bl.ocks.org Heroku app via cube-logplex and queried via Cube.

x dx a b
0 20 0 0
20 20 0 3
40 20 2 15
60 20 121 2
80 20 306 2
100 20 811 0
120 20 1022 3
140 20 910 5
160 20 799 1
180 20 709 1
200 20 593 1
220 20 600 0
240 20 501 1
260 20 408 1
280 20 358 0
300 20 316 0
320 20 256 0
340 20 252 2
360 20 200 1
380 20 161 0
400 20 121 3
420 20 103 2
440 20 107 1
460 20 74 0
480 20 73 1
500 20 61 0
520 20 63 0
540 20 56 0
560 20 44 1
580 20 28 0
600 20 30 0
620 20 27 0
640 20 30 1
660 20 24 1
680 20 15 1
700 20 15 1
720 20 24 1
740 20 18 1
760 20 17 2
780 20 14 0
800 20 19 1
820 20 21 1
840 20 7 0
860 20 11 4
880 20 11 1
900 20 7 2
920 20 15 3
940 20 14 3
960 20 8 3
980 20 256 290
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font: 10px sans-serif;
}
.bar rect {
fill: #1f77b4;
shape-rendering: crispEdges;
}
.bar .a {
fill: #aec7e8;
}
.bar text {
text-anchor: end;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
</style>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script>
var formatPercent = d3.format(".1%");
var margin = {top: 10, right: 30, bottom: 30, left: 30},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x = d3.scale.linear()
.domain([0, 1000])
.range([0, width]);
var y = d3.scale.linear()
.range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
d3.tsv("histogram.tsv", type, function(error, histogram) {
var n = d3.sum(histogram, function(d) { return d.y = d.a + d.b; });
y.domain([0, d3.max(histogram, function(d) { return d.y; })]);
var bar = svg.insert("g", ".axis")
.attr("class", "bar")
.selectAll("g")
.data(histogram)
.enter().append("g")
.attr("transform", function(d) { return "translate(" + x(d.x) + ",0)"; });
bar.append("rect")
.attr("class", "b")
.attr("x", 1)
.attr("y", function(d) { return y(d.b); })
.attr("width", x(histogram[0].dx) - 1)
.attr("height", function(d) { return height - y(d.b); });
bar.append("rect")
.attr("class", "a")
.attr("x", 1)
.attr("y", function(d) { return y(d.y); })
.attr("width", x(histogram[0].dx) - 1)
.attr("height", function(d) { return height - y(d.a); });
bar.filter(function(d) { return d.y / n >= .0095; }).append("text")
.attr("dy", ".35em")
.attr("transform", function(d) { return "translate(" + x(histogram[0].dx) / 2 + "," + (y(d.y) + 6) + ")rotate(-90)"; })
.text(function(d) { return formatPercent(d.y / n); });
});
function type(d) {
d.x = +d.x;
d.dx = +d.dx;
d.a = +d.a;
d.b = +d.b;
return d;
}
</script>
@adrobbins
Copy link

Quality mate.

@mekb-turtle
Copy link

How do you upload images? Infact any binary files?!

@fxfactorial
Copy link

git clone [email protected]:<hash>.git mygist

its a plain repo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment