Self-hosted service
muety/wakapi avatar
muety/wakapi

Wakapi: a self-hosted WakaTime backend where you own the heartbeat data

📊 A minimalist, self-hosted WakaTime-compatible backend for coding statistics

4,431 stars300 forksGoMIT

At a glance

What is it?
Wakapi is an MIT-licensed Go server that speaks the WakaTime API so existing editor plugins keep working while the database stays on your own machine. It is a reasonable fit for individuals and small teams who care about data residency, and the wrong tool for anyone who wants an actively maintained project accepting outside contributions.
Who is it for?
Adopt Wakapi if you want WakaTime-style dashboards and the wakatime-cli plugins you already use, but want the heartbeat database on hardware you control, and you accept that the maintainer has paused pull requests. Do not adopt it if you need vendor-backed support, a published compatibility matrix, or a project that will merge your patch.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day 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 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The problem Wakapi solves is custody of the heartbeat stream

WakaTime works by having a client tool, wakatime-cli, watch your editor and emit heartbeats: small records of file, project, language, editor, host and operating system, timestamped and sent to a server. The server aggregates them into the dashboards developers like to look at. The default server is WakaTime's own. That means the raw record of what you typed, in which repository, on which machine, at what hour, lives in someone else's database.

Wakapi's answer is to be that server, on your hardware. The README describes it as a minimalist, self-hosted WakaTime-compatible backend for coding statistics, and the compatibility claim is the load-bearing one: because Wakapi implements the same API shape, you keep using the official client tools and the editor plugins built on them. You change one URL in a config file rather than replacing your toolchain.

The audience is narrower than the feature list suggests. It is individual developers who already run a VPS or a home server, and small teams who want one shared instance for a handful of people. It is not aimed at organisations that need an SLA, an audit trail, or a support contract, because the project does not offer any of those.

Heartbeats in, aggregates out: the data flow Wakapi actually implements

The architecture is a single Go binary that serves an HTTP API and, by default, writes to SQLite. The README notes that SQLite is the default database and that MySQL and Postgres are alternatives configured through the Dockerfile and config.default.yml. Everything Wakapi knows arrives through that API, pushed by wakatime-cli running on each developer machine. There is no agent that reaches into your repositories or your CI.

That push model has a consequence worth stating plainly. If the client cannot reach the server, the heartbeat is not captured retroactively by Wakapi. Correctness depends on the client side, not on the server side. The README hints at this by pointing to a client-side proxy wiki page as an optional advanced setup, which is the usual way people smooth over intermittent connectivity or a machine that moves between networks.

On the output side, the README lists statistics for projects, languages, editors, hosts and operating systems, plus badges, weekly email reports, a REST API and Prometheus exports. The Prometheus support is the piece that makes Wakapi more than a personal dashboard: it means the same heartbeat stream can feed an existing metrics stack rather than only a web UI. The email reports and badges are the opposite end of the same spectrum, small conveniences for people who want the numbers visible without opening the app.

Four install paths and the one config file that matters

The README gives four routes. The hosted service at wakapi.dev requires only an account. A quick-run script is one line: curl -L https://wakapi.dev/get | bash. Docker is the third, and it is the one most people will use:

docker volume create wakapi-data SALT="$(cat /dev/urandom | LC_ALL=C tr -dc 'a-zA-Z0-9' | fold -w ${1:-32} | head -n 1)" docker run -d --init -p 3000:3000 -e "WAKAPI_PASSWORD_SALT=$SALT" -v wakapi-data:/data --name wakapi --restart unless-stopped ghcr.io/muety/wakapi:latest

The fourth is building from source with go install github.com/muety/wakapi@latest, then fetching config.default.yml, editing it, and starting the binary with ./wakapi -config wakapi.yml. The README also notes that a SystemD unit is provided at etc/wakapi.service for standalone runs, and that a community Helm chart exists for Kubernetes.

Configuration comes from either a YAML file or environment variables. The Docker example sets WAKAPI_PASSWORD_SALT, which is the value used to derive password hashes, so it must be set at first boot and kept stable afterwards. The README also names WAKAPI_DB_PASSWORD and WAKAPI_MAIL_SMTP_PASS as variables that can be supplied through Docker Secrets, either as mounted secret files or as plain environment variables.

