Skip to content

Details

Where commit data comes from, how it is cached, and when changes become visible.

Storage and data flow

A separate Turso database named commits contains a table also named commits. Each record stores a Git hash, author date, and commit subject. The server queries this table and caches the results before supplying them to pages and the API.

The cache belongs to Next.js: locally it uses generated storage under .next, while Vercel manages it for the deployed site. Local and deployed environments have separate caches. The cache is separate from the source snapshot in app/commits/changelog.json.

Cache periods

Commit data and response cache periods
CacheFresh forRoutesWhat it stores
Homepage count24 hours/Only the total from a separate COUNT(*) query. Displaying this count does not refresh the full history cache.
Shared commit history24 hoursAll commit records, shared by the explorer, dated analysis pages, and API. Filtering and activity calculations use these cached records in the application.
API browser cache24 hours/api/commitsThe JSON response for a particular API URL.
API CDN cache24 hours/api/commitsThe JSON response at the CDN. Its policy also permits a stale response for up to 24 hours while revalidating.

React also deduplicates matching data reads within a server render. This is separate from the persistent Next.js caches above. Cache periods are freshness windows, not scheduled jobs or guaranteed update deadlines.

Where the caches are used

  • Home uses the 24-hour count cache for its Commits card under Tools.
  • Commits uses the 24-hour history cache for the initial count, date range, activity chart, and commit list.
  • /api/commits uses the same history cache to answer filtered requests. The response can additionally be served from the browser or CDN cache before reaching the server.
  • Dated analysis pages share the history cache: 2026-10-11, 2026-10-14, 2026-10-15, 2026-10-21, 2026-10-22.
  • Changelog uses locally maintained highlights. This Details page also renders without querying the commits database.

The homepage count can temporarily differ from the count on Commits because their freshness windows are independent.

When a refresh happens

  • An empty cache makes the next request fetch from Turso and store the result.
  • A fresh cache serves its saved result without another Turso query.
  • After the freshness window, the next request can receive the existing result while Next.js refreshes it in the background. Later requests receive the refreshed result.
  • Without a request, an expired cache does not refresh itself. Clearing or losing a cache can cause a new fetch sooner.

For example, a history fetch at 10:00 stays fresh until 10:00 the next day. If the next history request arrives at 10:20 that day, that request can trigger the refresh. Visiting Home only checks its own independent 24-hour count cache.

API response caching adds another layer, so a request served entirely by a browser or CDN does not reach the history cache. Leaving the explorer open does not poll Turso on a timer; its client cache also disables automatic focus and reconnect revalidation.

Database reads and writes

A history refresh selects every commit row. With 1,900 stored commits, one such query reads about 1,900 rows even if a page displays only 50. The homepage count query returns one number; it can still involve database reads, so it has its own 24-hour cache. A cache hit adds no Turso reads for that data.

Viewing these pages does not write commit records. Imports add new commits or update changed records, and their verification step reads the stored history. Turso usage counters accumulate operations: they do not represent the number of unique commits stored.

Publishing changes and handling failures

The update workflow is Git history, then changelog.json, then a manual import into Turso. Run bun run sync:commits after committing to refresh the snapshot and upload records. Imports preserve existing history and skip unchanged records. Deploying the site does not upload commits automatically.

An import does not invalidate either data cache. New records become visible as requests refresh the relevant caches; the homepage count can remain older for 24 hours, and API response caching can add further delay.

If a background refresh fails, Next.js can retain previously cached data. When no usable result is available, the homepage still shows its Tools links without the count, and the API returns an uncached 503 response. Runtime readers do not fall back to changelog.json.