
Cloud CDNAuthorCloudBrum editorial teamLast reviewedReading time~12 minLevelBeginner to advanced
Google Cloud · Networking · Edge caching on the external Application Load Balancer
Cloud CDN is a switch you turn on for a backend of Google’s external Application Load Balancer, and from then on responses are cached in Google’s edge locations. There is no separate network to set up: the same front end that terminates TLS and routes by URL also decides whether an answer can come from the cache. That is a strength, because one set of rules covers routing, caching and protection with Cloud Armor, and a weakness, because you need a load balancer first, and its charges come with it. The settings that matter are the cache mode, the cache key and how long things live.
On this page (17 sections)
Mind map: Cloud CDN at a glance
Free to share. The downloaded image includes the CloudBrum link.
Key features (summary)
- A setting on the load balancerCloud CDN is enabled per backend on an external Application Load Balancer. Requests that hit the cache are served at the edge and never reach the load balancer’s backends, and misses go on to the origin as usual.
- Many kinds of originA Cloud Storage bucket through a backend bucket, instance groups, zonal and serverless network endpoint groups such as Cloud Run, and external servers reached through an internet NEG.
- Three cache modesUSE_ORIGIN_HEADERS caches only what the origin marks as cacheable. CACHE_ALL_STATIC also caches ordinary static content that has no headers. FORCE_CACHE_ALL caches everything successful, including responses that say private.
- A cache key you controlBy default the key includes the protocol, host and full URL. You can drop the protocol or the query string, keep only named parameters, and add headers or cookies on backend services.
- TTLs and stale answersSet a default, a client and a maximum TTL, cache errors briefly with negative caching, and let the edge serve a stale object for a while when the origin is slow or down.
- Signed URLs and cookiesPrivate content can be served from the cache when the request carries a signature made with a key that you hold, with an expiry time. Keys can be rotated without downtime.
- Protection at the edgeCloud Armor security policies sit in front of cached and uncached traffic alike. The load balancer terminates TLS with Google-managed or your own certificates.
- Media CDN for the heavy casesCloud CDN suits websites and APIs. Media CDN is the separate product, on YouTube’s delivery infrastructure, for very large streaming and download workloads.
Basic concepts
- External Application Load Balancer
- Google’s layer 7 load balancer with a single global address. Cloud CDN is an option on its backends.
- Backend service and backend bucket
- A backend service points at servers (instance groups or endpoint groups). A backend bucket points at a Cloud Storage bucket. Either can have Cloud CDN switched on.
- Cache mode
- Decides what Cloud CDN caches: only what the origin marks cacheable, also plain static content, or everything successful.
- Cache key
- What makes two requests the same cached object: protocol, host, path and, optionally, query string parameters, headers and cookies.
- TTL (default, client, max)
- The default TTL applies when the origin sends none. The client TTL caps what browsers are told. The maximum TTL caps how long the edge keeps an object, whatever the origin says.
- Negative caching
- Caches error responses such as 404 for a short time, so a missing file doesn’t hit the origin on every request.
- Serve while stale
- Lets the edge return an expired object for a set time while it refreshes it from the origin.
- Invalidation
- A request that removes a path or a path prefix from all caches. It takes a few minutes and is meant for exceptions.
- Signed URL and signed cookie
- A request carrying an expiry, a key name and a signature that Cloud CDN checks against the keys on the backend.
- Internet NEG
- A group that points to an external host name, so Cloud CDN and the load balancer can front a server outside Google Cloud.
- Cache fill
- The traffic from the origin into the cache when an object isn’t there yet. It is billed separately from cache egress.
- Custom response headers
- Headers the load balancer adds to responses, including variables such as the cache status, which makes caching visible to testers.
- Media CDN
- A separate Google Cloud product for large-scale video and downloads, with its own configuration and pricing.
How to create & configure it
Serve a static site from a bucket through Cloud CDN with gcloud
- Check that Cloud CDN fitsIt needs an external Application Load Balancer in front of the backend, so the site pays for the load balancer too. Plain TCP traffic or very large video are better served elsewhere.
- Put the files in a bucketCreate a bucket near your users, upload the site, and set a sensible Cache-Control header on the objects. Public content must be readable by the load balancer’s path.
- Create a backend bucket with CDN onPick a cache mode, set the default, client and maximum TTL, and turn on negative caching.
- Build the load balancerReserve a global address, create a URL map, a Google-managed certificate for your domain, an HTTPS proxy and a forwarding rule.
- Point DNS at the addressAdd an A record for your domain. The managed certificate becomes active once DNS points at the address, which can take a while.
- Make caching visibleAdd a custom response header with the cache status variable, so you can see hit and miss in a browser or with curl.
- Version your filesPut a hash in file names, so a release needs no invalidation. Invalidate only entry pages.
- Protect and tuneAttach a Cloud Armor policy, review the cache key, and consider signed URLs for private content.
- Watch the hit ratio and the billUse the load balancer logs and metrics to see cache hits, and review cache egress, cache fill and lookup charges.
Tip: Cloud CDN can add the cache status to responses. With a custom response header that uses the {cdn_cache_status} variable, a quick curl -I tells you whether an answer came from the cache. See the code references for the same setup as Terraform.
Common issues after configuration
| Symptom | Likely cause | What to check / fix |
|---|---|---|
| Nothing is cached, and the hit ratio stays at zero | The mode is USE_ORIGIN_HEADERS and the origin sends no cache headers, the response varies with a header that makes every request unique, or the request is not cacheable (for example a POST) | Set Cache-Control at the origin, or use CACHE_ALL_STATIC for static content, and check the Vary header. |
| Users still see the old version after a release | The edge keeps the object until its TTL ends | Invalidate the changed paths, or use hashed file names and short TTLs for HTML. |
| Private pages were served to the wrong person | FORCE_CACHE_ALL ignores private and no-store, so a personalised response was cached | Use FORCE_CACHE_ALL only for content that is the same for everyone, and keep personalised paths on another backend. |
| Hit ratio is low because the same file is cached many times | Query strings or the protocol are in the cache key, so tracking parameters create separate objects | Exclude the protocol and the query string, or keep only the parameters that change the response. |
| A backend bucket answers 403 | The objects aren’t readable by the path Cloud CDN uses, or the bucket is private and no signing key or service account access is set up | Make the content publicly readable, or keep it private and grant the Cloud CDN service account read access and use signed URLs. |
| A signed URL returns 403 | The key name or the secret is wrong, the expiry has passed, or the URL was changed after signing | Check the key on the backend, sign the exact URL, use a UTC timestamp and a URL-safe base64 key. |
| The managed certificate stays in provisioning | DNS doesn’t point at the load balancer’s address, or the domain is also served by something else | Create the A record for the forwarding rule’s address and wait. Check for conflicting records. |
| HTTP requests aren’t redirected to HTTPS | The HTTPS proxy only listens on 443, and no HTTP front end exists | A second forwarding rule on port 80 points at a URL map that only redirects to HTTPS. |
| A cache miss is very slow | The origin is far from the edge location that fetched it, or is slow to respond | Move the origin closer to the main audience, raise TTLs so misses are rarer, and use serve-while-stale. |
| Invalidation takes a long time or seems ignored | Invalidations take minutes to spread, and a path with the wrong form, host or trailing wildcard misses the objects | Use the exact path or a single trailing *, give the host if you serve several, and wait for the operation to finish. |
| The bill is higher than expected | Cache egress, cache fill and lookup requests are billed, along with the load balancer’s forwarding rules and data processing | Raise the hit ratio, compress responses, merge forwarding rules and compare the charges by SKU. |
Use cases: when and where to use it
Good fit
- Websites and single-page apps hosted in Cloud Storage, Cloud Run or on virtual machines
- Applications that already use, or need, an external Application Load Balancer
- Static assets, downloads and API answers that can be cached for a short time
- Sites that want caching, TLS, URL routing and Cloud Armor in one front end
- Content served from servers outside Google Cloud, through an internet NEG
- Private downloads that use signed URLs with expiry times
Consider something else
- Very large video and download delivery → Media CDN
- Distributing traffic across backends, with or without caching → Cloud Load Balancing
- Hosting the files themselves → Cloud Storage
- A fully managed web app with its own front end → Cloud Run
- DNS records and routing policies → Cloud DNS
- The same job on other clouds → compare Amazon CloudFront and Azure Front Door
Pros: why consider it?
Why teams choose it
- Caching sits in the same front end as routing, TLS and protection
- No separate CDN account, network or certificate setup
- Cache hits skip the load balancer’s backends, so origin load falls
- Three cache modes and a flexible cache key
- Signed URLs and cookies for private content
- Works with origins outside Google Cloud through an internet NEG
Trade-offs to weigh
- It needs an external Application Load Balancer, whose charges apply on top
- There is no standalone CDN: the load balancer is the entry point
- Invalidation is slow and meant for exceptions
- FORCE_CACHE_ALL can cache private data if used carelessly
- Fewer edge-compute options than some CDNs, with logic mostly in the load balancer’s URL map and extensions
- Billing has several parts: egress, cache fill, lookups and the load balancer
Common threats, vulnerabilities & risks
| Risk | Severity | Why it matters | Mitigation |
|---|---|---|---|
| FORCE_CACHE_ALL on personalised content | High | Responses marked private or no-store are cached anyway, and may be served to another visitor. | Use it only for identical-for-everyone content, and route personalised paths to a backend without CDN. |
| A public bucket holding private files | High | Anyone who finds the URL can fetch the object directly, even without the CDN. | Use signed URLs with a private bucket, and grant read access only to the Cloud CDN service account. |
| Signing keys left in code or logs | High | A leaked key lets anyone create valid signed URLs until it is removed. | Keep keys in Secret Manager, rotate them on a schedule and remove the old key after clients move. |
| Origins open to the internet | Medium | Attackers can hit the origin directly, past Cloud Armor and the cache. | Allow only the load balancer and health check ranges on the backend, and keep origin addresses private. |
| Long TTLs on pages that change | Medium | A mistake stays in the cache for the whole TTL. | Keep HTML TTLs short, use hashed assets, and have a documented invalidation step. |
| Wide cache keys | Medium | Cookies or headers in the key fragment the cache and slow every visitor. | Include only what changes the response. |
| No Cloud Armor policy | Medium | Bots and floods can push up egress charges and load. | Attach a policy with rate limits and managed rules, and set a budget alert. |
| Unreviewed load balancer changes | Low–Med | A change to the URL map or a backend can disable caching for a whole site. | Keep the load balancer in code, review changes and watch the hit ratio after each. |
| Origin outside Google Cloud with no limits | Low–Med | Cache misses can flood an external origin. | Raise TTLs, use serve-while-stale and rate-limit the origin. |
Performance optimisation
- Set long TTLs on hashed assets and short ones on HTML, so most requests are answered at the edge.
- Keep the cache key small: drop the protocol and the query string unless they change the response.
- Use CACHE_ALL_STATIC for sites whose origin doesn’t send good headers, and fix the headers when you can.
- Turn on compression at the origin or load balancer for text, so responses are smaller.
- Use serve while stale and negative caching to absorb origin slowness and repeated misses.
- Place the origin near most users, since the first fetch for each edge location travels to it.
- Use HTTP/3 and TLS 1.3 on the load balancer, which clients negotiate automatically.
- Warm up important pages after a release by requesting them once, rather than letting the first visitors take the miss.
Reduce monthly cost
FinOps is the habit of managing cloud spend together with engineering. These are the FinOps checks that matter most for Cloud CDN.
- Raise the cache hit ratio: cache egress is cheaper than the load balancer’s data processing, and fills are paid once per object.
- Compress responses and size images, since cache egress is billed per GiB.
- Use versioned file names instead of invalidations.
- Reduce cache lookups by combining small files and removing needless requests, such as repeated polls.
- Keep forwarding rules to what you need, since each one has an hourly charge.
- Choose the region of the bucket and origin with care, because cache fill follows origin location.
- Use Cloud Armor rate limits to stop abusive traffic that would raise egress.
- Check whether Media CDN is cheaper for very large download or streaming workloads.
- Review logs for requests that can never be cached, and fix or move them.
- Add a budget alert and review the SKUs on the invoice every month.
Figures here come from Google's pricing page and published guides, read in October 2026. Regional rates vary and a few sources disagree, so check the live page (see Pricing).
Security optimisation
- Use signed URLs or cookies for private content, short expiry times and rotated keys kept in Secret Manager.
- Keep buckets private where you can, and give the Cloud CDN service account read access instead of making objects public.
- Attach Cloud Armor policies for rate limits, geographic rules and managed protection.
- Terminate TLS on the load balancer with a modern SSL policy and a minimum TLS version.
- Allow only the load balancer and health check ranges to reach backends.
- Use FORCE_CACHE_ALL only for content that is the same for every visitor.
- Turn on request logging for the load balancer and send logs to a restricted bucket or Log Analytics.
- Restrict who can change load balancers, backends and cache settings with IAM, and alert on changes.
- Redirect HTTP to HTTPS with a separate front end on port 80.
- Review Security Command Center findings for the project and its load balancers.
Governance & compliance
Guardrails
- A shared Terraform module for load balancers that sets CDN, cache mode, TTLs, a Cloud Armor policy, logging and labels
- An organisation policy and IAM review that limits who may change load balancers and make buckets public
- A naming standard for backends and URL maps, with the cache mode and the reason for it noted on each backend
- A release checklist covering hashed assets, HTML TTLs and the invalidation of entry pages
Continuous checks (Cloud Asset Inventory, Security Command Center and your own scripts)
- A scheduled script that lists backends with FORCE_CACHE_ALL, CDN switched off or a wide cache key (the C# tab does this)
- Security Command Center and organisation policy findings for public buckets and load balancers
- Alerts on the cache hit ratio, 5xx rate and backend latency
- An audit-log alert for changes to backends, URL maps and signed URL keys
- A monthly report of cost by SKU for the load balancer and Cloud CDN
Cloud Audit Logs record who changed load balancers and backends, Cloud Asset Inventory keeps the configuration history, Security Command Center reports posture, and Google’s compliance reports manager holds certifications. Google runs the edge and the load balancer. Cache settings, signing keys, origin protection and what is cached are yours.
Reduce carbon footprint
- A higher cache hit ratio keeps cache fill and origin load down.
- Compress text responses and export images at the size they are shown.
- Use modern formats and HTTP/3 to cut transfer.
- Remove unused load balancers, backends and forwarding rules.
- Choose a Google Cloud region marked as low carbon for the origins, if data rules and latency allow it.
- Google’s Carbon Footprint report is per project and service group, so quote no Cloud CDN-only figure.
Pricing
Purchase options
Cache egress Per GiB, by region of the visitor
Data served from the cache to visitors. Rates fall with volume and differ by destination region.
Cache fill Per GiB, by origin and cache region
Data moved from the origin into the cache when an object isn’t there yet. A better hit ratio means fewer fills.
Cache lookups Per 10,000 requests
Every request that reaches Cloud CDN counts, hit or miss.
Load balancer Forwarding rules and data
The external Application Load Balancer bills per forwarding rule hour and per GiB processed. Cache hits don’t pass through it.
What you actually pay for
- Cache egress to visitors, by destination region
- Cache fill from the origin
- Cache lookup requests, and invalidations beyond any free allowance
- Forwarding rules and data processing on the load balancer
- Cloud Armor policies, rules and requests, if you attach one
Google lists cache egress, fill and lookup rates on its pricing page, and rates differ by region. See the official Cloud CDN pricing page and the Google Cloud Pricing Calculator.
Important code references
A static site: a Cloud Storage bucket, a backend bucket with Cloud CDN, cache mode, TTLs and a cache status header, and the load balancer in front of it, with a Google-managed certificate. The CLI tab builds it, adds a signing key and invalidates a path; Terraform describes the same resources. The Python tab signs a URL with a key and invalidates a path through the Compute API, and the C# tab audits backends for FORCE_CACHE_ALL, wide cache keys and CDN switched off. Replace the project, domain and names with your own.
# Placeholders: replace the project and the domain with your own. The domain's DNS must point at the address created below.
PROJECT=my-project-id
BUCKET=$PROJECT-static-site
DOMAIN=static.example.com
# 1. A bucket for the site, readable by everyone, with one page. Cache-Control tells the edge and browsers how long to keep it.
gcloud storage buckets create gs://$BUCKET --project $PROJECT --location asia-south1 --uniform-bucket-level-access
gcloud storage buckets add-iam-policy-binding gs://$BUCKET --member allUsers --role roles/storage.objectViewer
echo '<h1>Hello from the edge</h1>' > index.html
gcloud storage cp index.html gs://$BUCKET/index.html --cache-control "public, max-age=300"
# 2. A backend bucket with Cloud CDN switched on. CACHE_ALL_STATIC also caches plain static files that carry no cache headers.
# The custom header shows the cache status (hit or miss) on every response, which makes testing easy.
gcloud compute backend-buckets create site-bucket --project $PROJECT --gcs-bucket-name $BUCKET --enable-cdn \
--cache-mode CACHE_ALL_STATIC --default-ttl 3600 --client-ttl 600 --max-ttl 86400 --negative-caching \
--custom-response-header "X-Cache-Status: {cdn_cache_status}"
# 3. Put an external Application Load Balancer in front, with a global address, URL map, managed certificate, HTTPS proxy and forwarding rule.
gcloud compute addresses create site-ip --project $PROJECT --global
gcloud compute url-maps create site-map --project $PROJECT --default-backend-bucket site-bucket
gcloud compute ssl-certificates create site-cert --project $PROJECT --domains $DOMAIN --global
gcloud compute target-https-proxies create site-proxy --project $PROJECT --url-map site-map --ssl-certificates site-cert
gcloud compute forwarding-rules create site-rule --project $PROJECT --global --address site-ip --target-https-proxy site-proxy \
--ports 443 --load-balancing-scheme EXTERNAL_MANAGED
# 4. Point DNS at this address, wait for the certificate to become ACTIVE, then ask for a page twice and read X-Cache-Status.
IP=$(gcloud compute addresses describe site-ip --project $PROJECT --global --format="value(address)")
echo "Create an A record: $DOMAIN -> $IP"
gcloud compute ssl-certificates describe site-cert --project $PROJECT --global --format="value(managed.status)"
curl -sI https://$DOMAIN/ | grep -i -E "^(HTTP|x-cache-status|age)"
curl -sI https://$DOMAIN/ | grep -i -E "^(HTTP|x-cache-status|age)"
# 5. After a release, invalidate the changed paths. Invalidation takes a few minutes to spread.
gcloud compute url-maps invalidate-cdn-cache site-map --project $PROJECT --path "/index.html" --async
# 6. For private files: add a signing key (keep the key file safe), then sign URLs with it.
head -c 16 /dev/urandom | base64 | tr +/ -_ > key-1.txt
gcloud compute backend-buckets add-signed-url-key site-bucket --project $PROJECT --key-name key-1 --key-file key-1.txt
# Placeholders: pass in your own values. The ones below are examples.
variable "project" {
type = string
}
variable "domain" {
type = string
default = "static.example.com"
}
provider "google" {
project = var.project
}
resource "google_storage_bucket" "site" {
name = "${var.project}-static-site"
location = "ASIA-SOUTH1"
uniform_bucket_level_access = true
}
# Public read. For private files use signed URLs instead and give the Cloud CDN service account read access.
resource "google_storage_bucket_iam_member" "public" {
bucket = google_storage_bucket.site.name
role = "roles/storage.objectViewer"
member = "allUsers"
}
resource "google_compute_backend_bucket" "site" {
name = "site-bucket"
bucket_name = google_storage_bucket.site.name
enable_cdn = true
cdn_policy {
cache_mode = "CACHE_ALL_STATIC"
default_ttl = 3600
client_ttl = 600
max_ttl = 86400
negative_caching = true
serve_while_stale = 86400
}
custom_response_headers = ["X-Cache-Status: {cdn_cache_status}"]
}
resource "google_compute_global_address" "site" {
name = "site-ip"
}
resource "google_compute_url_map" "site" {
name = "site-map"
default_service = google_compute_backend_bucket.site.id
}
resource "google_compute_managed_ssl_certificate" "site" {
name = "site-cert"
managed {
domains = [var.domain]
}
}
resource "google_compute_target_https_proxy" "site" {
name = "site-proxy"
url_map = google_compute_url_map.site.id
ssl_certificates = [google_compute_managed_ssl_certificate.site.id]
}
resource "google_compute_global_forwarding_rule" "site" {
name = "site-rule"
target = google_compute_target_https_proxy.site.id
ip_address = google_compute_global_address.site.address
port_range = "443"
load_balancing_scheme = "EXTERNAL_MANAGED"
}
output "address" {
value = google_compute_global_address.site.address
}
# pip install google-cloud-compute
# Signs a URL for private content, and invalidates a path in the cache through the Compute API.
import base64
import datetime as dt
import hashlib
import hmac
from google.cloud import compute_v1
def sign_url(url, key_name, key_b64, expires):
"""Returns the URL with Expires, KeyName and Signature added. key_b64 is the URL-safe base64 key that was given to
`gcloud compute backend-buckets add-signed-url-key`. The signature covers the whole URL, so don't change it afterwards."""
expiry = int(expires.replace(tzinfo=dt.timezone.utc).timestamp()) if expires.tzinfo is None else int(expires.timestamp())
separator = "&" if "?" in url else "?"
to_sign = "%s%sExpires=%d&KeyName=%s" % (url, separator, expiry, key_name)
digest = hmac.new(base64.urlsafe_b64decode(key_b64), to_sign.encode(), hashlib.sha1).digest()
return "%s&Signature=%s" % (to_sign, base64.urlsafe_b64encode(digest).decode())
def invalidate(project, url_map, path, host=None):
"""Asks every cache to drop the path. A single trailing * removes a whole prefix. It takes a few minutes to spread."""
rule = compute_v1.CacheInvalidationRule(path=path, host=host) if host else compute_v1.CacheInvalidationRule(path=path)
operation = compute_v1.UrlMapsClient().invalidate_cache(project=project, url_map=url_map, cache_invalidation_rule_resource=rule)
return operation.name
if __name__ == "__main__":
key = open("key-1.txt").read().strip()
expires = dt.datetime.now(dt.timezone.utc) + dt.timedelta(minutes=15)
print(sign_url("https://static.example.com/private/report.pdf", "key-1", key, expires))
print("invalidation operation:", invalidate("my-project-id", "site-map", "/index.html"))
// dotnet add package Google.Cloud.Compute.V1
// Audits the project's backends: FORCE_CACHE_ALL (private data can be cached), CDN switched off on a backend bucket,
// and cache keys that include the whole query string, which splits the cache.
using Google.Cloud.Compute.V1;
string project = Environment.GetEnvironmentVariable("GOOGLE_CLOUD_PROJECT") ?? throw new InvalidOperationException("Set GOOGLE_CLOUD_PROJECT first.");
int problems = 0;
BackendBucketsClient buckets = BackendBucketsClient.Create();
foreach (BackendBucket bucket in buckets.List(project))
{
if (!bucket.EnableCdn)
{
Console.WriteLine($"backend bucket {bucket.Name}: Cloud CDN is switched off");
problems++;
}
else if (bucket.CdnPolicy?.CacheMode == "FORCE_CACHE_ALL" && bucket.CdnPolicy.SignedUrlKeyNames.Count > 0)
{
Console.WriteLine($"backend bucket {bucket.Name}: FORCE_CACHE_ALL together with signed URLs, so check what is cached for whom");
problems++;
}
}
BackendServicesClient services = BackendServicesClient.Create();
foreach (BackendService service in services.List(project))
{
if (!service.EnableCDN) continue;
if (service.CdnPolicy?.CacheMode == "FORCE_CACHE_ALL")
{
Console.WriteLine($"backend service {service.Name}: FORCE_CACHE_ALL ignores private and no-store, so personal responses can be cached");
problems++;
}
var key = service.CdnPolicy?.CacheKeyPolicy;
if (key != null && key.IncludeQueryString && key.QueryStringWhitelist.Count == 0 && key.QueryStringBlacklist.Count == 0)
{
Console.WriteLine($"backend service {service.Name}: the whole query string is in the cache key, which splits the cache");
problems++;
}
}
Console.WriteLine(problems == 0 ? "No problems found." : $"{problems} problem(s) found.");
return problems == 0 ? 0 : 1;
Best videos to explore
Videos picked for this service. Each one is labelled with its source, opens on YouTube if you prefer, and loads only when you press play.
Interview questions
BasicWhat is Cloud CDN?
It’s Google Cloud’s content delivery network. You turn it on for a backend of an external Application Load Balancer, and Google then caches responses in its edge locations, so visitors get repeat content from somewhere close and your servers see fewer requests.
BasicWhat do you need before you can use Cloud CDN?
An external Application Load Balancer, because Cloud CDN is a setting on its backend services or backend buckets. That means a forwarding rule, a URL map, a proxy and usually a certificate, and the load balancer’s charges come with it.
BasicWhat are the three cache modes?
USE_ORIGIN_HEADERS caches only responses that the origin marks as cacheable. CACHE_ALL_STATIC also caches ordinary static content that has no cache headers. FORCE_CACHE_ALL caches every successful response and ignores private and no-store, so it needs care.
IntermediateHow does the cache key work, and how do you improve a low hit ratio?
The key decides which requests count as the same object, and by default it includes the protocol, host, path and the full query string. If tracking parameters or the HTTP and HTTPS split create copies of the same file, exclude the protocol and the query string, or keep only the parameters that change the response, and the hit ratio rises.
IntermediateHow do you release a new version without waiting for caches to expire?
Use hashed file names so assets get new URLs, keep HTML TTLs short, and invalidate only the entry pages. Invalidation removes a path or a prefix with one trailing * and takes a few minutes, so it is a tool for exceptions and not the usual method.
IntermediateHow would you serve private files through Cloud CDN?
Keep the objects private and grant read access to the Cloud CDN service account, add a signing key to the backend, and have your application issue signed URLs or cookies with an expiry after it checks the user. Cloud CDN checks the signature and serves cached content to valid requests, so the origin sees little traffic.
AdvancedWhen is FORCE_CACHE_ALL dangerous, and what is the alternative?
It is dangerous whenever a response can differ per user, because the object is cached despite private or no-store and may reach someone else. Use it only for content that is identical for everyone, such as hashed static assets. For mixed backends use CACHE_ALL_STATIC or USE_ORIGIN_HEADERS and fix the headers at the origin.
AdvancedHow would you put Cloud CDN in front of an origin outside Google Cloud?
Create an internet network endpoint group that points at the origin’s host name, add it to a backend service with Cloud CDN enabled and a host header that the origin expects, and route to it from the URL map. Raise TTLs and use serve-while-stale so cache misses don’t flood the origin, and protect the origin so it accepts traffic only from Google.
AdvancedWhat affects the cost of Cloud CDN, and how do you reduce it?
Cache egress to visitors, cache fill from the origin and cache lookup requests are billed, together with the load balancer’s forwarding rule hours and data processing on traffic that isn’t served from the cache. A higher hit ratio cuts fills and load balancer data, compression cuts egress, and Cloud Armor rate limits stop abusive traffic. Check the invoice by SKU every month.
AdvancedA deployment broke caching for a whole site. How do you find the cause?
Compare the backend’s CDN settings and URL map with the last known good version in code. Look at the cache status header or the load balancer logs for hit and miss, check for a new Vary header, cookies or query strings in the cache key, and a change in cache mode or TTL. Roll back the setting, then fix the root cause and add an alert for the hit ratio.
Similar or alternative services on other clouds
| Capability | AWS | Azure | Google Cloud |
|---|---|---|---|
| Service | Amazon CloudFront | Azure Front Door | Cloud CDN with an Application Load Balancer |
| What it is | A CDN with edge compute | A CDN plus a global HTTP(S) load balancer and WAF | A cache switched on for a load balancer backend |
| Origins | S3, load balancers, API Gateway, VPC origins, any HTTP server | Storage, App Service, any public origin, Private Link origins (Premium) | Cloud Storage buckets, backend services, external origins through an internet NEG |
| Caching control | Cache policies and behaviors per path | Route caching settings and rule sets | Cache modes, TTLs and cache keys on the backend |
| Code at the edge | CloudFront Functions and Lambda@Edge | Rules engine for rewrites, redirects and headers | Service Extensions on the load balancer |
| Web firewall | AWS WAF | Front Door WAF | Cloud Armor |
| Private origin | Origin access control, VPC origins | Private Link origins (Premium) | Backends inside the VPC behind the load balancer |
| Certificates | Free ACM certificates, in us-east-1 | Managed certificates for custom domains | Google-managed certificates on the load balancer |
| How you are billed | Data out and requests, or a flat-rate plan | Base fee per profile, plus data and requests | Cache egress, cache fill and lookups, plus the load balancer |
Typical origins are Cloud Storage and Cloud Run, in front of a load balancer from Cloud Load Balancing. Signing keys belong in Secret Manager, and metrics and logs go to Cloud Monitoring.
Did you find this article helpful?
Your answer helps us improve this page for the next reader.
Sources and further reading
CloudBrum wrote this page in its own words, using the provider’s public documentation listed below as the reference. Features, limits, names and prices change, so confirm anything that matters on the provider’s own pages before you decide.
- Cloud CDN overviewGoogle Cloud
- Caching overviewGoogle Cloud
- Using cache modesGoogle Cloud
- Cache invalidation overviewGoogle Cloud
- Using signed URLsGoogle Cloud
- External Application Load Balancer overviewGoogle Cloud
- Set up a backend bucketGoogle Cloud
- Cloud CDN best practicesGoogle Cloud
- Cloud CDN pricingGoogle Cloud
- Terraform google: google_compute_backend_bucketHashiCorp
