Caching
How Pages CMS caches config, collections, media, and permission data.
Pages CMS uses GitHub as the source of truth and a DB cache for fast reads.
Cache layers
| Layer | Scope | Purpose |
|---|---|---|
config table |
Per owner/repo/branch |
Stores parsed .pages.yml and its SHA. |
cache_file table |
Per folder path | Stores collection/media directory listings and file metadata. |
cache_permission table |
Per user/repo | Caches access checks used by file cache endpoints. |
| In-memory TTL caches | Per server process | Short-lived branch HEAD and repository metadata lookups. |
Config lifecycle
- UI/API requests call
getConfig. - If DB has config, it is returned immediately.
- If DB is missing config and a GitHub token is available, Pages CMS fetches
.pages.ymlfrom GitHub, parses it, upserts DB, then returns it. - Optional sync mode (
sync: true) can compare DB SHA with GitHub SHA using a TTL gate.
This bootstrap-on-miss guarantees first-open repos still load config even before webhooks run.
Collection and media lifecycle
- Request checks cache row for the requested folder.
- On cache miss, Pages CMS fetches from GitHub and writes cache before responding.
- On cache hit, stale-while-revalidate logic can run async reconcile using branch HEAD + per-file SHA checks.
- Create/update/delete/rename operations update cache rows directly after successful GitHub writes.
This keeps normal navigation fast and makes writes visible immediately.
Staleness behavior
- Backend cache uses DB rows plus TTL and reconcile logic.
- Client state (for example current config in layout/provider) is in-memory for the current session and may lag external edits until refresh or polling updates.
- Background reconcile does not block user navigation; stale data can be served while refresh runs.
Webhook push behavior
GitHub push webhooks use a tiered strategy to keep webhook responses fast while avoiding broad cache resets on normal commits:
- For small pushes, Pages CMS applies incremental file cache updates.
- For medium pushes, Pages CMS skips per-file processing and invalidates only affected cache paths.
- For very large pushes, Pages CMS invalidates the full branch cache as a safety fallback.
All fallback modes invalidate cache only. The next user request repopulates data on demand.
Environment variables
| Variable | Unit | Default | Purpose |
|---|---|---|---|
CACHE_CHECK_MIN |
minutes | 5 |
Reconcile interval for file cache freshness checks. |
CONFIG_CHECK_MIN |
minutes | 5 |
TTL gate for config SHA checks when sync is enabled. |
FILE_TTL_MIN |
minutes | 1440 |
Max age for cache_file rows (-1 no expiry, 0 no cache). |
PERMISSIONS_TTL_MIN |
minutes | 60 |
Max age for cache_permission rows (0 always recheck GitHub). |
BRANCH_HEAD_TTL_MS |
milliseconds | 15000 |
In-memory TTL for branch HEAD lookups. |
REPO_META_TTL_MS |
milliseconds | 15000 |
In-memory TTL for repo metadata snapshot lookups. |
WEBHOOK_PUSH_INCREMENTAL_MAX_FILES |
files | 120 |
Max changed paths for incremental push processing. |
WEBHOOK_PUSH_SCOPED_INVALIDATION_MAX_FILES |
files | 800 |
Max changed paths for scoped invalidation before full branch invalidation. |
Legacy aliases are still accepted for backward compatibility.