CLI tool
sourcegraph/checkup avatar
sourcegraph/checkup

sourcegraph/checkup: distributed health checks with a static status page

Distributed, lock-free, self-hosted health checks and status pages

3,459 stars246 forksGoMIT

At a glance

What is it?
Checkup runs HTTP, TCP, DNS, TLS and exec checks from any host, writes the results to storage you control, and renders a status page from those files. It is a small Go tool with a narrow, deliberate design and a long gap since its last tagged release.
Who is it for?
Checkup fits teams that already run their own storage and want check results as plain files they can serve or commit, rather than a hosted monitoring account. It does not fit anyone who needs alerting guarantees, a query language over metrics, or a UI that reads SQL back-ends, since the README states the status page does not support SQL or Azure Application Insights storage.
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 15 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

What Checkup is for, and who ends up using it

Checkup answers a narrow question: is this endpoint still responding, and can I show that answer on a page I host myself? The README describes it as "distributed, lock-free, self-hosted health checks and status pages, written in Go." The three pieces it names are storage, checks and a status page, and the order matters. Nothing in the tool owns state on a server. A check run produces result files, those files go wherever your storage provider points, and the status page reads them back.

The intended user is someone who already has a place to put files or rows and does not want to hand endpoint URLs to a hosted monitor. The GitHub storage provider makes that concrete: results are committed to a branch in a repository you own, and the README suggests GitHub can host the status page itself. If your team already publishes a gh-pages branch, the status page is a static asset sitting next to everything else. That is a different posture from a monitoring SaaS account, and it is the main reason to pick this tool over a hosted one.

The README is candid that the project is unfinished. It says the tool "is a work-in-progress" and asks users to report bugs. The most recent tagged release listed is v0.2.0 from 2017-07-28, and the last push to the repository was on 2026-09-16. Commits continue; releases do not. Anyone installing from a release archive is installing code from 2017, while anyone building from source gets whatever is on master.

How a check run becomes a status page

The data flow has no coordinator. A Checkup process reads checkup.json, builds a list of checkers, runs each one, and writes the outcome through the configured storage provider. There is no daemon holding results in memory and no lock between runs, which is what the "lock-free" claim covers: two hosts running checks against the same storage write independent result files rather than contending for a single record.

Checkers are selected by a type field. The README lists HTTP, TCP with TLS, DNS, TLS and exec. Each checker config carries an endpoint_name and, for most types, an endpoint_url. The exec checker is the escape hatch: it runs any command and treats a zero exit code as success, with a raise setting of warning available so a failing service is reported as DEGRADED rather than down.

Storage providers are the second half. The README lists Amazon S3, the local file system, GitHub, MySQL, PostgreSQL, SQLite3 and Azure Application Insights. The status page is the third piece, and here the README draws a boundary directly: "Currently the status page does not support SQL or Azure Application Insights storage back-ends." So the storage list is wider than the status page can consume. If you pick MySQL, you get results in a database and no built-in page to render them.

Notifiers are optional and sit alongside the check run. The go.mod file lists dependencies including mailgun-go, slack-go-webhook, pushover and gomail, which matches the README's claim that notifications go through "your service of choice (if an integration exists)."

Installing Checkup and running a first check

The README gives two install paths: download a release binary for your platform and put it in your PATH, or install from source with go get. The source path needs Go 1.8 or newer according to the README, though go.mod declares go 1.13, so build with a toolchain that satisfies the module file.

bash
go get -u github.com/sourcegraph/checkup/cmd/checkup

After that, the README says to verify the binary is on your path by running checkup --help.

bash
checkup --help

Configuration is a single JSON document saved as checkup.json in your working directory. The README gives the outline: a checkers array, a storage object, and a notifiers array. Here is a minimal config with one HTTP check and local file storage, using the field names the README shows.

json
{
  "checkers": [
    {
      "type": "http",
      "endpoint_name": "Example HTTP",
      "endpoint_url": "http://www.example.com"
    }
  ],
  "storage": {
    "type": "fs",
    "dir": "/path/to/your/check_files"
  }
}

With that file in place, a check run writes result files into the directory named in dir. The README notes that the default for the status page config has been set to local source, used together with checkup serve. The Dockerfile shows the same arrangement: it copies statuspage/ into /app/statuspage, exposes port 3000, and sets the entrypoint to checkup with the default command serve.

bash
docker build --no-cache . -t checkup
docker run -p 3000:3000 -v ./checkup.json:/app/checkup.json -v ./checks:/app/checks checkup

The docker-compose.yml in the repository wires the same two mounts and leaves the published port as 3000, so the status page is reachable on that port once the container is running.

Where Checkup breaks down

The breaking changes section is the first thing to read before upgrading anything. Two config fields were renamed: the json field provider became type for providers, and name became type for notifiers. A config written against an older version will not load with the same meaning. The mailgun to parameter changed from a single recipient to a list of addresses. And the README states in capitals that logging is not swallowed anymore, with the instruction not to parse checkup output in scripts. If any of your automation scrapes stdout, that automation is now fragile by design.

The SQLite situation is also a trap. The README says that by default the sqlite storage engine is disabled and needs a build with -tags sql to enable, then says the sql engine is deprecated in favor of postgres, mysql and sqlite3. The Makefile reflects the split: make build produces a binary with mysql and postgresql support, and make build-sqlite3 produces one with additional sqlite3 support. A binary built with the plain build target will not have sqlite3, and the README does not document what error you get when you configure it anyway.

The status page limitation is the sharpest one. SQL and Azure Application Insights storage are excluded from it, so a team that wants a database for querying and a page for viewing has to build the page side themselves. There is no documented rollback procedure for a bad config change, and no documented migration path between storage providers, so switching from fs to s3 means re-running checks rather than moving history.

Checkup against a pull-based metrics system

The obvious comparison is Prometheus with Blackbox Exporter. Both probe HTTP, TCP, DNS and TLS endpoints from infrastructure you run, and both keep the results in storage you own. The difference is the shape of the output and what consumes it.

Prometheus stores numeric time series and expects a query layer, alerting rules and a dashboard on top. Checkup stores result files and expects a static status page. There is no query language in Checkup and no aggregation across runs; the README describes checks, storage and a page, and nothing about thresholds, rate windows or recording rules. If your question is "what is the 99th percentile latency of this endpoint over the last week," Checkup is the wrong tool and will not become the right one by adding config.

If your question is "is this endpoint up, and can I publish the answer as a file," the trade runs the other way. The GitHub storage provider commits results to a branch, which means the history is a git log you can read and the status page can be served by GitHub itself. Prometheus has no equivalent of committing probe results to a repository. That is the specific reason to choose Checkup, and it is also why the storage provider list includes GitHub at all.

A second alternative is running your own cron jobs that curl endpoints and write files. Checkup's advantage there is the checker set: DNS checks with a hostname_fqdn field, TLS checks against a port, and an exec checker with a DEGRADED state are all things you would otherwise write yourself and maintain.

Licence, build cost and what maintenance looks like

The repository is MIT licensed, which places few restrictions on use, modification or redistribution. The practical implication is that you can vendor the code, fork it, or ship a modified binary without a copyleft obligation. This is not legal advice; read the LICENSE file in the repository for the actual terms.

The build cost is low if you have a Go toolchain. The Makefile's build target runs go fmt, go mod tidy and go build into the builds/ directory. The Dockerfile pins golang:1.14-alpine as the builder stage and copies the resulting binary into a plain alpine image, running as the nobody user. That is a small image and a reproducible build, with one caveat: the build stage sets CGO_ENABLED=0, which is consistent with a static binary but also means any storage engine that needs cgo is not available in that image. Since sqlite3 support is gated behind a build tag and the mattn/go-sqlite3 driver is a cgo dependency, the Docker image as written does not carry sqlite3.

Upgrade cost is dominated by the config renames. Moving from an older Checkup to current master means editing every provider block to use type and every notifier block to use type, plus converting any mailgun recipient to a list. There is no compatibility shim documented. The last tagged release is v0.2.0 from 2017-07-28, and the last push was on 2026-09-16, so the gap between releases and commits is wide enough that building from source is the realistic path for anyone who wants current behaviour.

Editorial conclusion

Checkup fits teams that already run their own storage and want check results as plain files they can serve or commit, rather than a hosted monitoring account. It does not fit anyone who needs alerting guarantees, a query language over metrics, or a UI that reads SQL back-ends, since the README states the status page does not support SQL or Azure Application Insights storage. Before adopting it, build the binary with make build and confirm which storage engines your target build actually includes, because sqlite3 support requires the separate make build-sqlite3 target.

Frequently asked questions

What is sourcegraph/checkup?

It is a self-hosted health check tool written in Go, described in its README as distributed, lock-free health checks and status pages. It runs HTTP, TCP, DNS, TLS and exec checks and writes results to a storage provider you configure.

How do I install sourcegraph/checkup?

The README offers two paths: download a release binary for your platform and put it in your PATH, or install from source with go get -u github.com/sourcegraph/checkup/cmd/checkup. It states you need Go 1.8 or newer.

Which storage back-ends can the Checkup status page read?

The README states that the status page does not support SQL or Azure Application Insights storage back-ends. S3, the local file system and GitHub are the providers the page is built around.

Why does my Checkup build not have sqlite3 support?

The README says the sqlite storage engine is disabled by default and needs a build with -tags sql to enable. The Makefile provides make build for mysql and postgresql, and a separate make build-sqlite3 for sqlite3.

What changed in Checkup's configuration format?

The README lists breaking changes: the json field provider was renamed to type for providers, and name was renamed to type for notifiers. The mailgun to parameter now takes a list of e-mail addresses instead of one recipient.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. sourcegraph/checkup on GitHub
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/sourcegraph-checkup.svg)](https://hysenlabs.com/projects/sourcegraph-checkup)