CubeAPM
CubeAPM CubeAPM

How to Monitor AWS CloudFront Distribution Performance

How to Monitor AWS CloudFront Distribution Performance

Table of Contents

Amazon CloudFront is AWS’s globally distributed CDN. It serves your static files, API responses, and video streams from edge locations close to your users, so requests never have to travel all the way back to your origin server.

But fast delivery only stays fast if you are watching it. Cache hit rates drop, origin servers slow down, and edge locations can start throwing errors without your application showing any obvious sign. By the time users report a problem, the issue has already been happening for minutes.

This guide walks you through setting up monitoring for a CloudFront distribution from scratch, using both the AWS Console and the CLI. Every section includes the exact commands you need to run.

💡 Key takeaways

  • 6 default metrics are free. Cache hit rate and origin latency cost extra but are worth it.
  • All CloudFront CloudWatch metrics live in us-east-1, regardless of where your distribution serves.
  • Standard logs go to S3 (free, delayed). Real-time logs go to Kinesis (paid, live).
  • You must enable additional metrics per distribution. They are not on by default.
  • Set alarms for 5xxErrorRate, CacheHitRate, and OriginLatency before your next launch.

What Does AWS CloudFront Monitoring Cover?

CloudFront sits between your users and your origin. It is a layer your application server never sees directly, which means traditional server monitoring is blind to problems that happen there.

Monitoring a CloudFront distribution means watching four things:

LayerWhat You WatchTool
Edge metricsRequest counts, error rates, cache hit rate, origin latencyAmazon CloudWatch
Request logsPer-request detail: IP, URL, status, edge location, cache resultS3 or Kinesis
AlarmsAlerts when a metric crosses a thresholdCloudWatch Alarms
Internet healthISP and city-level latency/availability to the edgeCloudWatch Internet Monitor

What Can Go Wrong with CloudFront

These are the four failure modes you need visibility into. Each one requires a different signal to detect.

Failure ModeSymptomSignal
High error rate4xx or 5xx responses reaching users4xxErrorRate, 5xxErrorRate
Low cache hit rateToo many requests bypassing the cache and hitting originCacheHitRate
Rising origin latencySlow responses on cache-miss pathsOriginLatency
Geo degradationOne region or ISP slow while everything else looks fineInternet Monitor
⚠️

Note: CloudFront metrics are always in us-east-1

All CloudFront metrics in CloudWatch are published to the us-east-1 (N. Virginia) region only. This applies regardless of where your distribution serves traffic. When querying via the API, SDK, or CLI, always target us-east-1 explicitly.

Step 1: View Default CloudFront Metrics in CloudWatch

CloudFront automatically publishes 6 metrics to CloudWatch at no extra cost. These update every minute and require no setup.

Console: View metrics

  1. Sign in to the AWS Console and go to   console.aws.amazon.com/cloudfront
  2. In the left navigation, choose Monitoring.
  3. Select your distribution, then choose View distribution metrics.
  4. Use the time range selector (1h, 3h, 1d, custom) to adjust the view.
  5. To pin graphs to a CloudWatch dashboard, choose Add to dashboard.  Select the us-east-1 region when prompted.

CLI: Pull a metric value

This example fetches the 5xxErrorRate for the past hour. Replace EDFDVBD6EXAMPLE with your distribution ID.

aws cloudwatch get-metric-statistics  --namespace AWS/CloudFront  --metric-name 5xxErrorRate  --dimensions Name=DistributionId,Value=EDFDVBD6EXAMPLE  --start-time $(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%SZ)  --end-time $(date -u +%Y-%m-%dT%H:%M:%SZ)  --period 300  --statistics Average  --region us-east-1
⚠️

Note: CloudFront metrics are only available in the us-east-1 region. If you query any other region you will get an empty response.

The namespace is case-sensitive: use AWS/CloudFront, not AWS/Cloudfront.

Step 2: Enable Additional Metrics (Cache Hit Rate and Origin Latency)

The default metrics do not include cache hit rate or origin latency. These are the two most useful signals for a CDN and they require a paid opt-in per distribution.

Console: Enable additional metrics

  1. Go to CloudFront console > Monitoring.
  2. Select your distribution and choose View distribution metrics.
  3. Choose Manage additional metrics.
  4. Toggle Enabled to on, then close the dialog.

Graphs for the new metrics appear within a few minutes at 1-minute granularity.

CLI: Enable additional metrics

aws cloudfront create-monitoring-subscription  --distribution-id EDFDVBD6EXAMPLE  --monitoring-subscription    RealtimeMetricsSubscriptionConfig={RealtimeMetricsSubscriptionStatus=Enabled}  --region us-east-1

CLI: Check if additional metrics are already enabled

aws cloudfront get-monitoring-subscription  --distribution-id EDFDVBD6EXAMPLE  --region us-east-1

CLI: Disable additional metrics

aws cloudfront delete-monitoring-subscription  --distribution-id EDFDVBD6EXAMPLE  --region us-east-1

Step 3: Set CloudWatch Alarms

Metrics are only useful if someone acts on them. Set alarms to get notified automatically when something goes wrong.

