Skip to Content

How Pushbroom Works

This is the part underneath. Nothing here is a prerequisite for anything else in these docs — you can register a domain, install the script, read your numbers and never open this page. It is here because some people want to know, and because a claim you cannot check is not worth much.

The short version

Pushbroom is a Solid application. Your analytics are stored as RDF in a pod you own, and read back with SPARQL. What we keep is a registry row: this domain writes to that pod. The events themselves are never written to our servers, so when we draw you a chart we are querying your storage, not ours.

That is what “your data is yours” is made of. It is not a policy we could quietly reverse — there is no second copy to reverse it about.

The three pieces

The collector. A couple of hundred lines of JavaScript, most of them comments, served minified and published in full at pushbroom.co/script.src.js. It finds <push-broom> elements, asks for a visit identifier, and sends page views and events as plain GET requests.

The session identifier. Not a cookie. It rides in the browser’s HTTP cache as an ETag, lasts two hours from the moment it was minted, and belongs to one site. How that works, and what it cannot do.

The store. Every page view and event is a handful of triples written into your pod with a SPARQL update. Every chart in the dashboard is a SPARQL query read back out of it.

Why a graph

Because it is the reason you can ask questions you did not plan for.

There is no schema to declare and no custom-dimension slots to register. A pb:cohort attribute you invent this afternoon is a predicate in the graph the moment it arrives, and it is filterable against every event you have ever recorded — including the ones from before you invented it. Nothing has to be modelled in advance, because nothing is stored in a shape that assumes the question.

It is also why a third party can write into the same graph. A deploy marker from your CI job, an incident, a campaign — arbitrary triples alongside your events, joinable without an integration.

Going further

Last updated 2026.09.14