examlab .net The most efficient path to the most valuable certifications.
In this note ≈ 21 min

Cloud CDN

4,100 words · ≈ 21 min read ·

Master Google Cloud CDN cache modes, TTL, signed URLs, custom cache keys, invalidation, BYOIP, Cloud Armor stacking and origin choices for PCNE.

Do 20 practice questions → Free · No signup · PCNE

Introduction

Cloud CDN is Google's globally distributed edge caching service that sits in front of a Global External Application Load Balancer (gXLB) or the classic Global HTTP(S) LB. It serves cached responses from more than 200 edge Points of Presence so that requests rarely travel back to the origin in us-central1, asia-east1, or wherever the workload runs. Cloud CDN is enabled per backend service or backend bucket with a single --enable-cdn flag and is billed per cache fill, cache egress, and cache lookup. For PCNE candidates the service shows up in three recurring scenarios: lowering p95 latency for international users, reducing origin egress cost, and stacking with Cloud Armor for L7 protection at the edge.

Cloud CDN caches HTTP(S) responses at Google's edge POPs and is configured on a backend service or backend bucket of a Global External Application Load Balancer (or classic Global HTTP(S) LB). It does not attach to Regional, Internal, or Network (L4) load balancers.

Cache Modes: USE_ORIGIN_HEADERS, CACHE_ALL_STATIC, FORCE_CACHE_ALL

Cache mode controls which responses Cloud CDN considers cacheable before it even looks at TTL fields. The mode is set on the backend service via gcloud compute backend-services update BACKEND --cache-mode=MODE.

USE_ORIGIN_HEADERS

The strictest mode. Cloud CDN caches a response only if the origin returns a valid Cache-Control: public directive together with max-age or s-maxage, or an Expires header. Responses with Cache-Control: private, no-store, or no-cache are passed through. This mode is the right default when your origin already enforces caching policy (for example a Next.js or Hugo build that emits explicit headers per asset).

CACHE_ALL_STATIC

Cloud CDN automatically caches responses whose Content-Type matches a static file pattern (CSS, JS, images, fonts, video, archives) and that lack explicit private/no-store directives. Dynamic content (text/html, JSON responses without cache headers) bypasses the cache. Default TTL is 3600 seconds when the origin sends no cache headers. This mode is the easiest "turn it on and forget" option for marketing sites and SPAs.

FORCE_CACHE_ALL

Cloud CDN ignores all origin cache directives and caches every successful response, including ones marked private. Never use FORCE_CACHE_ALL in front of personalised or authenticated endpoints — you will leak one user's session HTML to the next visitor. The mode is appropriate for backend buckets serving fully public static sites or video manifests where every URL is intentionally public.

A common PCNE distractor pairs FORCE_CACHE_ALL with a backend serving logged-in dashboards. Even with signed URLs in the URL path, the cached HTML body will be served to anyone holding the same signed URL, including unauthorised parties who replay the link. Use USE_ORIGIN_HEADERS plus Cache-Control: private, no-store on personalised responses instead.

TTL Configuration and Stale-While-Revalidate

Cloud CDN exposes three TTL knobs that override or complement origin headers. They are configured via gcloud compute backend-services update:

default-ttl, max-ttl, client-ttl

  • --default-ttl (default 3600s) applies when the origin returns no cache header under CACHE_ALL_STATIC or FORCE_CACHE_ALL.
  • --max-ttl (default 86400s, max 31622400s = 1 year) caps any TTL the origin sends, preventing a misconfigured max-age=99999999 from pinning content for a decade.
  • --client-ttl controls the Cache-Control: max-age value Cloud CDN sends to the browser. Setting it lower than default-ttl keeps browsers refreshing while still hitting the edge cache.

Negative caching

Negative caching tells Cloud CDN to cache common error responses (404, 410, 451, 500, 502, 503, 504) for a short window so that a flapping origin does not get hammered. Enable with --negative-caching and tune per-status TTLs with --negative-caching-policy=404=120,500=10. Without this, every 500 from an unhealthy backend round-trips through the LB and bills as a cache miss.

Stale-while-revalidate

When a cached object has expired, Cloud CDN can still serve it (up to serve-while-stale, default 86400s) while it revalidates with the origin in the background. This protects users from latency spikes during cache fills and from short origin outages.

PCNE often tests the precedence rule: max-ttl always wins. If the origin sends Cache-Control: max-age=2592000 (30 days) but you set --max-ttl=3600, edge objects expire in one hour. If the origin sends no header, Cloud CDN uses --default-ttl. Browser caching is governed by --client-ttl, which Cloud CDN rewrites into the response.