The client side is a single INI file, ~/.wakatime.cfg, with api_url pointing at your server plus /api and api_key set to the key shown in the Wakapi web interface after you create an account. If you want to feed both WakaTime and Wakapi, the README's preferred approach is client-side: keep the WakaTime key under [settings] and add an [api_urls] section mapping .* to a pipe-separated pair of URL and key. The README warns explicitly not to add multiple .* entries, because duplicate keys are invalid in an INI file and wakatime-cli ignores them. That is a real trap, and it is the kind of mistake that produces silent data loss rather than an error message.

The pull request freeze is the constraint that shapes adoption

The README carries a notice that, due to limited time available on the maintainers' part, pull requests are temporarily not accepted, and asks people to refrain from submitting contributions. That single sentence changes what Wakapi is. A self-hosted tool you can patch is a different proposition from a self-hosted tool you can only configure.

If you hit a bug in the WakaTime API surface, or need a field the aggregator does not store, your options are to fork, to wait, or to work around it. The MIT licence means forking is legally straightforward, but a fork carries its own maintenance burden, and the README gives no indication of when the freeze lifts. The word temporarily is doing a lot of work in that notice.

The release cadence visible in the repository metadata is roughly every one to two months across the 2.17.x line, which suggests the project is still being maintained by its author even with contributions closed. Maintenance and adoption are not the same thing, though. You are depending on one person's available time, and the README says as much in its own words.

There is a second limitation that follows from the compatibility claim. The README says partially compatible with WakaTime, and that qualifier is not expanded anywhere in the material available here. Which endpoints, which response fields, and which client behaviours are covered is not stated. If your workflow depends on a specific part of the WakaTime API, the only reliable way to find out is to point a client at Wakapi and observe what breaks. Treat the compatibility claim as a starting point for testing, not as a specification.

WakaTime's hosted service versus running the server yourself

The obvious alternative is WakaTime itself. The difference is not features, it is who operates the backend and what that buys you. WakaTime runs the server, handles scaling and storage, and supports the client tools that both projects depend on. You get an account and a URL. Wakapi gives you the same client-side experience but hands you the operational work: a host, a database, a backup routine, a salt you must not lose, and an upgrade path.

The README treats this as a spectrum rather than a binary, which is unusual and worth noting. You can run Wakapi and still forward heartbeats to WakaTime through the relay feature under Settings, Integrations, or by configuring [api_urls] on the client. So the two are not mutually exclusive, and a reasonable migration path is to run both for a while and compare the numbers before deciding whether the self-hosted instance is sufficient.

Choosing Wakapi is therefore a decision about data custody and operational tolerance, not about which dashboard looks better. If you do not already run servers, the hosted option costs you nothing in effort and Wakapi costs you a container, a volume, a salt, and the attention to keep it patched. If you do run servers, the marginal cost is small and the benefit is that the heartbeat database sits next to everything else you own.

Licence, upgrades and what the MIT grant does and does not cover

Wakapi is MIT licensed. In practical terms that permits use, modification and redistribution, including in commercial settings, provided the licence and copyright notice are preserved. It says nothing about the hosted service at wakapi.dev, which is a separate offering operated by the maintainer, and nothing about WakaTime's own client tools, which carry their own terms. This is not legal advice; if you plan to redistribute a modified Wakapi or bundle it into a product, read the licence text and the client tool licences yourself.

Upgrade cost is modest but not zero. The Docker path is a pull of ghcr.io/muety/wakapi:latest and a restart, and the README's run command already includes --restart unless-stopped. The source path is a re-run of go install plus a restart of the SystemD unit. What the README does not describe is a migration story for schema changes between releases. The material available here does not state whether Wakapi applies migrations automatically at startup or requires a manual step, so back up the volume before upgrading and check the release notes for the version you are moving to.

There is one operational detail in the README that is easy to skip and expensive to get wrong. If you persist SQLite data in a local directory rather than a named volume, the README says to set the correct user option in the Docker Compose configuration to avoid permission issues. A container running as one UID writing into a host directory owned by another produces a failure that looks like data loss. Set the user before the first write, not after.

Editorial conclusion

Adopt Wakapi if you want WakaTime-style dashboards and the wakatime-cli plugins you already use, but want the heartbeat database on hardware you control, and you accept that the maintainer has paused pull requests. Do not adopt it if you need vendor-backed support, a published compatibility matrix, or a project that will merge your patch. Before committing, verify three things on your own deployment: that your editor plugin writes heartbeats against api_url with the Wakapi API key, that the SQLite volume survives a container restart, and that whatever backup routine you pick actually restores into a working instance.

Official sources

  1. License: MIT
  2. muety/wakapi on GitHub
  3. Project website
  4. README
  5. Releases
Community notes

Community notes