Console: Create an alarm

  1. Go to CloudFront console > Monitoring.
  2. Select your distribution and choose View distribution metrics.
  3. On any metric graph, choose the bell icon or choose Create alarm.
  4. Set the threshold, evaluation period, and SNS notification topic.
  5. Choose Create alarm.  The alarm is automatically created in us-east-1.

CLI: Create a 5xx error rate alarm

Fires when 5xx errors exceed 1% for two consecutive 5-minute periods.

aws cloudwatch put-metric-alarm  --alarm-name 'CloudFront-5xxErrorRate-High'  --alarm-description 'CloudFront 5xx errors above 1%'  --namespace AWS/CloudFront  --metric-name 5xxErrorRate  --dimensions Name=DistributionId,Value=EDFDVBD6EXAMPLE  --statistic Average  --period 300  --evaluation-periods 2  --threshold 1  --comparison-operator GreaterThanThreshold  --alarm-actions arn:aws:sns:us-east-1:123456789012:YourTopic  --region us-east-1

CLI: Create a cache hit rate alarm

Fires when cache hit rate drops below 50% for two consecutive 5-minute periods.

aws cloudwatch put-metric-alarm  --alarm-name 'CloudFront-CacheHitRate-Low'  --alarm-description 'CloudFront cache hit rate below 50%'  --namespace AWS/CloudFront  --metric-name CacheHitRate  --dimensions Name=DistributionId,Value=EDFDVBD6EXAMPLE  --statistic Average  --period 300  --evaluation-periods 2  --threshold 50  --comparison-operator LessThanThreshold  --alarm-actions arn:aws:sns:us-east-1:123456789012:YourTopic  --region us-east-1

🔔 Recommended alarm thresholds

  • 5xxErrorRate > 1% for 2 periods of 5 min
    → origin or Lambda@Edge failure
  • 4xxErrorRate > 5% for 2 periods of 5 min
    → bad links, expired signed URLs, or bot traffic
  • CacheHitRate < 50% sustained
    → cache key misconfiguration or cache invalidation wave
  • OriginLatency > 2,000 ms
    → slow database query, origin saturation, or keep-alive misconfiguration

Step 4: Enable Standard Access Logs

CloudWatch metrics give you aggregate numbers. Standard access logs give you the full request record: every IP, URL, response code, edge location, cache result, and time-taken. Use them for post-incident analysis, usage reporting, and debugging specific requests.

Console: Enable standard logs

  1. Open CloudFront console > Distributions.
  2. Select your distribution and choose the General tab.
  3. Under Settings, choose Edit.
  4. Find Standard logging and toggle it to On.
  5. Choose an S3 bucket.  Create a dedicated bucket, e.g. my-cf-logs-123456.
  6. Optionally add a log prefix to separate logs from multiple distributions, e.g. prod/dist1/.
  7. Choose Save changes.

CLI: Enable standard logs

First get the current distribution config (you need the ETag for updates):

# 1. Save the current distribution configaws cloudfront get-distribution-config \  --id EDFDVBD6EXAMPLE \  --region us-east-1 > dist-config.json
# 2. Note the ETag value from the output - you will need it for the updatecat dist-config.json | python3 -c "import sys,json; print(json.load(sys.stdin)['ETag'])"

Edit the DistributionConfig block in dist-config.json to add logging:

"Logging": {  "Enabled": true,  "IncludeCookies": false,  "Bucket": "my-cf-logs-123456.s3.amazonaws.com",  "Prefix": "prod/dist1/"}

Apply the update:

# 3. Extract only the DistributionConfig blockcat dist-config.json | python3 -c \  "import sys,json; print(json.dumps(json.load(sys.stdin)['DistributionConfig']))" \  > config-only.json
# 4. Update the distribution (replace ETAG with your actual ETag value)aws cloudfront update-distribution \  --id EDFDVBD6EXAMPLE \  --distribution-config file://config-only.json \  --if-match ETAG \  --region us-east-1

Step 5: Enable Real-Time Logs

Real-time logs stream request records to Amazon Kinesis Data Streams within seconds of each request. Use them when you need live visibility during a traffic spike, a deployment, or an active incident.

Before you start: create a Kinesis Data Stream

aws kinesis create-stream  --stream-name cloudfront-realtime-logs  --shard-count 1  --region us-east-1
# Get the stream ARN (you will need it below)aws kinesis describe-stream-summary \  --stream-name cloudfront-realtime-logs \  --region us-east-1 \  --query 'StreamDescriptionSummary.StreamARN' \  --output text

Console: Create a real-time log configuration

  1. In CloudFront console, choose Logs from the left navigation.
  2. Select the Real-time configurations tab.
  3. Choose Create configuration.
  4. Set Sampling rate.  Start at 5% for high-traffic distributions. 100% for debugging.
  5. Select the fields you want.  At minimum: timestamp, c-ip, cs-method, cs-uri-stem, sc-status, x-edge-result-type, time-taken.
  6. Choose your Kinesis Data Stream.
  7. For IAM role, choose Create new service role or pick an existing role that has kinesis:PutRecord permission.
  8. In the Distribution section, attach this configuration to your distribution and the relevant cache behavior.
  9. Choose Create configuration.

