Cloud CDN
Cloud CDN caches content at Google's edge POPs — over 200 locations worldwide — so users get bytes from the closest one instead of round-tripping to the origin. The result is lower user-perceived latency and dramatically lower egress cost on cacheable content.
The key fact that catches people new to Cloud CDN: it is not a standalone service. Cloud CDN is a feature flag on an external Application Load Balancer's backend service. You do not deploy a "Cloud CDN endpoint"; you enable CDN on a backend service of an existing global Application Load Balancer. Internalize this and everything else makes sense.
CDN as a Load Balancer Feature
Cloud CDN binds to a backend service on a global external Application Load Balancer. Traffic arrives at the load balancer's anycast IP, hits the nearest Google POP, and either serves from cache or fetches from the backend behind the LB. The CDN layer adds caching to the load balancing path that already existed — you do not change DNS, you do not change the URL structure, you flip a setting. Regional LBs do not support Cloud CDN; only the global Application LB does.
Cache Modes
A backend service with CDN enabled runs in one of three cache modes:
- USE_ORIGIN_HEADERS — respect the
Cache-Controlheaders your origin returns; cache when the origin says it is cacheable, do not cache when it says it is not. The most principled choice when the origin is set up correctly. - CACHE_ALL_STATIC — cache static content (images, CSS, JS, fonts, video) automatically; pass through dynamic content. The safe default for a typical web application.
- FORCE_CACHE_ALL — cache everything regardless of headers. Use only when the entire backend response is genuinely public and immutable. A single misuse — say, an authenticated API path mixed into the backend — serves one user's response to another.
Cache Key Composition
/p?id=1&utm_source=x and /p?id=1&utm_source=y become separate entries — hit rate collapses on the same content.utm_* and other irrelevant params from the cache key so identical responses share one cached object.By default Cloud CDN keys cache entries on the request's host, path, and query string. If your application's response varies on additional inputs — Accept-Language, custom headers, a logged-in cookie — you must add those to the cache key configuration. The opposite mistake is also common: leaving the query string in the cache key when it carries irrelevant tracking parameters (utm_*, gclid) causes one canonical URL to occupy hundreds of cache slots. Strip query parameters that do not affect the response.
Signed URLs and Cookies
For paywalled or otherwise restricted content (video downloads, premium assets), Cloud CDN supports signed URLs and signed cookies. The application generates a time-limited signed URL; Cloud CDN validates the signature at the edge and serves the asset without consulting the origin. Without signed URLs, the origin handles every paywall check itself — defeating most of the CDN's value when traffic spikes.
Cache Invalidation and TTL Strategy
Cache invalidation by path is supported but quota-limited and not designed for high-frequency use. Treat invalidation as a fire-extinguisher mechanism for emergencies, not as the primary content-update path. Better: version your URLs (cache-busting filenames like main.a3f7c2d.js) and let old TTLs expire naturally. Set Cache-Control: max-age appropriately at the origin — long for immutable versioned assets, short for HTML that needs freshness.
Negative Caching
Negative caching stores error responses (404, 410, 5xx) at the edge for a short TTL. Without it, every 404 on a missing image hits the origin — which under attack or popular-but-missing-asset conditions can effectively DDoS your own backend. Enable negative caching with a short TTL (a few seconds to a minute) on all production backend services.
- No CDN on public-facing apps with significant static or semi-static content — paying for origin egress and serving users slower than necessary.
- FORCE_CACHE_ALL on a backend that also serves personalized or authenticated responses — one user's response gets served to another.
- Cache key includes tracking query parameters (utm, gclid) — one canonical URL fragments into hundreds of cache entries, cache hit rate collapses.
- Cache key excludes the dimension the response actually varies on (Accept-Language, a custom segmentation header) — wrong content served from cache.
- Treating cache invalidation as the primary update mechanism — quota runs out, deploys block waiting for invalidations.
- No signed URLs for paid content — every paywall check still hits the origin even though the CDN could serve the asset directly.
- Negative caching disabled — origin gets hammered by 404s and 5xx requests that the edge could absorb.
- Enable Cloud CDN on every global Application LB backend that serves cacheable content. The cost is near zero; the benefit is real.
- Start with
CACHE_ALL_STATICunless you have explicit Cache-Control discipline at the origin. - Set Cache-Control: max-age explicitly at the origin: long for versioned immutable assets, short for HTML, no-store for personalized responses.
- Strip tracking query parameters from the cache key. Add only headers and cookies the response actually varies on.
- Use signed URLs or signed cookies for any paywalled, time-limited, or per-user assets.
- Enable negative caching with a short TTL on every production backend service.
- Version asset URLs (
main.a3f7c2d.js) so deploys do not depend on cache invalidation.
Knowledge Check
How is Cloud CDN deployed in front of a workload?
- As a standalone Cloud CDN endpoint with its own provisioned DNS hostname and anycast IP that clients resolve to directly
- As a feature flag enabled on a backend service of a global external Application Load Balancer
- By installing a CDN module inside the GKE cluster or VM that originates content
- By creating a CDN-specific Network Endpoint Group that fronts the origin
What is the risk of FORCE_CACHE_ALL cache mode?
- FORCE_CACHE_ALL silently bypasses signed-URL token validation at the edge and exposes paid, gated content to any anonymous client
- It rapidly increases cache-invalidation quota consumption because every cached path must be re-validated against the origin on each request
- Every response is cached regardless of headers; if any path serves authenticated or personalized responses, one user's response can be served to another
- It disables negative caching of 404 and 410 responses by default, leaving the origin exposed to repeated floods of requests for objects that no longer exist
Why strip tracking query parameters (utm_*, gclid) from the Cloud CDN cache key?
- Tracking parameters such as gclid and utm_source count as personal data, so caching a URL that contains them is itself a GDPR violation
- They do not affect the response, but leaving them in the key fragments one canonical URL into hundreds of cache entries, collapsing cache hit rate
- Tracking parameters break URL signing for paid content
- Cloud CDN treats any request carrying utm or gclid parameters as uncacheable and bypasses the cache entirely as a built-in safety measure for tracked traffic
What is the purpose of signed URLs in Cloud CDN?
- To rewrite cache keys so that personalized responses can be cached safely
- To allow Cloud CDN to validate access at the edge and serve paid or time-limited content without the origin handling every paywall check
- To enable and enforce encrypted HTTPS on the backend connection between Cloud CDN's edge POPs and the origin load balancer or storage bucket that holds the content
- To trigger on-demand cache invalidation for protected paths without consuming the project's per-minute invalidation quota
Why prefer versioned asset URLs (e.g. main.a3f7c2d.js) over relying on cache invalidation for deploys?
- Versioned filenames reduce egress bandwidth costs because the hashed asset URL is compressed more aggressively at the edge before the bytes ever leave Google's premium-tier network to the client
- Cache invalidation is not supported on global external Application Load Balancer backends, so a hashed filename is the only way to refresh content there
- Cache invalidation is quota-limited and not designed for high-frequency use; versioned URLs let old TTLs expire naturally with no invalidation calls per deploy
- Cloud CDN cannot serve responses larger than 1 MB without versioned URLs
You got correct