Open-source project
medama-io/medama avatar
medama-io/medama

Medama Analytics: cookie-free, self-hosted web analytics in a single Go binary

Self-hostable, privacy-focused website analytics.

643 stars21 forksGoLicense varies

At a glance

What is it?
Medama Analytics is a self-hostable, cookie-free website analytics server written in Go, with a tracker under 1KB and an OpenAPI-based API. This review covers what it does, how to install it, and where it stops being the right tool.
Who is it for?
Adopt Medama Analytics if you want cookie-free page analytics on your own hardware and can accept a single-node Go service with a DuckDB-backed store and a tracker you load from your own domain. Do not adopt it if you need scheduled reporting, data export guarantees, or a documented upgrade path: the README does not describe rollback or downgrade, and the repository has no migration guide.
Can I use it commercially?
Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
Is it still maintained?
Yes. The repository last received commits 54 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem Medama Analytics solves, and who it is for

Most teams that want to know how many people read a page end up embedding a third-party script that sets cookies, collects IP addresses, and ships the raw events to someone else's servers. The README frames Medama Analytics as the opposite: a self-hostable server that stores aggregate page analytics without cookies, IP addresses or additional identifiers, and a tracker the README describes as less than 1KB. The stated compliance targets are GDPR and PECR.

The audience is narrow and specific. It is a developer or a small operations team that already runs a VM or a container host and is willing to own the analytics pipeline: the binary, the database file, the tracker script, and the dashboard that ships in the same repository. The README claims the server has no external dependencies and can run on a VM with 256MB of memory for most small websites. That is the pitch: one process, one disk, no managed service.

It is not a marketing analytics suite. There is no mention of funnels, cohorts, attribution modelling or ad-network integrations in the README. If your reporting requirements include those, this is the wrong layer of the stack.

How the tracker, the Go server and the dashboard fit together

The repository splits into three directories with different jobs and different licences. `tracker/` holds the client-side script that runs in the browser and posts events back to your server. `core/` is the Go server that receives those events and serves the API. `dashboard/` is the front end that reads from that API and renders the charts.

The README describes the server as OpenAPI-based, and links to an API reference at oss.medama.io/api-reference/introduction. That matters more than it sounds: the dashboard is not privileged. Anything the dashboard can display is reachable through the same HTTP API, so you can pull numbers into your own tooling without scraping the UI.

The build is a polyglot workspace. The top-level package.json declares `dashboard` and `tracker` as Bun workspaces alongside a Biome dependency, and the Dockerfile installs Go and Bun through mise before running `mise run //core:release:docker`. The final image is built from a distroless base, which means there is no shell inside the runtime container. Debugging happens from outside it, not by exec'ing in.

The DuckDB topic tag on the repository, together with the single-binary claim in the README, points to an embedded analytical store rather than a separate database service. The README does not document a schema, a retention policy, or a way to move data between instances, so treat the storage layer as an implementation detail you inherit rather than a surface you configure.

Installing Medama Analytics and sending your first event

The README points to oss.medama.io/deployment/installation for installation rather than spelling out the steps inline, and the repository ships a Dockerfile and a fly.toml, which tells you the intended deployment shapes are a container and a Fly.io app. Because the README does not reproduce the exact flags or environment variables, the honest starting point is the installation page plus the Dockerfile. A local build from the repository root follows the same path the Dockerfile takes: mise installs the runtimes, then the release task produces the server.

bash
mise trust -a -y
mise install go bun
mise run //core:release:docker

What you should see is the release task completing and a server binary or image produced by the core package. If mise is not already on the machine, the Dockerfile's own bootstrap is `curl https://mise.run | sh`, which is the same command the image build uses.

The container build accepts two build arguments, both defaulting to the literal string `development`:

bash
docker build \
  --build-arg VERSION=v0.6.2 \
  --build-arg COMMIT_SHA=$(git rev-parse HEAD) \
  -t medama-analytics .

Setting `VERSION` and `COMMIT_SHA` is worth doing because the Dockerfile echoes both during the build and the final image carries an `org.opencontainers.image.source` label. Stamping them makes it possible to tell two images apart later.

The second half of the setup is the tracker. The README does not publish the snippet, but it does state the tracker lives in `tracker/` under the MIT licence and is served to browsers as a script. The integration step is therefore: build or serve the tracker from your own domain, add the script tag to your pages, and point it at your server. Verify in the dashboard that a pageview from your own browser appears before you roll the tag out to real traffic.

The single-binary claim is also the scaling boundary

Medama Analytics is designed as one process with an embedded store. That is what makes the 256MB VM claim in the README plausible, and it is also the constraint. There is no documented read replica, no sharding story, and no separate ingestion tier. When the box is busy, ingestion and dashboard queries compete for the same CPU and the same disk.

