Quickstart
Six steps and a configuration file. The only decision worth thinking about before you start is which store keeps the history, and you can defer that by printing the points to the terminal first.
The short way
Section titled “The short way”If you have a terminal, let it ask:
ghchronicle -setupIt asks for a token, checks with GitHub who the token is, asks which account to
collect and where to put the numbers, checks that the place answers, offers the
dashboard and offers to set it up to run by itself. What it writes is a
config.yaml that loads and, when you asked for a service, a unit, an agent or
a scheduled task for whichever system this is.
Credentials never go in the configuration. They go in a file beside it that only you can read, and the configuration refers to them by name.
The installer above offers to run it as its last step, so on a new machine the two together are the whole of getting started.
The rest of this page is what it writes, for a reader who would rather write it themselves or wants to know what they just agreed to.
Zero to a first sweep
Section titled “Zero to a first sweep”-
Install the binary.
Terminal window curl -fsSL https://raw.githubusercontent.com/jmrplens/ghchronicle/main/install.sh | bashOn Windows, in PowerShell:
Terminal window irm https://raw.githubusercontent.com/jmrplens/ghchronicle/main/install.ps1 | iexTake the archive for your platform from the releases page and put
ghchronicleon yourPATH.Terminal window docker pull ghcr.io/jmrplens/ghchronicleTerminal window go install github.com/jmrplens/ghchronicle/v2/cmd/ghchronicle@latest -
Create a token at
https://github.com/settings/tokensand export it.Terminal window export GITHUB_TOKEN=github_pat_...A classic token with
repo,read:packages,read:user,read:org,security_events,read:public_keyandread:gpg_keysees everything this collects. The token page explains which scope buys which family, and why the automaticGITHUB_TOKENof an Action is not enough. -
Write the configuration. Two decisions, and this is the whole file:
config.yaml github:token: ${GITHUB_TOKEN}targets:user: your-loginsinks:stdout: true # swap for influxdb once you have somewhere to put itA
${VAR}in a credential, an address or a file path is read from the environment at start-up, so the file itself holds no secrets and can be committed. Everything else has a default.The documented version, which comments every option there is, lives in the repository rather than in the install, so take it from there when you want to read the rest:
Terminal window curl -O https://raw.githubusercontent.com/jmrplens/ghchronicle/main/config.example.yaml -
See what would be collected, before spending any quota on it.
Terminal window ghchronicle -config config.yaml -listThat prints the repositories in scope. Forks and archived repositories are excluded by default. If something you expected is missing, this is the command that tells you.
-
Run one sweep.
Terminal window ghchronicle -config config.yaml -onceWith
sinks.stdout: truethe points go to the terminal as line protocol instead of to a database, which is the cheapest way to see the shape of what you are about to store. -
Leave it running.
Terminal window ghchronicle -config config.yamlEach family then runs on its own cadence: workflow runs every fifteen minutes, the contribution calendar every hour, the account’s SSH and GPG keys once a day.
What the first sweep does that later ones do not
Section titled “What the first sweep does that later ones do not”Four things happen once, and they are why the first run is the expensive one.
- The daily star history of every repository, whatever the token may see, is read back to the repository’s first week, and the whole stargazer list of every repository whose list the token may read (since July 2026, only a repository’s admins and collaborators) is walked, page by page, so each of those stars carries the moment it was given and who gave it. After that, the history is one request per repository for its newest thirty weeks, usually a free 304, and the newest hundred stars of each readable list ride in one GraphQL query per ten repositories.
- A month of workflow runs, so a fresh install does not chart a CI history that begins fifteen minutes ago. After that, twice the cadence, and never less than two hours.
- The co-authored pull requests of the account’s whole life, which
achievementswalks for the Pair Extraordinaire count: 35 queries and 23.7 MB over 2,315 merged pull requests, measured on 2026-09-27. After that a pass walks the days since, one page, and the whole history again once a week. - Every year’s contribution calendar, if
every.families.historyis set, back to the day the account was created. After that, only the year in progress, rewritten at its cadence.
Nothing is cached yet either, so every answer of the first sweep is paid in full, where a later one asks with the ETag the last answer came with and is mostly answered a free 304; see the cache beside the state file.
Expect a few thousand points from a first sweep of twenty repositories, and a few hundred from each one after.
None of that is the history. The first sweep is a wider increment, and a
dashboard at ninety days or two years then begins on the day you installed the
collector: measured after a day of sweeps, about a fifth of the pull requests
the repositories report, commits from the last thirty days only, and jobs for
a tenth of the workflow runs. Run ghchronicle -config config.yaml -backfill
once, before the service or right after it;
the backfill page says what it reaches and what
it costs.
Where to go next
Section titled “Where to go next”- Ways to install is what turns the command above into something that keeps running: systemd, Docker or a scheduled Action.
- Dating a point is the design idea everything else follows from.
- Choosing a store decides which questions you will be able to ask later.
- Cost of a sweep is the measured price in API calls.