Me and my friend, analytics
We’re good buds.
A few days ago, Bryce sent me Dax's video about Cloudflare Pipelines. Ironically I had saw it on X earlier and doom-scrolled right past it. Silly me. So, I gave it another watch. Neat, more stuff on my stack of things to check out.
I will circle back to this...
I’ve been itching, for quite some time, to set up my own analytics for my website; effectively something that isn‘t Google Analytics. Something where I could dump arbitrary events — OpenTelemetry-like data perhaps — and also be able to query it in, ideally with SQL, but not some gnarly BigQuery SQL dialect; no thanks.
ClickHouse®#
I am partial to ClickHouse®, after having worked with their cloud offering for over a year now. I’ve simultaneously grown to love it and have been spoiled by it. And when you’ve invested a decent amount of time and energy into grinding at something, you get a little reluctant to let go of it, right? I think so.
The bulk of my ClickHouse® experience is on the querying and aggregation side, and a handful of backfills from Postgres to recreate some historical business facts in a new ClickHouse® cluster; less so on the ingestion side, though I learned the hard way early on that ClickHouse® doesn’t like it when you do ~100 single-row inserts per second; and not at all on the operating — I made an intentional choice to steer clear of operational burden and resposibilities.
That started around around July 2025, when frontier models like GPT 5.0 still kind of sucked at ClickHouse®. In fact, I don’t remember “agents” or “harnesses” being super hot yet either. So I got to spend a decent amount of time, reading docs, testing out queries through trial and error, as opposed to delegating most of it to an agent to figure out.
I built the service that aggregates the user retention and churn analytics that you see on the Clerk dashboard overview. Each vertical bar is precomputed, and would otherwise take upwards of 15-20 seconds to query for larger tenants.

Here's the overview of the pipeline; arguably super basic. My approach was to start stupid-simple with direct queries, but if they ran too slow — > ~1-2s — for our largest tenants, that would be a non-starter and would warrant pre-computation, hence the materialized views below. Eventually I landed on the following architecture, 100% on ClickHouse® primitives.
Back to ClickHouse® for personal projects though, I cannot justify paying for it. Their cheapest cloud offering starts at $161/month for an always-on cluster; Way too expensive. I also won’t go into the embarrassing number of times I’ve fired off desperated cries to GPT 5.4, 5.5, and 5.6 in hopes of some magically-simple way to self-host ClickHouse® as cheaply as possible, only to arrive at the conclusion of, ”Ain’t nobody got time fo dat...”
Personal analytics#
Ok, so, what can I use for my humble little website that is low-touch, and cheap?
Here is what I have tried or considered:
TinyBird: Basically gives you a full pipeline — ingestion endpoint, storage, and retrieval. Despite being a very cool product, it has always felt a bit too abstracted to me. Cool to play with, but felt like there was too much magic going on, and never really stuck with me. Their events API was always a killer feature though. Ingestion is challenging to get right.
Workers Analytics Engine by CloudFlare: This is another flavor of ClickHouse®, basically, but also felt slightly too awkward for my taste. This would put the onus on me to handle write the ingestion logic — buffering, batching, error handling — which is something I was not super interested in rebuilding just for my website.
Cloudflare Pipelines#
Alas, we arrive back at the top: Cloudflare Pipelines
Everything about them is perfect for my personal website usage.
- They’re pretty cheap: unlimited ingress, and free 50gb of both SQL transforms and sink egress. Who doesn’t love $free.99?
- They’re terraform-able: Who doesn’t appreciate infrastructure-as-code?
Am I sounding like an advertisement yet?
The biggest feature for me is the simple HTTPS endpoint for ingestion. A quick test with hey showed 100% successful responses at 10k requests and 80 concurrent connections. Nice.
A close second is the ease of querying the final data that sits in an R2 bucket, via SQL. These queries are kind of slow, but that’s totally acceptible for my use case.
Overall, it’s a nice package that delivers simplicity while taking care of an otherwise complex technical problem. Great value, I’d say.
Here’s the overview of the analytics for this site.
You can see the querying side of things at /analytics.
Pipeline Schema#
Querying the R2 data catalog#
https://developers.cloudflare.com/r2-sql/sql-reference/