# StatLite: a metrics dashboard sized for a VPS, with no auth

> StatLite is a single Go binary that polls Spring Boot, Quarkus or any application exposing a small fixed JSON endpoint and stores what it finds in SQLite on your own server. It is deliberately not a Prometheus and Grafana replacement, and the sharpest edge in the documentation is that it has no built-in authentication at all, so the access guidance is part of the install.

**PVRLabs/statlite** — A tiny self-hosted metrics dashboard for small servers. Spring Boot Actuator monitoring with SQLite, simple charts, and no Prometheus/Grafana stack required.

- Repository: https://github.com/PVRLabs/statlite
- Website: https://pvrlabs.xyz/statlite/
- Stars: 178 · Forks: 6
- Language: Go
- License: MIT
- Published: 2026-08-24 · Updated: 2026-08-24 · Language: en
- Canonical page: https://hysenlabs.com/projects/pvrlabs-statlite

## No authentication at all, which shapes the whole install

The most important line in the documentation is flagged as important rather than buried: StatLite has no built-in dashboard or API authentication, and you are pointed at the server and access guidance before exposing it remotely. That single fact decides the default configuration, and the example file shows why. The listen address in the sample configuration is a loopback address on port 9090, the SQLite file sits in the working directory, the polling interval is thirty seconds, and the one target is a Spring application pointed at its Actuator base URL. A loopback bind with no auth is a coherent combination; a public bind with no auth is not, and the project is explicit that the choice is yours. The Docker invocation in the quick start follows the same logic, publishing port 9090 onto loopback on the host rather than on all interfaces, so a browser on the machine can reach it and nothing else can.

## A YAML file with four sections, and one is a list of targets

The configuration is a small YAML document and it is worth reading as a schema because it tells you what the tool models. A server section holds the listen address. A storage section names the SQLite path, which is the only durable state in the system. A polling section sets the interval between requests to each target, and that single value is the resolution of everything on the dashboard. A targets section is a list, and each entry has a name, a type and a URL, with the type selecting which metric source to use and the name being what you see on the dashboard. The documented path for adopting an existing setup is deliberately conservative: rather than replacing a configuration you already have, you copy only the target entry into its targets list, which means the tool can be added to an existing monitoring arrangement one application at a time. A complete multi-target example and framework-specific examples live in the examples directory in the repository.

## inspect generates a config, and it is deliberately bounded

Rather than making you write YAML by hand, there is an inspect subcommand that probes a running application and produces the configuration. Given a base URL it inspects the application and generates the target entry; given a type and a URL it does the same for a framework it cannot infer, such as a Quarkus application on a different port. Two properties are stated for the command rather than left implicit. It checks conventional supported endpoints, and it is bounded and read-only, so it is a discovery step rather than a crawl. For untyped discovery it expects a base HTTP or HTTPS URL with no query string or fragment, which is a small constraint that keeps the probe predictable. The documentation also names the limits of this approach in a configuration page covering exact endpoint forms, discovery limits and authentication limitations, and that last item is the honest one: inspection cannot get past an endpoint that requires credentials, so a target behind basic auth is something you configure by hand.

## Four metric sources, and health is treated separately from reachability

What StatLite can read is four sources, and the distinctions between them matter more than the list. Spring Boot is the primary one: it collects authoritative health when Actuator health is available, and it automatically selects a compatible Micrometer Prometheus endpoint or the Actuator JSON for request, JVM, process and optional host metrics. The detail worth noting is that independently usable metrics stay reportable if health retrieval fails, so a health outage does not blank the rest of the dashboard. Quarkus is read through Micrometer metrics from an exact Prometheus or OpenMetrics endpoint, with SmallRye Health as an optional capability the application may or may not publish. The third source is the project's own small fixed JSON endpoint, which any application in any language can implement, with integration guides for FastAPI, Express, Django, Go's standard HTTP server and Gin. The fourth is self-monitoring: StatLite reports its own health, traffic, process and host metrics, which is why the dashboard has data the moment you start it.

## Health is a separate concept from successfully scraping a target

There is a design decision here that shows up in two separate places and is easy to miss. When a target has no health signal at all, StatLite does not treat the fact that it is receiving metrics as proof that the application is healthy. The dashboard reports whether StatLite is successfully receiving metrics, which is a statement about the monitoring path, and keeps that distinct from the health of the thing being monitored. The same separation shows up in the Spring target, where health is described as authoritative when Actuator makes it available and everything else remains reportable independently. For a small deployment this is the difference between a green dashboard that means the application is serving and a green dashboard that means the poller is running, which are very different pages at three in the morning. It is also why a target type can be configured without a health endpoint and still be useful, since request and resource metrics do not depend on one.

## One static binary, a pure Go SQLite driver, no cgo

