- Why browser-cached graphs show yesterday's data
- Query-parameter cache busting with template variables
- HTTP Cache-Control headers for weather images
- CDN purge strategies for Cloudflare, AWS, and others
- Balancing freshness against bandwidth for graph images
Few things frustrate station operators more than uploading a fresh graph every five minutes, only to have visitors report they see yesterday’s data. The culprit is almost always caching — browser, proxy, or CDN — serving a stored copy instead of fetching the latest version. This guide walks through the caching layers between your station and the viewer’s screen, and provides field-tested solutions that work across the common hosting environments used by weather-station publishers. For the broader publishing context, see Publishing Fundamentals.
How Browser Caching Works
When a browser downloads an image, it stores a local copy keyed by the full URL including query parameters. On subsequent requests, the browser checks its cache rules:
- If the URL matches and the cache is still “fresh” (based on
Cache-ControlorExpiresheaders), the browser uses the cached copy without contacting the server at all. - If the cache entry is “stale” but exists, the browser may send a conditional request (
If-Modified-SinceorIf-None-Match) and get a304 Not Modifiedresponse. - If no cache entry exists, the browser fetches the image fresh.
The problem for weather graphs: the filename typically stays the same (temp_24h.png), so the browser treats every request as the same resource and serves from cache.
Cache-Busting with Query Parameters
The most reliable technique is appending a unique query parameter to the image URL at each publish cycle. Since the browser uses the full URL as the cache key, a different query string forces a fresh fetch:
<!-- In your template -->
<img src="/images/temp_24h.png?v=<%publish_timestamp%>"
width="800" height="400"
alt="24-hour temperature graph" />The publish_timestamp variable changes at each upload cycle, generating URLs like temp_24h.png?v=1709654400. The browser sees a new URL and fetches the latest version.
Alternative: File Hash Naming
A more aggressive approach renames the file itself with a hash or timestamp:
<img src="/images/temp_24h_<%hash%>.png" ... />This is more work to set up but ensures no caching layer can serve a stale version. The downside is that old files accumulate on the server unless you add a cleanup routine.
HTTP Cache-Control Headers
Server-side headers tell browsers and CDNs how long to cache a resource. For weather graphs that update every few minutes, configure headers that balance freshness against bandwidth:
# For weather graph images
Cache-Control: public, max-age=120, must-revalidate
# For static assets that rarely change (CSS, fonts)
Cache-Control: public, max-age=31536000, immutableA max-age=120 (2 minutes) for graph images means the browser caches the image for at most 2 minutes before revalidating. Combined with query-parameter cache busting, this provides a solid two-layer defence against stale images.
CDN-Specific Notes
- Cloudflare — caches by full URL including query string. Set a Page Rule for
/images/*with “Cache Level: Standard” and “Edge Cache TTL: 2 minutes” for weather graphs. - AWS CloudFront — by default does NOT include query strings in the cache key. You must explicitly configure the distribution to forward query strings.
- Shared hosting (no CDN) — relies on browser caching and server headers. Query-parameter cache busting is usually sufficient.
Troubleshooting Matrix
| Symptom | Likely Cause | Fix |
|---|---|---|
| Graph shows old data even after hard refresh | CDN serving cached version | Check CDN cache rules; purge CDN cache; add query-parameter cache busting |
| Graph updates on one browser but not another | Different cache states per browser | Clear cache in the stale browser; implement cache busting so all browsers get fresh copies |
| Query parameter changes but image still stale | CDN stripping query parameters from cache key | Configure CDN to include query strings; or switch to filename hashing |
| Mobile shows stale, desktop shows fresh | Mobile browser aggressive caching or mobile CDN proxy | Add Cache-Control: no-cache for graph paths; or use file hashing |
| All graphs stale, HTML is fresh | Image upload order issue — HTML uploaded before images | Configure upload order: images first, HTML last. See FTP Publishing |
FAQ
Does cache busting increase bandwidth usage?
max-age to your publish interval so the browser only re-fetches once per cycle.