SelfHost Hub SelfHost Hub
中文
← Back to all services

GitHub repository information

Fetched · June 5, 2026
★ 181 Latest: v0.9.0 Updated: June 4, 2026
README
# ghstats

<div align="center">

🤩📈 Self-hosted GitHub traffic analytics with long-term history, SQLite storage,
and a tiny Docker image.

[<img src="https://badges.ws/github/release/vladkens/ghstats" alt="version" />](https://github.com/vladkens/ghstats/releases)
[<img src="https://badges.ws/github/license/vladkens/ghstats" alt="license" />](https://github.com/vladkens/ghstats/blob/main/LICENSE)
[<img src="https://badges.ws/badge/-/buy%20me%20a%20coffee/ff813f?icon=buymeacoffee&label" alt="donate" />](https://buymeacoffee.com/vladkens)

</div>

<div align="center">
  <img src="https://github.com/vladkens/ghstats/blob/assets/preview.png?raw=true" alt="preview" />
</div>

GitHub only keeps repository traffic data for 14 days. `ghstats` continuously
pulls that data from the GitHub API and keeps your own history of views, clones,
stars, forks, issues, and pull requests in a local SQLite database.

Use it for personal projects, open-source portfolios, organization dashboards,
or public stats pages where GitHub's built-in traffic tab is too short-lived.

## Features

- Long-term history for GitHub repository traffic beyond the 14-day GitHub limit
- Per-repository dashboards for stars, clones, views, referrers, and popular paths
- Automatic hourly sync for public repos, with optional private repo support
- Repo filtering by owner, exact name, forks, and archived status
- JSON API for exposing collected stats to personal sites or other tools
- Small self-hosted deployment: one Rust binary, one SQLite database, one Docker image

## Quick start

```sh
docker run -d --env-file .env -p 8080:8080 -v ./data:/app/data --name ghstats ghcr.io/vladkens/ghstats:latest
```

Open http://127.0.0.1:8080 after the container starts.

Note: ghstats Docker images run as a non-root user. If you upgrade an existing
installation and the container cannot write to SQLite, fix the mounted data
directory ownership once:

```sh
docker run --rm -u root -v ./data:/app/data ghcr.io/vladkens/ghstats:latest chown -R appuser:appgroup /app/data
```

Docker Compose:

```yaml
services:
  ghstats:
    image: ghcr.io/vladkens/ghstats:latest
    container_name: ghstats
    restart: always
    environment:
      - GITHUB_TOKEN=???
    env_file: .env # or with .env file
    ports:
      - 8080:8080
    volumes:
      - ./data:/app/data
```

## Why ghstats?

- **Own your history**: keep traffic data for months or years instead of losing it
  after two weeks.
- **Keep the setup boring**: no Postgres, no hosted account, no frontend build
  pipeline in production.
- **Publish only what you want**: filter repositories, hide forks or archived
  projects, and expose a read-only dashboard or API.

### Build locally with Docker Compose

This repository includes a `compose.yml` that builds the local `Dockerfile`, loads variables from `.env`, and stores SQLite data in a Docker named volume.

```sh
docker compose up --build -d
```

By default, the local compose setup exposes the app at http://127.0.0.1:8080. You can change the host port with `HOST_PORT` in `.env`.

### Github token generation

`ghstats` needs Github Token to collect traffic data from API. Token can be obtained with following steps:

1. Go to https://github.com/settings/tokens
2. Generate new token > Generate new token (classic)
3. Enter name, e.g.: `ghstats`. Scopes: `public_repo`
4. Click genereate token & copy it
5. Save token to `.env` file with name `GITHUB_TOKEN=ghp_XXX`

Note: If you want to access private repos too, choose full `repo` scope and set `GHS_INCLUDE_PRIVATE=true` to env.

## How it works?

Every hour `ghstats` loads the list of public repositories and their statistics, and saves the data in SQLite. If at the first startup there is no repositories in the database, synchronization will happen immediately, if `ghstats` is restarted again, synchronization will be performed according to the scheduler. Data is stored per day, re-fetching data for the current day will update existing records in the database.

All public repositories that can be accessed are saved. If you need more detailed configuration – open PR please.

## Configuration

### Host & Port

You can to change default host / port app will run on with `HOST` (default `0.0.0.0`) and `PORT` (default `8080`) environment variables.

### Metrics schedule

You can change how often metrics are pulled with the `GHS_CRON_SCHEDULE` environment variable. It uses the six-field cron format from `tokio-cron-scheduler`. The default is `0 59 * * * *`, which runs at minute 59 of every hour.

For example, to pull metrics once per day at 00:59:

```sh
GHS_CRON_SCHEDULE="0 59 0 * * *"
```

### Custom links

If you plan to display your stats publicly, there is an option to add custom links to the header via environment variables, e.g.:

```sh
GHS_CUSTOM_LINKS="Blog|https://medium.com/@vladkens,Github|https://github.com/vladkens,Buy me a coffee|https://buymeacoffee.com/vladkens"
```

### Filter repos

You can filter repos for display (and data collection). You can select a specific org/user or a specific list of repositories. This is configured via the `GHS_FILTER` environment variable. You can use negation in the rules to remove a specific repo or org/user using the `!` symbol. By default, all repos are shown.

_Note: Statistics on previously downloaded repos remain in database, but they are hidden from display._

Usage examples:

```sh
GHS_FILTER=vladkens/macmon,vladkens/ghstats # show only this two repo
GHS_FILTER=vladkens/*,foo-org/bar # show all vladkens repos and one repo from `foo-org`
GHS_FILTER=vladkens/*,!vladkens/apigen-ts # show all vladkens repos except `apigen-ts`
GHS_FILTER=*,!vladkens/apigen-ts,!foo-org/bar # show all repos expect two

GHS_FILTER=*,!fork # show all repos expect forks
GHS_FILTER=vladkens/*,!fork # show all vladkens repos expect forks
GHS_FILTER=*,vladkens/some-fork,!fork # show all repos expect forks and keep `some-fork`

GHS_FILTER=*,!archived # show all repos expect archived
```

Filtering rules:

- If no filter provided all repos will be shown (implicitly `*`)
- There are two kind of rules: direct (`foo/bar`, `foo/*`) and meta (`*`, `!fork`, `!archived`)
- Direct rule can be wildcard (`foo/*` – include all repos of `foo` org / user)
- Direct rules are applied first, then meta
- If no direct rules specified, all repos included by default (implicitly `*`)
- If at least one direct rule – all repos excluded by default (pass `*` explicitly to include all)
- Meta-exclusion rules are: `!fork`, `!archived`
- Wildcard rules do not work with meta-exclusion rules

### API endpoint

You have the ability to get collected data by `ghstats` via API. At the moment there is only one method available to get all repos list – if you need other data – open PR, please. `GHS_API_TOKEN` environment variable must be set for the API to work. All API calls if protected by `x-api-token` header, which should be same with `GHS_API_TOKEN` variable. CORS is enabled for all hosts, so you can access API from personal pages.

#### Endpoints

`/api/repos` – will return list of all repos and overall metrics. Data returted in JSON format. Usage example:

```sh
curl -H "x-api-token:1234" http://127.0.0.1:8080/api/repos
```

```jsonc
{
  "total_count": 20,
  "total_stars": 1000,
  "total_forks": 200,
  "total_views": 20000,
  "total_clones": 500,
  "items": [
    {
      "id": 833875266,
      "name": "vladkens/ghstats",
      "description": "🤩📈 Self-hosted dashboard for tracking GitHub repos traffic history longer than 14 days.",
      "date": "2024-09-08T00:00:00Z",
      "stars": 110,
      "forks": 1,
      "watchers": 110,
      "issues": 5,
      "prs": 1,
      "clones_count": 90,
      "clones_uniques": 45,
      "views_count": 1726,
      "views_uniques": 659
    }
    // ...
  ]
}
```

## 🤝 Contributing

All contributions are welcome! Feel free to open an issue or submit a pull request.

## 🔍 See also

- [repohistory](https://github.com/repohistory/repohistory) – NodeJS application as a service.

Discover more

Social media management software to easily create, schedule, publish, and manage social media content in one place (alternative to Hootsuite, Buffer, and other social media tools).

6/5/2026 Details →