The dependency list is short enough to be a design statement. The module requires Go 1.27.1 and pulls in four direct dependencies: a YAML parser, a system calls package, a pure-Go SQLite driver, and a library that calls native code without cgo. There is no HTTP framework, no metrics client library, no chart rendering dependency and no ORM, which is consistent with a tool whose stated goal is a small memory and operational footprint. The container build follows the same logic: the build stage compiles with cgo disabled, path trimming and stripped symbols, injecting a version string at link time, and the runtime stage is a minimal Alpine image with a dedicated non-root user, a data directory that user owns, and the binary plus a default configuration copied in. Exposed port 9090 matches the default listen port, and the entrypoint passes the bundled configuration file. The result is an image whose only moving parts are the binary and a YAML file.

## Install, run, and the operational files around it

Installation has three documented routes and each suits a different situation. A piped install script is the quick path on macOS and Linux, Homebrew is the route if you would rather manage the binary through a package manager, and Docker isolates the tool entirely:

```bash
curl -fsSL https://raw.githubusercontent.com/PVRLabs/statlite/main/install.sh | sh
```

```bash
brew install pvrlabs/tap/statlite
```

```bash
docker run --rm \
  -p 127.0.0.1:9090:9090 \
  ghcr.io/pvrlabs/statlite:latest
```

Note that the Docker invocation publishes port 9090 onto loopback on the host, matching the no-authentication default. The Docker guide covers persistent storage, container networking, local builds and access guidance, which are the four things that go wrong with a containerised dashboard. The install documentation additionally covers supported platforms, custom install locations, source builds and server-wide Linux setup, and there is a separate document for running it under systemd, which is what you would use on a VPS. At the root of the repository sit the expected operational files: a `Dockerfile`, an `install.sh`, a `run.sh`, a `deploy/` directory, a `scripts/` directory, a default `statlite.yaml`, a changelog, an `AGENTS.md` and a Chinese README alongside the English one. A deprecations and compatibility document is a good sign for a project at this version, since it means the configuration surface has a written history rather than quiet changes.

## Conclusion

StatLite fits a single small server or VPS where a full metrics stack would cost more in memory than the application being measured, and the design is coherent about that: one static binary, SQLite on local disk, and a monitoring surface narrow enough to reason about. It is not a Prometheus replacement, and the documentation says so rather than hedging, pointing instead at a document comparing it against a general-purpose self-hosted stack, telemetry pipelines and hosted platforms. Two things to settle before you expose it. It has no built-in dashboard or API authentication, so binding it to a public interface is on you, and the default listen address in the example configuration is a loopback address for that reason. Second, the metrics are polled on an interval, so a burst shorter than the interval may not appear. Licence is MIT, the current release is v0.5.1, and the last push was on 2026-09-25.

## FAQ

### What is StatLite and what does it monitor?

StatLite is a self-hosted metrics dashboard in a single Go binary for resource-constrained servers and VPSs. It monitors Spring Boot through Actuator JSON or Micrometer Prometheus metrics, Quarkus through Micrometer, any application implementing its small fixed JSON metrics endpoint, and itself.

### How do I install StatLite?

On macOS or Linux, pipe the install script with curl to sh, or use brew install pvrlabs/tap/statlite. There is also a Docker image published as ghcr.io/pvrlabs/statlite:latest, and the installation documentation covers supported platforms, custom install locations, source builds and server-wide Linux setup.

### Does StatLite have authentication?

No. It has no built-in dashboard or API authentication, and the documentation flags this as important and points at the server and access guidance before you expose it remotely. The sample configuration binds to a loopback address on port 9090 for that reason.

### What does a statlite.yaml configuration look like?

Four sections: a server section with the listen address, a storage section with the SQLite path, a polling section with the interval between requests, and a targets list where each entry has a name, a type and a URL. To add StatLite to an existing setup, copy only the target entry into the existing targets list.

### What does the statlite inspect command do?

It probes a running application and generates the configuration for it. You can pass a base URL for automatic detection or a type and URL for frameworks it cannot infer, such as Quarkus. Inspection checks conventional supported endpoints and is bounded and read-only, and untyped discovery expects a base HTTP or HTTPS URL with no query string or fragment.

### Is StatLite a replacement for Prometheus and Grafana?

No, and the documentation says so directly. StatLite is intentionally focused, and a separate document covers the practical tradeoffs between it, a general-purpose self-hosted stack, telemetry pipelines and hosted platforms.

## Sources

- [Official documentation](https://pvrlabs.xyz/statlite/)
- [Official README](https://github.com/PVRLabs/statlite#readme)
- [Project repository](https://github.com/PVRLabs/statlite)
- [Release notes](https://github.com/PVRLabs/statlite/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/pvrlabs-statlite
