Skip to content

Static assets are served with a 10-minute TTL: every user re-downloads ~4 MB of unchanged JS all day #212

Description

@sspickle

app.yaml sets no default_expiration and no per-handler expiration:, so GAE applies its default of 10 minutes to every static file:

$ curl -sI https://www.glowscript.org/package/glow.3.2.min.js | grep -i cache-control
cache-control: public, max-age=600

glow.3.2.min.js is 4.3 MB. A student in a two-hour lab re-downloads it roughly a dozen times.

What the traffic looks like

A 2000-request sample of the last 24h of request_log. 99% of bytes are static assets:

URL bytes requests
/package/glow.3.2.min.js 158.1 MB 43
/package/RScompiler.3.2.min.js 45.1 MB 41
/lib/ace/ace.js 10.1 MB 20
/lib/jquery/2.1/jquery-ui.custom.min.js 7.9 MB 42
/lib/plotly.js 6.0 MB 1
/ (the app itself) 2.2 MB 323

(A sample, not a daily total — but the ratio is the point.)

⚠️ The obvious fix is unsafe for the file that matters most

default_expiration: 365d looks like a one-line win. It is not, and the reason is worth recording.

The version in the filename is the release line, not the content. glow.3.2.min.js has 65 commits and last changed 2025-03-29 — it keeps being modified under a fixed URL. Pinning it for a year would leave a stale copy in students' browsers after a fix ships, with no way to bust it.

The rule is: a long TTL is safe only if the URL changes when the bytes change.

Older lines are effectively frozen:

file size last changed commits
package/glow.3.2.min.js 4308 KB 2025-03-29 65
package/glow.3.1.min.js 4296 KB 2021-10-22 10
package/glow.3.0.min.js 4295 KB 2021-03-25 21
package/glow.2.9.min.js 4293 KB 2020-05-01 19
package/glow.2.8.min.js 5222 KB 2019-06-20 1
package/glow.2.7.min.js 4398 KB 2019-06-19 73
package/RScompiler.3.2.min.js 1357 KB 2024-01-09 28
package/RSrun.3.2.min.js 107 KB 2022-08-04 4
lib/plotly.js 5821 KB 2018-08-09 3
lib/ace/ace.js 529 KB 2022-03-18 8

Proposal — three tiers

1. Frozen release linesexpiration: 365d per handler, today. glow.3.1 and older have not changed in 4+ years; a new release gets a new filename. Zero risk.

2. Vendored third-partylib/ace, lib/jquery, lib/plotly.js. Versioned by directory or frozen since 2018, and not ours to modify. Same treatment.

3. The current dev line (glow.3.2.min.js, RScompiler.3.2.min.js) — where the 158 MB actually is, and the one that cannot take a long TTL as-is. Needs a content-derived URL so it changes when the bytes do. More work, and worth doing separately.

Tiers 1 and 2 are a few lines of YAML and take a real bite out of egress on their own.

Not a CDN problem

Worth stating so nobody reaches for the wrong tool: GAE already serves these from Google's edge. Unlike the Cloud Run deploys, no CDN needs adding — the only thing missing is the cache policy.

Found while investigating unrelated /google/auth 500s (#210 / #211).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions