feat(code.gs): gzip cache bodies + status-aware TTL (skip 5xx, cap persistent 4xx)#953
Merged
therealaleph merged 1 commit intotherealaleph:mainfrom May 9, 2026
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Three improvements to the optional spreadsheet response cache in
Code.gs. They compound: more URLs become cacheable, the cache stops being poisoned by transient outages, and 4xx storms cost zero quota.1. Gzip body before base64 storage.
_fetchAndCachenow storesbase64(gzip(rawBytes))(marked with a newZcolumn) when the response is not already content-encoded and is over 256 bytes. Most cacheable text bodies (HTML / JSON / JS / CSS) compress 3–5×, so a ~100–150 KB pre-compressed response now fits under the unchanged 35 KB cell ceiling where it previously bailed. Skip-when-already-encoded prevents double-compressing gzip/br/zstd payloads; skip-when-tiny avoids gzip's ~20-byte header bloating sub-256-byte responses._getFromCachedecompresses on hit and re-base64s for the wire — relay protocolbfield staysbase64(rawBytes), no client change.2. 5xx never enters the cache. Previously, a single 503 from a flapping upstream would pin that response for 24 h (the default TTL fallback) and break the URL for every subsequent client until expiry. Now
status >= 500early-returns the live response without writing to the sheet.3. Negative caching for persistent 4xx.
404 / 410 / 451with no upstreamCache-Controlget a 5-minute TTL instead of the 24-hour default. Long enough to absorb buggy clients hammering favicons / telemetry pixels / dev-tools probes at zero quota cost; short enough that transient 404s (e.g. eventual-consistency CDN misses) self-heal quickly. If upstream explicitly stated a max-age, we honor it instead — origin knows best when it spoke up.Schema migration
Cache sheet grew from 7 columns to 8 (added
Zflag). New deployments get the 8-column header; existing deployments keep their old 7-column header (cosmetic only —getCacheStatsdoesn't read it). Legacy 7-column rows read back withZ = undefined, which is falsy and falls through the not-gzipped branch — fully backward-compatible, no user action required.Behavior change to flag
For users relying on the previous "everything cached for 24 h" default:
Cache-Control: max-age=...on the origin if you actually want long negative caching.No behavior change for 2xx, 3xx, other 4xx, or any response where upstream specified a Cache-Control directive — those continue to honor stated max-age (or 24 h default).
Scope
Code.gsonly.CodeFull.gsdoesn't have the spreadsheet response cache (it has a separate CacheService-backed edge DNS cache, which doesn't benefit from these changes).Code.cfw.gsruns the actual fetch on a Cloudflare Worker, so caching would have to live there. Both are out of scope.Test plan
node --checkparsesCode.gscleanlygetRange(..., 7)orsetValueswidths of 7 outside meta-sheet opsrow[7] === undefined→ falsy → not-gzipped branch