You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
wait0 checks RAM, then disk, and waits for the origin only on a cache miss. A cached response is returned immediately. **Even when it is older than `expiration`, wait0 serves it first and refreshes it asynchronously.** Therefore, `expiration: '1m'` is a stale-after signal, not a hard expiry or eviction.
145
+
146
+
wait0 caches only `GET` responses with a `2xx` status, an allowed `Content-Type`, and no `Cache-Control: no-cache` or `no-store` directive. `cachableContentType` defaults to `text/html` and `application/xhtml+xml`, including values with parameters such as `text/html; charset=utf-8`. This keeps wait0 focused on controllable dynamic SWR; static assets should normally be cached by a CDN, Nginx, and browser caching.
147
+
148
+
An origin response that fails these checks is served as `X-Wait0: bypass` without being stored, with `X-Wait0-Reason` explaining why. If background revalidation receives a disallowed content type, either cache-control directive, or a non-`2xx` status, the existing entry is deleted; a network error leaves it available. A stale response is reported as `X-Wait0: hit`.
149
+
150
+
### Query parameter caching
151
+
152
+
Cache keys use only the URL path by default, so `/blog`, `/blog?page=1`, and `/blog?utm_source=email` share the same cached response. The first cold request reaches the origin with its complete query and fills the shared entry; later background refreshes omit query parameters that are not in `varyByQueryParams`.
153
+
154
+
Use `varyByQueryParams` to explicitly choose the parameters that must create different entries:
155
+
156
+
```yaml
157
+
varyByQueryParams: ['page', 'lang']
158
+
```
159
+
160
+
With this setting, `/blog?page=1` and `/blog?page=2` are different cache entries, while an unlisted parameter such as `utm_source` is ignored for cache identity and background refreshes. Allowed parameter names and values are normalized into a stable order.
136
161
137
-
Use `varyByQueryParams` on a rule when only a small set of query parameters should affect cache identity.
162
+
### Sitemap warmup
138
163
139
-
Example:
164
+
`urlsDiscover` reads sitemap files and registers their paths in the disk cache. It supports sitemap indexes, gzip sitemaps, absolute URLs, and origin-relative paths. Discovery does not fetch each page body by itself: add `warmUp` to a matching rule to fetch and periodically refresh the discovered paths. Paths with no matching rule, or a rule with `bypass: true`, are ignored.
165
+
166
+
### Config file reference
167
+
168
+
This example contains every current configuration option. Durations use Go syntax such as `10s`, `1m`, or `2h`; sizes accept bytes or `k`, `m`, and `g` suffixes.
140
169
141
170
```yaml
171
+
storage:
172
+
ram:
173
+
# Maximum RAM cache size.
174
+
max: '100m'
175
+
disk:
176
+
# Maximum LevelDB cache size.
177
+
max: '1g'
178
+
179
+
server:
180
+
# HTTP port; defaults to 8080 when omitted or set to 0.
181
+
port: 8082
182
+
# Required origin base URL.
183
+
origin: 'http://host.docker.internal:8080'
184
+
185
+
invalidation:
186
+
# Enables POST /wait0/invalidate.
187
+
enabled: true
188
+
# Maximum number of waiting asynchronous invalidation jobs; default 128.
189
+
queue_size: 128
190
+
# Number of invalidation workers; default 4.
191
+
worker_concurrency: 4
192
+
# Maximum invalidation request body in bytes; default 1 MiB.
193
+
max_body_bytes: 1048576
194
+
# Recommended maximum normalized paths per request; default 1024.
195
+
max_paths_per_request: 1024
196
+
# Recommended maximum normalized tags per request; default 1024.
197
+
max_tags_per_request: 1024
198
+
# true rejects requests over path/tag limits; false accepts and logs them.
199
+
hard_limits: false
200
+
201
+
auth:
202
+
tokens:
203
+
# Unique name used for authentication and audit logs.
204
+
- id: 'backoffice'
205
+
# Optional inline secret/fallback; prefer token_env in production.
206
+
token: 'replace-me'
207
+
# Environment variable whose non-empty value overrides token.
# Only these query parameters become part of the cache key.
237
+
varyByQueryParams: ['page', 'lang']
238
+
# Stale-after age: serve cached data immediately, then refresh async;
239
+
# omit to disable request-triggered age refresh.
146
240
expiration: '1m'
241
+
warmUp:
242
+
# Refresh all known matching paths at this interval, regardless of age.
243
+
runEvery: '10m'
244
+
# Maximum concurrent requests for this warmup rule.
245
+
maxRequestsAtATime: 20
246
+
247
+
logging:
248
+
# Logs a stats snapshot at this interval; omit to disable.
249
+
log_stats_every: '1m'
250
+
# Logs a summary after each warmup batch.
251
+
log_warmup: true
252
+
# Logs details for each scanned sitemap.
253
+
log_url_autodiscover: true
147
254
```
148
255
149
-
With that rule:
150
-
151
-
- `/blog`and `/blog?utm_source=newsletter` use the same cache entry because `utm_source` is ignored.
152
-
- `/blog?page`uses a different cache entry from `/blog`.
153
-
- `/blog?page=1`uses a different cache entry from both `/blog` and `/blog?page`.
154
-
- If multiple values are present for an allowed parameter, wait0 canonicalizes them into a stable key order.
256
+
Compatibility-only options are still accepted but should not be used in new files: `urlsDiscover.initalDelay`is the old spelling of `initialDelay`, `logging.log_revalidation_every` is replaced by `log_warmup`, and `server.invalidation.tokens` is replaced by top-level `auth.tokens`.
155
257
156
258
## Redeploy Note
157
259
@@ -163,7 +265,7 @@ If stale HTML is still cached, clients can receive pages that point to missing a
163
265
To reduce this risk, `wait0` clears disk cache on startup by default (`WAIT0_INVALIDATE_DISK_CACHE_ON_START=true`).
164
266
That behavior makes rollout safer because old HTML is not reused across deploy generations.
165
267
166
-
Hpowever, during redeploy you still need to restart wait0 by explicitly orchestrating it (for example, docker restart wait0).
268
+
However, during redeploy you still need to restart wait0 by explicitly orchestrating it (for example, `docker restart wait0`).
167
269
168
270
If you do not restart between deploys, proactively refresh cache using invalidation and warmup for critical routes.
169
271
@@ -174,7 +276,8 @@ If you do not restart between deploys, proactively refresh cache using invalidat
174
276
- Rule field `varyByQueryParams[]` opts specific query parameters into cache identity for matching paths.
175
277
- Query parameters not listed in `varyByQueryParams[]` and all fragments are ignored for cache identity.
176
278
- Only `GET` requests are cache candidates.
177
-
- Only origin `2xx` responses are stored.
178
-
- For stale entries (rule `expiration`), wait0 serves cached response immediately and revalidates asynchronously.
179
-
- For origin non-`2xx`, wait0 skips caching and evicts any existing key for that path.
279
+
- Only origin `2xx` responses matching the rule's `cachableContentType` allowlist are stored.
280
+
- `cachableContentType`defaults to HTML and XHTML; use CDN, reverse-proxy, and browser caches for static assets.
281
+
- Rule `expiration` marks entries stale but does not evict them; stale responses are served immediately and revalidation is scheduled on a best-effort basis.
282
+
- On a cache-path miss or revalidation, an origin non-`2xx` is not cached and any existing key is evicted.
180
283
- Invalidation is asynchronous: accept request -> resolve keys by `paths` and `tags` -> delete keys -> recrawl in background. Path invalidation clears all cached query-aware variants for that path.
- the media type in `Content-Type` appears in the matching rule's `cachableContentType` list, and
46
49
-`Cache-Control` does not include `no-store` or `no-cache`.
47
50
51
+
`cachableContentType` defaults to `text/html` and `application/xhtml+xml`. Matching is case-insensitive and ignores media-type parameters such as `charset=utf-8`. A missing or malformed `Content-Type` is not cacheable.
52
+
48
53
## Response headers added by wait0
49
54
50
55
| Header | When present | Meaning |
51
56
|--------|--------------|---------|
52
57
|`X-Wait0`| always on handled responses | Cache/proxy decision marker |
58
+
|`X-Wait0-Reason`| response bypassed or failed | Machine-readable reason the response was not cached |
53
59
|`X-Wait0-Revalidated-At`| cache `hit` with revalidation metadata | Last revalidation timestamp (RFC3339Nano) |
54
60
|`X-Wait0-Revalidated-By`| with `X-Wait0-Revalidated-At`| Revalidation source (`user`, `warmup`, `invalidate`, etc.) |
55
61
|`X-Wait0-Discovered-By`| if entry was discovery seeded | Discovery source marker |
Copy file name to clipboardExpand all lines: docs/for-developers.md
+6-1Lines changed: 6 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -128,6 +128,7 @@ For dashboard:
128
128
|`priority`| no | Rules are sorted ascending by priority |
129
129
|`bypass`| no | For matching paths, bypass cache completely |
130
130
|`bypassWhenCookies[]`| no | If any listed cookie exists, bypass cache |
131
+
|`cachableContentType[]`| no | Exact cache-eligible media types; defaults to `text/html` and `application/xhtml+xml`; parameters are ignored |
131
132
|`varyByQueryParams[]`| no | Query params that should participate in cache identity for matching paths |
132
133
|`expiration`| no | Duration for stale check and async revalidation |
133
134
|`warmUp.runEvery`| with `warmUp`| Duration, must be `> 0`|
@@ -157,9 +158,13 @@ For dashboard:
157
158
- Rule field `varyByQueryParams[]` opt-ins selected query params so `/a/b?page`, `/a/b?page=1`, and `/a/b` can be distinct cache entries.
158
159
- Query params not listed in `varyByQueryParams[]` and all fragments are ignored for cache identity.
159
160
- Only `GET` requests are cache-eligible.
161
+
- Bypassed and non-`GET` requests are sent upstream as `GET` without the original body.
160
162
- Non-2xx origin responses are not cached and existing cached key is removed.
161
-
- Dynamic pages are expected to send `Cache-Control: no-cache` or `no-store` so wait0 treats them as passthrough and revalidation-managed.
163
+
- Origin responses whose media type is not in `cachableContentType` are served but not stored; background revalidation deletes an existing entry if its new media type is disallowed.
164
+
- We recommend to Keep static assets in CDN, Nginx, and browser caches; wait0 defaults to caching only dynamic HTML/XHTML SWR responses.
165
+
- Origin `2xx` responses with `Cache-Control: no-cache` or `no-store` are not stored; either directive received during revalidation deletes the existing entry.
0 commit comments