Google Cloud — Cloud CDN
Learn about Google Cloud CDN including cache modes, origin configuration, signed URLs, cache invalidation, and integration with HTTP(S) Load Balancing..
20+ years shipping production infrastructure and CI/CD at scale. Lessons pulled from things that broke in production.
- ✓Google Cloud project with billing enabled, gcloud CLI installed and configured, basic understanding of HTTP load balancing and caching concepts, familiarity with curl and bash.
Cloud CDN is like having a specialized tool that handles the heavy lifting so you don't have to build and manage the underlying infrastructure yourself — it just works with Google Cloud.
Cloud CDN accelerates content delivery by caching static assets at Google's global edge locations. It integrates directly with the HTTP(S) Load Balancer. Proper cache configuration — cache modes, TTLs, and origin settings — directly impacts performance and cost. Signed URLs and signed cookies provide access control for premium content.
What Is Cloud CDN and Why You Should Care
Cloud CDN is Google Cloud's content delivery network, built on top of Google's global edge infrastructure. It caches content at over 150 edge locations worldwide, reducing latency and offload from your backend. If you serve static assets, API responses, or streaming content, Cloud CDN can cut response times by 50-80% and reduce origin load by 90%+. It integrates natively with HTTP(S) Load Balancers and supports custom origins (e.g., Compute Engine, GKE, or external servers). Key features: cache modes (USE_ORIGIN_HEADERS, FORCE_CACHE_ALL, FORCE_CACHE_ALL with TTL override), signed URLs/ cookies for private content, and cache invalidation. For production, you must understand cache hit ratio, TTL management, and origin shielding to avoid stampedes. Cloud CDN is not a magic bullet—misconfigured caching can serve stale data or bypass your security controls.
Setting Up Cloud CDN with HTTP(S) Load Balancer
Cloud CDN is enabled on a backend service attached to an HTTP(S) load balancer. Steps: 1) Create a backend service (e.g., with a GCE instance group or NEG). 2) Enable CDN on that backend service. 3) Create a URL map, target proxy, and forwarding rule. For production, use a global external HTTP(S) load balancer (Premium Tier) to get the full edge network. Regional load balancers also support CDN but with limited edge locations. You must also configure a public IP and DNS. Example: serve static files from a GCS bucket via a backend bucket (which automatically enables CDN). For custom origins, ensure your origin returns valid Cache-Control headers. Use gcloud compute backend-services update with --enable-cdn flag. After setup, test with curl and check the Age header to confirm caching.
--global on the forwarding rule, creating a regional LB that only cached in one region. Users outside that region got no CDN benefit. Always use global load balancers for multi-region coverage.Cache Keys and How to Control Them
Cache keys determine how Cloud CDN identifies a cached object. By default, the cache key includes the full URL (protocol, host, path, query string). You can customize which parts are included: protocol, host, query string, and even specific query parameters. Use --cache-key-include- and --cache-key-exclude- flags. For example, exclude the protocol to cache both HTTP and HTTPS versions as one object. Or include only certain query parameters (e.g., ?v=1) to avoid cache fragmentation. For API responses, consider using Cache-Control: s-maxage to set shared cache TTL. Avoid including session IDs or timestamps in cache keys—they'll kill your hit ratio. Use signed URLs for private content instead of complex cache keys. Monitor cache hit ratio in Cloud Monitoring; a ratio below 70% indicates poor key design.
--cache-key-query-string-blacklist to exclude them. Otherwise, each unique query string creates a new cache entry, reducing hit ratio._t timestamp parameter. After blacklisting it, the ratio jumped to 85%. Always audit query parameters in production.Cache Modes and TTL Configuration
Cloud CDN offers three cache modes: USE_ORIGIN_HEADERS (respects Cache-Control from origin), FORCE_CACHE_ALL (caches everything regardless of headers), and FORCE_CACHE_ALL with TTL override (caches everything with a fixed TTL). Choose based on content type: static assets (images, CSS) can use FORCE_CACHE_ALL with a long TTL (e.g., 1 hour). API responses should use USE_ORIGIN_HEADERS so you can control caching per endpoint. You can also set a default TTL via --cdn-policy-default-ttl (in seconds). For dynamic content, set Cache-Control: private, no-cache on the origin to bypass CDN. Remember: Cloud CDN respects Cache-Control: s-maxage over max-age. Use s-maxage=0 to prevent caching while still allowing browser cache. Test with curl -I and check Cache-Control and Age headers.
--cdn-policy-default-ttl with FORCE_CACHE_ALL, all responses get that TTL, even those with Cache-Control: no-cache. Use USE_ORIGIN_HEADERS for mixed content.s-maxage=60 on the origin for a 1-minute cache.Origin Shielding to Prevent Thundering Herd
Origin shielding is a feature that adds an intermediate cache layer between edge caches and your origin. When multiple edge locations miss the cache simultaneously, they all request the object from the shield, which fetches it once from the origin and serves all edges. This prevents a thundering herd problem that can overwhelm your backend. Enable it by specifying a shield location (e.g., us-central1). Choose a location close to your origin. Without shielding, a sudden traffic spike (e.g., product launch) can cause a cache stampede, leading to origin overload and increased latency. Use --enable-cdn-origin-shielding and --cdn-policy-origin-shielding-location. Monitor origin requests in Cloud Monitoring to see the reduction. Shielding adds a small latency penalty (one extra hop) but is critical for high-traffic sites.
Serving Private Content with Signed URLs and Cookies
Cloud CDN supports signed URLs and signed cookies to restrict access to private content. Signed URLs append a signature to the URL; signed cookies set a cookie that authorizes requests. Both use a shared secret key (stored in Cloud CDN) and an expiration time. Use signed URLs for temporary access (e.g., video streaming) and signed cookies for session-based access (e.g., paywalled content). Generate keys with gcloud compute backend-services add-signed-url-key. Sign URLs using HMAC-SHA256. For production, rotate keys regularly and use short expiration times (e.g., 1 hour). Never expose the signing key in client-side code. Use Cloud CDN's CdnSignedUrl or CdnSignedCookie features. Test with curl and verify that unsigned requests get 403.
Cache Invalidation: When and How
Cache invalidation removes objects from Cloud CDN before their TTL expires. Use it when you update content (e.g., new CSS version, corrected data). Invalidate by URL or by prefix (e.g., /images/*). You can invalidate up to 1000 URLs per minute per project. For large-scale invalidation, use wildcards or directory prefixes. Invalidation is not instantaneous—it propagates globally within minutes. For production, plan invalidations during low traffic. Avoid invalidating the entire cache unless necessary; it causes a cache stampede. Use versioned URLs (e.g., style.v2.css) to avoid invalidation altogether. Monitor invalidation requests in Cloud Logging. Use gcloud compute url-maps invalidate-cdn-cache.
app.abc123.js). This also enables long TTLs and eliminates invalidation costs./*) during peak hours. The resulting stampede crashed our origin. Now we only invalidate specific paths and use versioned assets.Monitoring and Debugging Cloud CDN Performance
Monitor Cloud CDN with Cloud Monitoring metrics: cache hit ratio, total requests, origin latency, and egress bytes. Set up alerts for low hit ratio (<70%) or high origin latency. Use Cloud Logging to see cache status (HIT/MISS) per request via the X-Cache header. Enable CDN logging on the backend service to get detailed logs. For debugging, use curl -I to inspect Age, X-Cache, and Cache-Control headers. Common issues: low hit ratio due to cache key fragmentation, high miss latency due to origin overload, or stale content due to long TTL. Use Cloud CDN's dashboard in the console for a quick overview. For advanced analysis, export logs to BigQuery and run queries to identify uncacheable requests.
gcloud compute backend-services update my-backend-service --enable-logging --logging-sample-rate=1.0 to log all requests. Use BigQuery to analyze cache behavior.?session=xyz added by a frontend update. We blacklisted it and hit ratio recovered.Cost Optimization with Cloud CDN
Cloud CDN costs include cache egress (data served from edge), cache fill (data fetched from origin), and invalidation requests. Egress is cheaper than origin egress, so high hit ratio saves money. Optimize by: 1) Setting appropriate TTLs to reduce cache fills. 2) Using compression (gzip) to reduce egress bytes. 3) Minimizing invalidations (use versioned URLs). 4) Enabling origin shielding to reduce origin egress (shield aggregates requests). 5) Using backend buckets for static assets (no compute cost). Monitor costs in the Billing console. For high-traffic sites, Cloud CDN can reduce overall egress costs by 50-70%. But beware: cache fills from distant origins can be expensive. Use Cloud CDN's CacheEgress and CacheFill metrics to track costs.
Production Best Practices and Common Pitfalls
After years of running Cloud CDN in production, here are the non-negotiables: 1) Always enable origin shielding. 2) Use versioned URLs for static assets. 3) Set cache keys to exclude unnecessary parameters. 4) Monitor hit ratio and set alerts. 5) Rotate signed URL keys monthly. 6) Test cache behavior with staging environment. 7) Use Cache-Control: s-maxage=0 for uncacheable content. 8) Avoid invalidating entire cache. 9) Enable logging for debugging. 10) Use backend buckets for static files. Common pitfalls: forgetting to enable CDN on the backend service, using regional LB instead of global, not setting TTLs, and ignoring cache key fragmentation. Also, Cloud CDN does not cache responses with Set-Cookie header by default—use Cache-Control: public to override (but be careful).
Set-Cookie. If you need to cache such responses, set Cache-Control: public on the origin, but understand the security implications.Set-Cookie prevented caching of a public API—fixed by removing the cookie.| File | Command / Code | Purpose |
|---|---|---|
| enable_cdn.sh | gcloud compute backend-services update my-backend-service \ | What Is Cloud CDN and Why You Should Care |
| setup_lb_cdn.sh | gcloud compute backend-services create my-backend-service \ | Setting Up Cloud CDN with HTTP(S) Load Balancer |
| custom_cache_key.sh | gcloud compute backend-services update my-backend-service \ | Cache Keys and How to Control Them |
| set_cache_mode.sh | gcloud compute backend-services update my-backend-service \ | Cache Modes and TTL Configuration |
| enable_origin_shielding.sh | gcloud compute backend-services update my-backend-service \ | Origin Shielding to Prevent Thundering Herd |
| generate_signed_url.py | from urllib.parse import urlencode | Serving Private Content with Signed URLs and Cookies |
| invalidate_cache.sh | gcloud compute url-maps invalidate-cdn-cache my-url-map \ | Cache Invalidation |
| check_cache_headers.sh | curl -I https://example.com/images/logo.png | Monitoring and Debugging Cloud CDN Performance |
| estimate_cdn_cost.sh | gcloud monitoring metrics list --filter="metric.type = loadbalancing.googleapis.... | Cost Optimization with Cloud CDN |
| cdn_best_practices.yaml | backendServices: | Production Best Practices and Common Pitfalls |
Key takeaways
style.v2.css) to avoid costly invalidations and enable long TTLs.Common mistakes to avoid
3 patternsNot understanding cloud cdn pricing model
Using default settings without tuning for cloud cdn
Missing IAM permissions and service account configuration
Interview Questions on This Topic
What is Cloud CDN and when would you use it?
Frequently Asked Questions
20+ years shipping production infrastructure and CI/CD at scale. Lessons pulled from things that broke in production.
That's Google Cloud. Mark it forged?
4 min read · try the examples if you haven't