CLI: Create a real-time log configuration

aws cloudfront create-realtime-log-config  --end-points '{    "StreamType": "Kinesis",    "KinesisStreamConfig": {      "RoleARN": "arn:aws:iam::123456789012:role/CloudFrontRealtimeLogRole",      "StreamARN": "arn:aws:kinesis:us-east-1:123456789012:stream/cloudfront-realtime-logs"    }  }'  --fields 'timestamp' 'c-ip' 'cs-method' 'cs-uri-stem'           'sc-status' 'x-edge-result-type' 'time-taken'  --name cloudfront-realtime-config  --sampling-rate 5  --region us-east-1
⚠️

Note: The IAM role you assign must have kinesis:PutRecord and kinesis:DescribeStream permissions on the stream, and CloudFront must be in the trust policy as a principal.

Step 6: Enable CloudWatch Internet Monitor

Internet Monitor watches the path between your users and CloudFront edge locations. It detects ISP-level or city-level availability and latency issues that CloudFront metrics cannot show. When it finds a problem it creates a health event with the affected location, ISP, and a network path visualization.

Console: Add your distribution to a monitor

  1. In CloudFront console, under Telemetry, choose Monitoring.
  2. Select your distribution and choose View distribution metrics.
  3. Scroll to the Enhance your monitoring experience with Amazon CloudWatch Internet Monitor section.
  4. Choose Monitor this distribution.
  5. In the dialog, choose Create new monitor or select an existing one.  The monitor name defaults to CF_<distributionID>_Monitor.
  6. Leave traffic percentage at 100% unless you want to reduce cost.  Pricing is based on the % of traffic monitored.
  7. Choose Monitor this distribution. The monitor starts collecting data immediately and becomes active within a few minutes.

CLI: Create an Internet Monitor

aws internetmonitor create-monitor  --monitor-name cf-distribution-monitor  --resources arn:aws:cloudfront::123456789012:distribution/EDFDVBD6EXAMPLE  --traffic-percentage-to-monitor 100  --region us-east-1

CLI: Check monitor status

aws internetmonitor get-monitor  --monitor-name cf-distribution-monitor  --region us-east-1

CLI: List active health events

aws internetmonitor list-health-events  --monitor-name cf-distribution-monitor  --event-status ACTIVE  --region us-east-1
⚠️

Note: Internet Monitor uses standard CloudWatch pricing for any metrics, logs, alarms, or dashboards you create from it. The traffic percentage you configure directly affects cost.

Step 7: Monitor Lambda@Edge Functions

If you run Lambda@Edge functions, they generate their own CloudWatch metrics and logs. These are separate from your distribution metrics.

CLI: Get Lambda@Edge execution errors

aws cloudwatch get-metric-statistics  --namespace AWS/CloudFront  --metric-name LambdaExecutionError  --dimensions    Name=DistributionId,Value=EDFDVBD6EXAMPLE    Name=FunctionName,Value=your-lambda-edge-function  --start-time $(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%SZ)  --end-time $(date -u +%Y-%m-%dT%H:%M:%SZ)  --period 300  --statistics Sum  --region us-east-1

Sponsored

Monitoring CloudFront? Connect it to your full stack.

CloudWatch shows you the metrics. CubeAPM connects them to your application traces and logs so you can follow a high error rate or a slow origin all the way to the exact service call causing it.

Works with your existing AWS account. No agents to install on your CDN.

FAQs

1. Why do I get an empty response when querying CloudFront metrics via the API?

Two causes cover 99% of cases. First, you are targeting the wrong region. CloudFront metrics only exist in us-east-1. Point your CloudWatch client there explicitly. Second, the namespace string is wrong. It must be AWS/CloudFront with a capital F. AWS/Cloudfront returns nothing.

2. Which CloudFront metrics are free and which cost extra?

The 6 default metrics (Requests, BytesDownloaded, BytesUploaded, 4xxErrorRate, 5xxErrorRate, TotalErrorRate) are free for all distributions. Cache hit rate, origin latency, and per-status-code error breakdowns are additional paid metrics you must enable per distribution.

3. What is a healthy cache hit rate for CloudFront?

Above 80% is a good baseline for workloads serving static assets. If yours is below 50% on a workload that should cache, check for unnecessary query string or cookie forwarding fragmenting cache keys, and verify that your Cache-Control headers are setting a reasonable TTL.

4. What is the difference between standard logs and real-time logs?

Standard logs land in S3 after a delay of up to a few hours and are free to generate. Real-time logs reach Kinesis Data Streams within seconds and carry a charge from both CloudFront and Kinesis. Use standard logs for historical analysis; use real-time logs when you need live request data during an incident.

5. Can I monitor multiple CloudFront distributions in one place?

Yes. In CloudWatch, you can create a dashboard that pulls graphs from multiple distributions. In Internet Monitor, a single monitor can cover multiple distributions. Third-party tools like CubeAPM and Datadog also let you view all distributions in one view alongside your application metrics.

×
×