Networking & Content Delivery
Accelerate, protect and make dynamic workloads delivery cost efficient with Amazon CloudFront
Whether you’re serving dynamic content from an Amazon Elastic Load Balancer (Amazon ELB), Amazon Elastic Compute Cloud (Amazon EC2) instances, Amazon API Gateway, or AWS Lambda to the end users on the Internet, you can improve the performance and security, and optimize the cost of your content delivery by using Amazon CloudFront as your content delivery network (CDN). Dynamic content refers to any web objects that are unique to every user or even every request, and as such it doesn’t benefit from caching. Examples include API calls and personalized content, such as on-line shopping carts or targeted advertising.
In this post, you learn about the benefits that CloudFront brings to your dynamic workloads, reviewed from the Cost optimization, Performance, and Security architectural pillars perspective. You also get familiar with the configuration best practices.
Content delivery performance refers to the low latency and high throughput of the IP packets transmitted between clients and the server. For static content to a large extent, this is achieved by caching static objects at CloudFront edge locations, closer to the users. By serving content from the edge, we reduce the network distance that IP packets must travel between clients and the server. This results in lower latency, higher throughput, and, overall, a better user experience. Although this isn’t applicable for dynamic content which is uncacheable, caching at the edge isn’t the only contributor to better performance when using CloudFront. You should consider other factors that are helpful for performance and work for both static and dynamic content.
One of the performance benefits of CloudFront for static content is Origin offload: when content is cached in CloudFront, most of the requests will be served from edge locations, never reaching out to Origin. Although we can’t cache dynamic content, we still achieve Origin offload by leveraging the persistent connections feature of CloudFront. This feature allows requests coming from users to reuse an existing TCP upstream connection toward Origin that was created by a preceding request. This eliminates the need for Origin TCP and TLS handshakes for each and every user. The effectiveness of upstream connection reuse, as well as its impact on overall performance, can be tested and demonstrated with the help of the CloudFront Server-Timing header feature. This enables you to receive some diagnostic information in response from CloudFront, including the cdn-upstream-connect metric. This metric contains a value with the number of milliseconds between when the origin DNS request completed and a TCP (and TLS, if applicable) connection to the origin completed. A value of zero (0) indicates that CloudFront reused an existing connection. Therefore, by sending several requests and analyzing the Server-Timing header, we can see how many of them reused the connection. With further help from Curl and its write-out capabilities, we can measure other timings from the client side, such as download time, and understand connection reuse impact.
We need a test environment to conduct the test, and for this we imitate a dynamic workload consisting of CloudFront distribution and Amazon EC2 with an Nginx server running behind CloudFront distribution uses a managed cache policy CachingDisabled which is useful for dynamic content. Furthermore, we then run the test and show the results. Note that the actual latency figures are specific to the test client. You can conduct your own test by deploying the test system available in Github, or by using only a Curl script from there to test your CloudFront distribution with Server-Timing header enabled. The test system uses some security best practices that we discuss further in this post in the Security section. In particular, the ALB and EC2 security group allows only requests coming from the CloudFront distribution, disabling any requests coming directly from the Internet.
First, let’s send 10 requests by running the test script:
python3 timings.py -url https://d1234.cloudfront.net -n 10
As we can see in the results, the upstream connect time for 6 requests out of 10 is zero. This means that the connection was reused, or in other words, the connection is pre-warmed. In this example, we can see that the download time for pre-warmed connections is an average of 39% less compared to initial connections. In addition to reducing the overhead of TLS and TCP handshakes, pre-warmed connections have a greater Congestion Window (CWND) resulting in higher throughput. If we send more requests, such as 100, then we can see that the connection reuse rate increases:
python3 timings.py -url https://d1234.cloudfront.net -n 100
Now it’s 93% of connection reuse rate and it can increase even further with more requests. Connection reuse not only lowers latency (especially for small files like the one used in the test), but also offloads the Origin and lets us use less compute resources on it. Without CloudFront, all end users’ requests land directly on ALB, which results in a new connection for every user and, consequently, in more LCUs and higher cost.
Note on performance benchmarking
As we can see in the tests, connection reuse has no effect on a few requests, and it starts to manifest itself after approximately 10 requests. This makes any kind of synthetic testing where only one or two probe requests are generated irrelevant for production traffic that consists of many requests triggering the effect of connection reuse. Therefore, we recommend conducting performance benchmarking using production traffic. You can either split your traffic 50/50 between tested systems, or make a day-to-day or week-to-week traffic switch between them. Follow this link to learn how Snap came to the conclusion of equal traffic share for performance benchmarking of QUIC.
Origin Shield to increase connection reuse rate
Origin Shield is a CloudFront solution for routing all requests to a single regional edge cache which performs origin fetches. Although Origin Shield is designed to maximize the caching ratio, it can also increase the connection reuse rate. This is because the chance that the request lands on an already created connection is higher in Origin Shield, which is the only caching layer interacting with your Origin. If you want to increase your connection reuse rate even further, then we recommend enabling Origin Shield in your CloudFront distribution. If the audience of your content is globally distributed, then you can group their requests at the same regional edge cache by enabling Origin Shield and testing if it results in a further connection reuse increase. Learn more about Origin Shield in our other post.
AWS Global Network
AWS Global Network is an Amazon-owned, highly-available, and low-latency network that connects CloudFront Edge locations to AWS Regions. Since Amazon fully owns the network, we scale it following the demand to make sure that it has sufficient capacity to carry customer traffic. When you serve dynamic content through CloudFront, traffic is moved off the public Internet onto the AWS Global Network through CloudFront edge locations that act as an entry point. CloudFront Edge locations are also well interconnected with all major ISPs in every region, making sure of great connectivity to end user networks. On the Internet, typically there are multiple routes where packets can be sent over for the same source and destination. CDNs that don’t use their own network might develop overlay routing over the Internet based on real-time performance measurement across different network paths, and offer it for an extra cost to customers. In the case of CloudFront, this functionality is native to its packet routing mechanism which takes into account the congestion status of the Amazon network and routes traffic only over congested-free links. Even if there is an unexpected traffic surge or network outage on a particular link between an Edge location and a region, then there would be an alternative path capable of taking over the traffic when the primary one is affected. Although this particular aspect doesn’t always result in a better performance, especially when the user is already close to the Origin and the network connectivity doesn’t suffer from congestion, the ability to use a managed network is always an advantage. This is because it often means less packet loss and consequently less retransmissions, more stable jitter, and overall a better quality of experience.
Other performance improvement techniques
CloudFront allows for the use of high performance protocols, such as HTTP/2 and HTTP/3, advanced TCP congestion control algorithm TCP BBR, and faster TLS version 1.3 (with session resumption). In particular, HTTP/3 unlike HTTP/1.1 and /2 is using UDP based QUIC protocol that overcomes some limitations of TCP and leads to faster connections setup and more efficient bandwidth utilization due to less dependency on packet loss. CloudFront customers that have enabled HTTP/3 on their distributions have seen up to 10% improvement in latency. Learn more about HTTP/3 benefits in CloudFront in another one of our posts.
You must raise the security posture for dynamic content, because applications such as API endpoints, login services, and others often become a subject for malicious traffic. Most requests for static content will be served from edge locations, which helps absorb DDoS. However, all requests for dynamic content, both legitimate and malicious, will reach Origin unless malicious traffic is detected and mitigated beforehand. CloudFront helps you increase the security posture of your application in different ways.
L3/L4 inline DDoS mitigation system
When you serve your web application with CloudFront, all of the packets to the application are inspected by a fully inline DDoS mitigation system, which doesn’t introduce any observable latency. L3/L4 DDoS attacks against CloudFront distributions are mitigated in real time. For regional resources, the detection logic is different: packets aren’t inspected inline and come directly to the application from the Internet. Instead, these resources are monitored for traffic elevations that may indicate the presence of a DDoS attack that requires mitigation. Traffic to each AWS resource is evaluated every minute. This means that detection and mitigation isn’t as quick as when you use CloudFront.
CloudFront requires Origin to use a public IP. However, CloudFront also enables you to allow incoming traffic from CloudFront IPs only and to block any other traffic coming directly to the application. For this, you can include CloudFront managed IP prefix list in the configuration of the Security Group protecting your Origin in VPC. Furthermore, we recommend configuring CloudFront to send a custom HTTP header and configuring Origin, such as ALB, to validate the presence of the header and its value, and block requests if validation fails. This way you will only allow traffic from your CloudFront distribution for which you can also configure user access control: signed URLs or signed cookies and Geo Blocking.
Implement perimeter protection
Perimeter protection services, such as AWS WAF and AWS Shield Advanced, help you reduce unwanted traffic that could overwhelm your application. AWS WAF rate-based rules, Bot Control, ATP, Shield automatic application layer DDoS mitigation, as well as CloudFront Functions to validate and authorize requests, would go a long way in stopping unwanted traffic at the edge. However, some AWS services don’t directly support AWS WAF or Shield Advanced. For example, API Gateway isn’t supported by Shield Advanced and AWS Lambda URL isn’t supported by AWS WAF. You can raise the security posture of your applications that use these services by fronting them with CloudFront and applying Shied Advanced and AWS WAF protection to your CloudFront distribution. By implementing API Key or a secret header between CloudFront and the services, you make it non-public as well as hardly interceptable when HTTPs is used toward the Origin.
CloudFront can lower the cost of your Data Transfer Out (DTO). You don’t incur charges for DTO from any AWS Origin to CloudFront, but you do incur charges for CloudFront DTO. In other words, the cost of DTO from AWS Origin is replaced with the CloudFront DTO cost, which is less and can decrease more if you’re willing to make minimum traffic commitments of typically 10 TB/month or higher, or use CloudFront Savings Bundle. CloudFront also offers a Free Tier, which includes 1 TB of data transfer out to the internet, and 10 million HTTP or HTTPS requests free each month. CloudFront DTO only counts bytes from the response, excluding exchanging TLS certificates, while, for example, Amazon EC2 DTO counts all of the bytes in the wire including TLS. As we demonstrated, Origin offload with persistent connections lets you reduce ALB LCU cost. Note that the Shield Advanced DTO cost is currently twice as low when the protected resource is CloudFront distribution compared to when protection is applied to Amazon EC2 or ALB. Finally, your subscription to Shield Advanced covers the basic AWS WAF fees for web ACLs, rules, and web requests.
Note that optional CloudFront features, such as Lambda@Edge, CloudFront Functions, Real-time logs, Origin Shield, and Invalidation above the limit, aren’t included in the traffic costs and are billed separately.
In this post, you learned about the benefits that CloudFront can bring to your dynamic content. CloudFront can help you in many ways: accelerate content delivery to your users, secure your application from malicious traffic, and reduce your DTO bills. Consider testing performance improvements, security, and cost impact when enabling CloudFront for your particular dynamic workload.