Custom Cache Keys

Cloud CDN's default cache key is the tuple (protocol, host, path, query string). Two requests that differ only by an irrelevant query string (?utm_source=fb vs ?utm_source=tw) are treated as different objects and each forces an origin fill. Custom cache keys let you raise the hit ratio dramatically.

Including/excluding query strings

  • --cache-key-include-query-string + --cache-key-query-string-whitelist=v,locale keeps only ?v= and ?locale= in the key; UTM tags collapse into a single cache entry.
  • --cache-key-query-string-blacklist=utm_source,utm_medium,utm_campaign,fbclid,gclid is the inverse approach.

Headers and cookies in the key

Cloud CDN can fold specific request headers (--cache-key-include-http-header=X-User-Country) or named cookies (--cache-key-include-named-cookie=theme) into the key. This is how A/B variants or per-country pages are cached separately without splitting URLs.

Host and protocol

--cache-key-include-protocol=false lets HTTP and HTTPS share the same cache entry, useful when you redirect HTTP→HTTPS at the edge. --cache-key-include-host=false collapses multiple hostnames behind one bucket.

Audit your cache keys with the Cache Hit Ratio metric in Cloud Monitoring (loadbalancing.googleapis.com/https/backend_request_count filtered by cache_result). A hit ratio under 60% usually points to UTM-style query string noise — whitelist the keys you actually vary on and the ratio will jump within minutes.

Signed URLs and Signed Cookies

Signed URLs and signed cookies serve private content from the public CDN edge without forcing requests through your origin. Cloud CDN validates an HMAC-SHA1 signature attached to the request and serves the cached object if the signature is valid and unexpired.

Signed URLs

You create a request signing key on the backend with gcloud compute backend-services add-signed-url-key BACKEND --key-name=key1 --key-file=key.bin. The application then assembles a URL of the form https://cdn.example.com/video.mp4?Expires=1714521600&KeyName=key1&Signature=.... Cloud CDN verifies the signature at the edge; expired or tampered URLs return 403.

Signed cookies

Signed URLs sign one URL at a time. For an HLS stream with hundreds of segments, you instead set a single Cloud-CDN-Cookie cookie via Set-Cookie and Cloud CDN validates it against every request that matches a URL prefix. The cookie name, key, and prefix are all carried in the cookie value itself.

Key rotation

Up to three signing keys can be active per backend service simultaneously, which is the mechanism for zero-downtime rotation: add the new key, deploy the new signer, remove the old key. Cloud CDN tries each active key until one validates.

  • Signed URL keys are HMAC-SHA1, base64url, 16 bytes.
  • Maximum 3 active keys per backend service.
  • Signed URLs cache the response, not the URL — so ?Expires=…&Signature=… query strings are automatically excluded from the cache key.
  • Cookies are scoped by URL prefix (e.g. /media/).

Signed Request Authentication (Origin Authentication)

Distinct from signed URLs (which protect access to the cache), Cloud CDN signed requests let the origin trust that a request came from Cloud CDN. When you enable signed requests on a backend, Cloud CDN attaches an X-Cdn-Signature header that the origin verifies before serving. This prevents direct-to-origin bypass attacks where an attacker discovers the origin's IP and skips the LB/CDN entirely.

Configuration

Signed requests are enabled per backend service with --signed-url-cache-max-age-sec and a separate signing key set installed on the origin. The origin (typically NGINX, an App Engine app, or a Cloud Run service) computes the same HMAC and rejects mismatches with 403. Combine with origin firewall rules that only allow Google's load balancer IP ranges (130.211.0.0/22, 35.191.0.0/16) for defence in depth.

When to choose signed requests vs VPC SC vs IAP

  • Signed requests — best for external HTTPS origins (Cloud Run with --ingress=internal-and-cloud-load-balancing) where you cannot put a private VPC in front.
  • VPC Service Controls — for protecting GCS buckets serving as origins from data exfiltration.
  • IAP — for interactive internal apps; not compatible with cached public CDN content.

Cloud Storage as a CDN Origin (Backend Buckets)

Backend buckets are how Cloud CDN serves static content directly from a Cloud Storage bucket without provisioning any compute. The bucket is attached to the URL map via gcloud compute backend-buckets create static-assets --gcs-bucket-name=my-bucket --enable-cdn.

Permissions and access

The load balancer reads objects with the project's load balancer service identity; if the bucket is private, grant roles/storage.objectViewer to [email protected]. For fully public buckets, allUsers viewer is acceptable but pair with Cloud Armor edge policies to throttle abusive scrapers.

