Skip to content
Gitupcms
Esc
↑↓navigate↵open⌘Jpreview
On this page

Caching

How Gitupcms keeps GitHub calls low without a content database, and what happens when GitHub's request limit is reached.

Gitupcms has no content database. Your repository on GitHub is the only copy of your content, so there is nothing to sync and nothing to go stale. The caches below only save GitHub requests; each one is keyed so it can never serve old content.

What is cached

Layer Where Keyed by Goes stale?
File tree — One recursive tree call per request Never: read fresh each time
File text SQLite blob_cache Git blob sha Never: a changed file has a new sha
Detected schema Memory Tree sha Never: a changed repo has a new tree sha
Media dates SQLite media_date Blob sha Never
GitHub GET answers Memory, 500 entries per server Token + URL, with the ETag Never: GitHub confirms each one

File tree and file text

Each page load reads the branch’s whole file tree in one call. File contents are then read in batches through GraphQL, and only for blobs that are not cached yet. Because a blob sha is the hash of the file’s content, an edited file gets a new sha and is read again; an unchanged file is never read twice.

Conditional requests (ETag)

Every GitHub GET is sent with the ETag of its last answer. When nothing changed, GitHub answers 304 Not Modified, and a 304 does not count against the rate limit. Gitupcms then reuses the answer it already has.

  • Answers are stored per token (as a hash, never the token itself), because private repositories and permissions differ per user.
  • The cache lives in memory and holds the 500 most recent answers. A restart empties it; the first requests after a restart cost the rate limit again.

When the rate limit is reached

GitHub allows 5,000 requests an hour per user. If a user reaches it, the CMS shows “GitHub’s request limit was reached. Try again after HH:MM UTC.” with the time the limit resets, instead of a generic error.

What is not cached, on purpose

  • No time-based cache (TTL). A cached answer that expires after N minutes can show content that was changed on GitHub a minute ago. Every cache above is checked against GitHub or keyed by content, so a commit made outside the CMS shows up on the next page load.
  • No webhooks. Nothing needs to be invalidated, so there is no GitHub App or webhook to set up.

The SQLite database (DB_PATH, WAL mode) holds accounts, workspaces, settings and comments, but never page content. Clearing the blob_cache and media_date tables is safe: they refill on their own.

Was this page helpful?