Skip to content

What Rainlytics is

Rainlytics is self-hosted web analytics for sites already served by CloudFront. It runs entirely inside one AWS account, and it is built around three constraints.

Nothing extra is downloaded by the pages being measured. No second DNS lookup, no second connection, no separate script tag. Page weight is most of why this project exists.

An optional beacon covers what server logs cannot see accurately, such as single-page-app route changes and Core Web Vitals. It is a small TypeScript module bundled into the site’s existing JavaScript, and it sends a GET to a path on the site’s own domain. CloudFront logs that request like any other, so the beacon has no ingestion pipeline of its own.

CloudFront standard logging writes to your S3 bucket, in Parquet, already partitioned. That bucket is the canonical store, and the data never leaves it. Glue holds the table definitions and Athena reads them in place.

There is no always-on infrastructure anywhere in the pipeline. Rollups are computed on a schedule by Athena, started by EventBridge Scheduler, and written back as small JSON summaries.

Reading those summaries is what the command line does, so an answer costs a GET rather than a query. That is the difference between cost tracking your traffic and cost tracking how often you check your analytics.

rainlytics query runs ad-hoc SQL through Athena, and named subcommands answer the questions people actually ask.

The reason is authentication. A dashboard needs an identity story, a session model and a way to revoke access, and that subsystem has to stay secure for as long as it exists. A command line on the AWS SDK’s credential chain inherits SSO, MFA, role assumption, least-privilege IAM and CloudTrail audit of who queried what, for no code.