URL rewriting

A pathMatcher rule like /static/* → backend-bucket: static-assets lets one hostname mix dynamic backends (Cloud Run for /api/*) and bucket origins (/static/*) under a single CDN configuration.

Cost behaviour

Backend bucket cache fills count as internal Google Cloud egress, which is significantly cheaper than internet egress from a Compute Engine VM origin. This is the classic "lift and shift" cost optimisation for image-heavy sites.

For maximum hit ratio on backend buckets, set --cache-mode=CACHE_ALL_STATIC, --default-ttl=86400, --max-ttl=31536000, and version your filenames (logo.7f3a.svg). Then you can ship deploys without invalidation API calls — the new build references new filenames and old objects naturally age out.

GKE and Cloud Run as CDN Backends

For dynamic workloads, Cloud CDN sits in front of Network Endpoint Groups (NEGs) that point to GKE pods or Cloud Run services.

GKE container-native load balancing

A GKE Ingress with cloud.google.com/neg: '{"ingress": true}' creates a zonal NEG containing pod IPs directly (no kube-proxy hop). Enable CDN on the backend service that Ingress generates: gcloud compute backend-services update BACKEND --enable-cdn --cache-mode=CACHE_ALL_STATIC. This is the standard pattern for serving a React SPA from GKE with CDN caching the build artifacts.

Cloud Run serverless NEGs

Cloud Run services attach to the LB via a serverless NEG: gcloud compute network-endpoint-groups create cr-neg --region=asia-east1 --network-endpoint-type=serverless --cloud-run-service=my-app. Cloud CDN then caches responses based on the same cache modes. Cloud Run's own per-revision response cache is independent — CDN sits in front and can absorb traffic that would otherwise scale Cloud Run to many instances.

Health checks and CDN

Cloud CDN itself does not bypass health checks. If the LB marks a backend unhealthy, all traffic fails over to remaining healthy backends, but cached responses keep serving from the edge. This is why Cloud CDN substantially improves availability during partial origin outages.

Dynamic Compression

Cloud CDN can compress responses on the fly with Brotli (preferred) or gzip at the edge, even when the origin emits uncompressed bytes. Enable with gcloud compute backend-services update BACKEND --compression-mode=AUTOMATIC.

How automatic compression decides

Cloud CDN inspects the Accept-Encoding request header and the response Content-Type. Text-like types (HTML, CSS, JS, JSON, SVG, XML) up to 10 MB are compressed; already-compressed types (JPEG, MP4, WOFF2) are skipped. The Vary: Accept-Encoding header is added automatically so that gzip and br variants are cached separately.

When to disable

If the origin already returns Brotli (Content-Encoding: br), set --compression-mode=DISABLED to avoid double-handling. For latency-critical APIs returning tiny JSON (<1 KB), compression CPU cost can outweigh the bandwidth savings; benchmark before enabling.

Compression is separate from caching. A response can be cached uncompressed at the edge and then compressed per-request before send. This means enabling automatic compression does not invalidate existing cache entries.

Cache Invalidation

Versioned URLs are the recommended invalidation strategy, but for emergency content recalls (legal takedown, leaked credential page) Cloud CDN exposes a synchronous invalidation API.

gcloud and API

gcloud compute url-maps invalidate-cdn-cache URL_MAP --path="/news/2026/article.html" flushes a single path. Path supports a single trailing * wildcard (/blog/*) but no nested patterns. Invalidations are global and typically complete within a few minutes.

Quotas and best practice

Each project gets a default quota of 1,500 invalidations per minute but Google strongly discourages relying on invalidation in normal release flows. The reason: even after invalidation, in-flight requests already in transit may still serve the old object. Versioned filenames (app.5fa1.js) sidestep the race entirely.

Invalidation matches the URL path only. If you cache different variants by X-User-Country, every country variant is invalidated together. You cannot invalidate "just the JP variant of /home".

Bring Your Own IP (BYOIP) for Cloud CDN

BYOIP lets enterprises advertise their own publicly-routable IP ranges (RFC 7039 verified) from Google's global edge so that customers continue to hit a legacy IP block even after migrating to Cloud CDN.

How BYOIP works

You contact Google Cloud, prove ownership of the prefix via Letter of Authorization, and Google adds the prefix to its public peering announcements. The prefix becomes a regular IP address pool that you can attach to a Global External LB forwarding rule with gcloud compute addresses create my-byoip --addresses=203.0.113.10 --global.

Use cases

  • Enterprises that hard-coded IPs in third-party allowlists.
  • Acquisitions where the acquired company's domain must stay on its legacy IP for SEO and reputation reasons.
  • Carriers and SaaS providers that publish their IP space to customers as part of an SLA.

Limitations

  • Minimum prefix size is /24 for IPv4 and /48 for IPv6.
  • BYOIP for Cloud CDN is Premium Tier only; the prefix is announced from every Google POP.
  • Provisioning takes 1-4 weeks because of routing coordination.

Cloud CDN + Cloud Armor Stacking

Cloud Armor security policies attach to the same backend service as Cloud CDN, but the enforcement order matters and shows up in PCNE scenarios constantly.

Standard backend security policy

A normal Cloud Armor policy evaluates after the LB selects a backend. With CDN enabled, cache hits never reach the policy — they short-circuit at the edge. This is desirable for performance but means rate-limiting rules on cached endpoints are bypassed.

Edge security policy

Edge security policies are a Cloud Armor feature explicitly designed to run before Cloud CDN cache lookup. Configure with gcloud compute security-policies create edge-policy --type=CLOUD_ARMOR_EDGE and attach with gcloud compute backend-services update BACKEND --edge-security-policy=edge-policy. Edge policies are restricted to a subset of rule types (IP/CIDR, geo, basic preconfigured WAF) but they run at the edge before cache lookup and so they can rate-limit or geo-block cache hits.

Layered defence pattern

The recommended stack is:

  1. Edge security policy — geo-block sanctioned countries and known-bad ASNs before the cache.
  2. Cloud CDN — serve cached content for the allowed 99% of traffic.
  3. Standard security policy — full WAF (OWASP CRS, CEL expressions, reCAPTCHA Enterprise) on cache misses heading to origin.

PCNE traps to watch for: "How do you geo-block users from accessing cached marketing pages?" → Edge security policy, not a standard security policy. A standard policy would only catch users on cache miss; cached pages would still serve to blocked geos.

白話文解釋(Plain English Explanation)

Analogy 1: A Chain of Convenience Stores

Imagine your origin server is a central warehouse in Iowa. Without Cloud CDN, every customer worldwide waits for shipment from Iowa — a customer in Tokyo waits 200 ms per page load. Cloud CDN is a chain of convenience stores Google operates in 200+ cities. The first Tokyo customer requesting cat.jpg still pulls it from Iowa, but the Tokyo store keeps a copy. The next 10,000 Tokyo customers get it instantly from the Tokyo shelf. The cache mode decides what merchandise the convenience stores are allowed to stock: USE_ORIGIN_HEADERS means only items the warehouse explicitly tagged "for retail" go on the shelf, CACHE_ALL_STATIC means anything that looks like a packaged retail item gets stocked, and FORCE_CACHE_ALL means the store puts everything on the shelf — including the warehouse manager's personal mail (which is why FORCE_CACHE_ALL leaks private data).

Analogy 2: A Concert Wristband System

Signed URLs and signed cookies are like the wristband system at a music festival. The festival entrance (Cloud CDN edge) does not call back to ticketing HQ for every guest — instead each guest's wristband (signature) is checked locally by a scanner. A signed URL is a one-time wristband good for one show; a signed cookie is a multi-day wristband good for every stage in the /main-festival/* zone. Wristband colours change every season — that is the three-key rotation. If you tear off your wristband (signature expires) you cannot get back in without buying a new one (re-signing) from ticketing HQ (your auth backend).

Analogy 3: A Restaurant's "Order Receipt Filing System"

Custom cache keys are the rules a busy restaurant uses to file order receipts. Default filing is by table number (URL path) plus party size (query string). If the staff files every "table 5, party of 4, on a Tuesday, in the rain" as a different folder, the cabinet overflows. Smart restaurants file by table number only and ignore the weather (utm_source=fb). Negative caching is what stops the kitchen from re-cooking a dish that just came back burnt 10 times in a row — they remember "the oven is broken, tell the next 10 customers we are out of pizza" for 30 seconds while maintenance is called. Cache invalidation is when health inspectors burst in and order all receipts shredded immediately, but a smart restaurant just prints menus with version numbers (menu_v2.pdf) so the old menus naturally retire when the week ends.

Monitoring and Observability

Cloud CDN exposes per-backend metrics in Cloud Monitoring under loadbalancing.googleapis.com/https/:

Key metrics

  • backend_request_count{cache_result="HIT|MISS|DISABLED|UNCACHEABLE"} — drives hit ratio dashboards.
  • frontend_tcp_rtt — edge-to-client RTT, lets you see CDN's latency benefit.
  • total_latencies — end-to-end including cache fill on misses.

Logging

Enable HTTP(S) LB logging at --logging-sample-rate=1.0 during cutovers. Log entries include cacheId (the POP that served the request) and cacheLookup, cacheHit, cacheFillBytes. This lets you correlate a single user complaint with the exact edge POP and decide whether the issue is global or POP-specific.

Cache Hit Ratio targets

Healthy static asset workloads hit 90-99%. Logged-in API responses hit 0-20% (and that is fine — they should not be cached). Hit ratios stuck at 30-50% on static content usually indicate UTM noise in cache keys, missing Cache-Control headers, or Vary: User-Agent from the origin (which fragments the cache by every browser variant).

Cost Model and Optimisation

Cloud CDN bills three separate dimensions and most cost surprises come from misunderstanding which dimension dominates.

Cache egress

Bytes served from the edge to clients are billed by region. North America and Europe are cheapest; Oceania and South America are roughly 2-3x. This is usually the largest line item.

Cache fill

Bytes pulled from the origin to the edge on a miss. Cross-region fills (origin in us-central1, fill into a Sydney POP) are billed at inter-region egress rates and add up fast on low-hit-ratio backends.

Cache lookup

A small per-request fee that applies to both hits and misses. Negligible for human traffic, painful for API surfaces hit 100k+ times per second.

Optimisation playbook

  1. Raise hit ratio first — every cache hit converts a cache_fill charge into a (cheaper) cache_egress charge.
  2. Use a backend bucket for static content; bucket-to-CDN fill is internal traffic.
  3. Set sensible --max-ttl so misconfigured origin headers do not pin objects forever (and inflate cache storage costs).
  4. Use BYOIP only when business reasons demand it; standard CDN IPs are free.

FAQs

Q: Can I use Cloud CDN with an internal load balancer?

A: No. Cloud CDN attaches only to the Global External Application Load Balancer (and the legacy classic Global HTTPS LB). Regional External Application LBs, Internal Application LBs, Network LBs, and TCP/SSL Proxy LBs cannot enable CDN. For private content delivery inside a VPC, you would terminate traffic on the external LB with Cloud Armor + signed URLs, or use Media CDN for video-specific scenarios.

Q: What is the difference between Cloud CDN and Media CDN?

A: Cloud CDN is the general-purpose CDN bundled with the global HTTPS LB; it caches anything up to 5 GB per object. Media CDN is a separate product built on YouTube's edge infrastructure, optimised for very large video files (up to terabytes), live streaming with manifest manipulation, and per-request DRM token exchange. For most websites, Cloud CDN is the right choice; choose Media CDN only when serving long-form video at YouTube scale.

Q: How long does cache invalidation take to propagate?

A: Cloud CDN invalidation is typically complete in a few minutes globally, but Google does not guarantee a hard SLA. Requests already in flight at the moment of invalidation may still receive the old object. For deterministic cache busting, use versioned URLs (app.5fa1.js) instead of relying on invalidation.

Q: Does Cloud CDN respect Vary headers?

A: Yes, but with restrictions. Cloud CDN honours Vary for Accept-Encoding and Origin automatically. It does not support Vary: User-Agent or arbitrary Vary values — those responses are passed through uncached. Use custom cache keys instead (e.g. --cache-key-include-http-header=X-Device-Type) to cache variant responses.

Q: Can I use Cloud CDN with a private origin in another cloud?

A: Yes. Configure an Internet NEG pointing to the external origin's hostname (gcloud compute network-endpoint-groups create my-aws-origin --network-endpoint-type=internet-fqdn-port --default-port=443) and attach it to a backend service with --enable-cdn. Combine with signed requests so the AWS origin can verify that traffic actually originates from Google's CDN and not from a direct attacker. Hairpin egress back to AWS will incur both Google egress and AWS ingress charges, so high hit ratio is critical.

Q: How do I exclude authenticated requests from caching?

A: Three layered options: (1) Set Cache-Control: private, no-store on the response from your origin — works under any cache mode except FORCE_CACHE_ALL. (2) Use --bypass-cache-on-request-headers=Authorization,Cookie on the backend so any request carrying an auth header skips the cache entirely. (3) Use USE_ORIGIN_HEADERS mode plus correct origin headers so personalisation never enters the cache in the first place.

Q: Does enabling Cloud CDN change my LB's IP address?

A: No. Cloud CDN is configured on the backend service, not the frontend. Your global forwarding rule and its anycast IP stay the same. This is what makes "turn on CDN for an existing LB" safe — no DNS changes required, just gcloud compute backend-services update BACKEND --enable-cdn.

Official sources

More PCNE topics