ChessInsights

How it works

ChessInsights turns Lichess broadcast PGNs into actionable insights on think-time management at the highest level of play worldwide.

The data

Each game is ingested from the public Lichess API (/api/broadcast/round/:id.pgn). PGNs contain %clk annotations (remaining time after each move) and %eval annotations (Stockfish engine evaluation).

The time spent on a move is computed, not read directly:

T_n = clk[n−1] − clk[n] + increment + phase_bonus

The time-control model is structured (phases with moveCount, baseMs, incrementMs), which makes it possible to handle any time control — FIDE classical, rapid, blitz, with or without increment.

The phases

Each move is classified as opening, middlegame or endgamebased on configurable boundaries. Defaults: 1-15 / 16-40 / 41+. Boundaries can be adjusted on the fly from a tournament's stats page (sliders persisted in the URL).

The stats produced

  • Per game: total time per side, longest thinks, breakdown by phase, clock curve.
  • Per player × tournament: time profile, average / max / min / median / standard deviation per phase.
  • Per tournament: leaderboards, aggregated analyses — clock at move 40, "out of book" depth, fatigue by round, opening × player heatmap, time × quality correlation.

The approach

No opaque machine learning. The stats are pure SQL + TS aggregations, reproducible and tested with golden files on real PGNs.

Time signals

For per-player time-management scores (Drowsy, Pressure Boss, Steadiness…), see the dedicated Time signals methodology →

The code

Open-source (private for now) on GitHub, Next.js 16 + Postgres 17 + Drizzle ORM, deployed on a VPS with GitHub Actions CI/CD.
Lichess data ↗