For a personal site or a documentation portal, that is a reasonable trade. For a high-traffic property where you want analytics to survive an incident in the application, colocating the analytics server on the same host is a poor arrangement, and the README does not offer a clustered alternative.

The privacy design has a matching cost. Because the tracker does not use cookies or persistent identifiers, the README's own framing implies the data is aggregate in nature. You will not be able to reconstruct an individual user's session path the way a cookie-based tool can. Teams that have built internal reporting on session stitching will find that reporting cannot be reproduced here.

Finally, the release cadence is uneven. v0.6.0 and v0.6.1 were published on 2025-08-11 and 2025-08-17, and v0.6.2 followed on 2026-01-18. The repository's last push was on 2026-08-07. The README does not document a rollback procedure or a database downgrade path, so pinning a version and keeping the previous image are the only safety nets the material actually supports.

Medama Analytics compared with Plausible and Umami

The obvious alternatives in this category are Plausible and Umami, both of which are also self-hostable and cookie-free. The difference is in the runtime shape. Plausible and Umami are conventionally deployed as a web application backed by PostgreSQL, which means a second service to run, back up and upgrade. Medama Analytics collapses that into one Go binary with an embedded store, which is why the README can talk about a 256MB VM with no external dependencies.

That trade runs in both directions. A PostgreSQL-backed deployment gives you a database you already know how to back up, replicate and inspect with standard tools. Medama Analytics gives you a file and a process. If your team's operational muscle memory is SQL and pg_dump, the single-binary design removes a dependency but also removes the tooling you would reach for during an incident.

The second difference is the API surface. Medama Analytics is explicitly OpenAPI-based, and the README calls out integration into personal or professional dashboards as a first-class use. If you intend to render your own views rather than use the bundled dashboard, that is the strongest argument for choosing it over a tool whose API is an afterthought.

Licence split, maintenance and upgrade cost

The licences are split by directory, and the split is not cosmetic. The README states that `core/` and `dashboard/` are under the Apache License 2.0, with separate LICENSE files in each directory, while `tracker/` is under the MIT License with its own LICENSE file. If you plan to modify the tracker and ship it, or to embed the dashboard in a commercial product, read the three files rather than the README summary. Nothing here is legal advice, and the repository does not state a licence for files outside those directories.

Maintenance signals are mixed. The last push was on 2026-08-07, roughly six weeks before this writing, and the repository is not archived, so the project is not dormant. But the release history is thin: three releases across the span from 2025-08-11 to 2026-01-18, with the most recent published on 2026-01-18. A project that pushes code without cutting releases means you are either tracking `main` or running an eight-month-old tag.

Upgrade cost is the weakest documented area. The README does not describe schema migrations, a backup command, or a downgrade path. The Dockerfile's `VERSION` and `COMMIT_SHA` build arguments suggest the project expects you to know which build you are running, which is a start, but it is not an upgrade procedure. Budget for snapshotting the data file before every version bump, and test the upgrade on a copy first.

Editorial conclusion

Adopt Medama Analytics if you want cookie-free page analytics on your own hardware and can accept a single-node Go service with a DuckDB-backed store and a tracker you load from your own domain. Do not adopt it if you need scheduled reporting, data export guarantees, or a documented upgrade path: the README does not describe rollback or downgrade, and the repository has no migration guide. Before committing, verify the licence terms in core/LICENSE, dashboard/LICENSE and tracker/LICENSE, and confirm that the release you pin (v0.6.2, published 2026-01-18) builds from the Dockerfile in your own CI.

Frequently asked questions

What is Medama Analytics?

It is an open-source, self-hostable website analytics server written in Go. The README describes it as cookie-free and privacy-focused, with a tracker under 1KB and an OpenAPI-based server for integrating the data into your own dashboards.

Does Medama Analytics use cookies or store IP addresses?

The README states the tracker uses no cookies, no IP addresses and no additional identifiers, and that this is intended to keep the deployment compliant with GDPR, PECR and similar regulations.

How do I install Medama Analytics?

The README links to oss.medama.io/deployment/installation for the steps, and the repository provides a Dockerfile and a fly.toml. The Dockerfile installs Go and Bun through mise and runs the core release task to produce the server image.

What licence is Medama Analytics under?

The licence is split by directory. The README says core/ and dashboard/ are Apache License 2.0, each with its own LICENSE file, while tracker/ is MIT with a separate LICENSE file.

How much memory does the Medama Analytics server need?

The README claims the server has no external dependencies and can run on a VM with 256MB of memory for most small websites. That figure comes from the project's own documentation and is not a measured benchmark.

Can I export data from Medama Analytics?

The README does not document an export or backup command. The server exposes an OpenAPI-based API, which is the documented route for pulling data into your own tooling, but the README does not describe a bulk export format.

Official sources

  1. Issues
  2. medama-io/medama on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/medama-io-medama.svg)](https://hysenlabs.com/projects/medama-io-medama)