The star badge endpoint: a count as SVG, with no server behind it

Show & TellIvan2 replies

IvanMember#1

Every project on this site can be cited with a badge: /badge/<project-slug>.svg returns an image with the star count in it. There is no server behind that endpoint, and the reason it works without one is the interesting part.

How it works

The badge is not rendered on request. It is a static file, generated once a day along with the rest of the snapshot, and served from the edge.

That is the whole trick. A badge that is rendered live would need the server to be up, would need to talk to GitHub or to our database on every request, and would break the moment either of those was slow. A badge that is a file is a file, and it costs nothing to serve.

The consequence is that the number is at most a day old. For a star count, that is not a meaningful difference, and it is the right trade for something people embed in a README.

The other half: the chart

The same snapshot writes the star history, and /chart/<project-slug>.svg draws it. That one is not a static image: the SVG is a template with the data points filled in, so the file is small and the shape is crisp at any size.

Both work without a key and without a page view, and both are allowed to be embedded anywhere — the licence on the data is CC BY 4.0, so a project can put the badge in its own README and we are happy about it.

Why it is a static file and not a proxy

The usual alternative is to proxy the image from GitHub. That has three problems: GitHub's own badge endpoint is rate-limited and occasionally slow, a proxy puts our domain in front of someone else's traffic, and it cannot show a number we know to be current.

The static file has none of those problems, and it has one drawback: if the number is wrong, the file is wrong until the next run. For a star count that is fine. For anything that changes on a timescale shorter than a day, it would not be.

2 replies

NicoMember#2

The "a badge that is a file is a file" line is the argument I use when people ask why this cannot just be a route handler.

It also makes the failure mode honest: if the daily job fails, every badge on every README in the world shows yesterday's number, and the number of people who notice is exactly the number of people who are looking at the badge today.

DaisyRegular#3

In reply to Nico (#2)

One detail worth having on the page: the date the number was read, next to the badge or in the tooltip.

The same argument as the licence request on this board — a number without a date is a claim, and a number with a date is a snapshot. For a badge that people embed, a reader has no way to know how old it is.