Moving from AWS Amplify to Cloudflare Pages: Pursuing Lower Costs

Moving from AWS Amplify to Cloudflare Pages: Pursuing Lower Costs

Learn how I moved my website from AWS to Cloudflare, with a focus on AWS Amplify vs Cloudflare Pages differences like lower costs and improved performance.

Introduction

At the time of writing this post, my site logarithmicspirals.com has been live for just a little over one year. For most of the site's life, it has been hosted on AWS Amplify. Before Amplify, the site lived on DigitalOcean's App Platform. After a few months of utilizing App Platform, I migrated over to Amplify and talked about that experience in a post titled Migrating My Blog from DigitalOcean App Platform to AWS Amplify.

Amplify has proven useful so far, offering a relatively straightforward path to deploying my site on AWS and allowing me to build my expand my online presence.

However, I watched a video a couple months ago called I think I was wrong about AWS Amplify uploaded to YouTube on the "Web Dev Cody" channel. While I didn't go to the same depth of analyzing CloudWatch logs for Amplify, I also observed the cache misses (even though I don't use cookies). Additionally, my own personal issue with the service was I felt like I hit a limit on how much AWS knowledge I was gaining through development with Amplify. Through Cody's video, I got introduced to SST.

The things I found appealing about SST were:

  1. More control over the resources being spun up in AWS.
  2. The prospect of centralizing all my code into one repository.
  3. An apparently simpler path to development of future, planned enhancements.

After giving it some thought, I decided to follow Cody's example and explore SST as a hosting solution for my blog on AWS. Unfortunately, SST proved to be too cumbersome and restrictive for my use case. Ultimately, I discovered Cloudflare Pages and decided to move there instead.

However, before publishing this post I made a comment on this post titled Introducing a New Fullstack TypeScript DX for AWS which was published to dev.to by AWS. I added a comment with some of the points I was going to talk about in this post and was pleasantly surprised to get a response back from an AWS employee. Some things I want to highlight from the response I received:

  1. Amplify now supports Node 18 build images.
  2. Amplify is going to roll out updates for CloudFront caching.

So it looks like there's quite a few big changes with Amplify, which is exciting.

Interacting with AWS in the comments of that post got me reflecting on this post. I realized there's some room for improvement in how I go about doing cross comparisons for different services. For example, keeping careful track of benchmarks before and after making significant changes is important for making deep, meaningful comparisons. Looking forward, I'm going to be putting more effort into the data gathering part of the writing process. So shoutout to the wonderful people working at AWS who interact with the community and encourage thoughtful discussions around their technology.

Diving Into SST

Researcher working on serverless technology
Image generated by ChatGPT

After investigating, I found I would need to:

  1. Configure IAM credentials.
    1. Create an IAM user.
    2. Configure the AWS CLI.
  2. Set up SST with my Astro project.
  3. Set up a custom domain.
    1. Create a public cert with AWS Certificates Manager to enable HTTPS.
  4. Set up deployments with GitHub Actions.

Using the above resources, I broke down the process I would need to follow into the following steps:

  1. Follow steps 1 and 2 above.
  2. Once the site is running under a test domain, transfer the domain from Amplify to the SST deployment via step 3.
    1. Set up an environment variable for the certificate ARN.
    2. Set up an external domain.
  3. Verify the site is working correctly.
  4. Tear down Amplify.
  5. Modify my existing GitHub Action (used for doing version bumps) to deploy the site automatically.

Miscellaneous Problems

Before even starting on the migration, I first had to add SST to my project. However, integrating SST posed some challenges:

  • The astro.config.mjs file got overwritten and I had to carefully merge the changes from the SST CLI with my existing configurations.
  • My initial attempt at creating my own custom IAM policy failed, so I went with the AdministratorAccess policy.
  • I had to add export const prerender = true; to my dynamic pages to prevent errors after deployment. The dynamically generated pages wouldn't load without this. However, this was only a problem when output: "server" was set.
  • Warning message The currently selected adapter 'astro-sst' is not compatible with the image service "Sharp". pops up when building the site with output: "static". The output: "server" and output: "hybrid" settings failed completely. The second problem went away after bumping the minor version of Astro from 4.1.1 to 4.4.1.

Frustration: Redirecting WWW to Domain Apex

After overcoming the problems associated with adding SST to my project, I was able to proceed with building and deploying it. I used the SST CLI to do so. However, I ran into a big problem when trying to redirect my domain. Apparently, one cannot redirect the www subdomain to the apex without first migrating the domain to Route 53. When faced with this decision, I decided I would need to find a new platform.

Route 53 charges per query, and this introduces an opportunity for runaway cost potential. With AWS, you pay only for what you use. While this is great in many cases, it does create new challenges around cost control.

Finding a New Platform

Researcher navigating the digital jungle
Image generated by ChatGPT

Understanding My Requirements

  1. No hidden cost overages. A static site shouldn't open me up to massive financial problems.
  2. Simplicity. Development should be easy. I run this site as a side project and don't make any money on it. I want working on it to be dead simple.
  3. S3-compatible object storage.
  4. Redirect www to domain apex.
  5. Maintain control of domain with current DNS provider.
  6. Customizable headers.

Assessing Options

When considering alternatives to AWS, I came up with the following list:

  1. DigitalOcean
  2. Vercel
  3. Netlify
  4. Cloudflare

To help compare these platforms, the following table highlights key technical differences between the platforms.

ProviderS3-Compatible Object StorageCustomize HeadersDNS DelegationAstro Support
DigitalOceanSpaces⚠️
VercelAstro on Vercel
NetlifyAstro on Netlify
CloudflareR2Cloudflare Pages

When it comes to the Astro support provided by DigitalOcean, I used the ⚠️ emoji because while I was able to build/deploy an Astro site with it, there doesn't seem to be any official documentation from DigitalOcean or Astro about it. I am wary of this because I have seen DigitalOcean lag in support/adoption of new technologies.

From this simple breakdown, it's clear Cloudflare Pages is the only one meeting the technical requirements I have. Of course, there are other differences I'm ignoring here. For the sake of simplicity, I've only highlighted three crucial ones. Cloudflare does offer further advantages though.

Cloudflare Offers Incredible Value

Race car tear through space with cosmic swirls and currency
Image generated by ChatGPT

A major factor to consider in cloud computing is cost. With platforms like AWS, one essentially has unlimited cost liability. If something were to go awry, huge bills can get generated. Here's a Reddit thread talking about a $20,000 surprise AWS bill, and another Reddit thread about a $104,000 Netlify bill. While AWS is very clear about this, other platforms like Netlify and DigitalOcean are not.

Another recent example of someone getting hit with unexpected charges is outlined in this article titled How an empty S3 bucket can make your AWS bill explode. The author of that post discovered they were getting charged for invalid requests to their S3 bucket. Users commenting on an associated Reddit thread are pointing how big of a problem this is. One example given is someone getting hit with a huge bill because they posted content on a website that an attacker didn't like. Reading about this problem makes me feel justified in hiding my gallery's S3 URL in previous posts 😮‍💨.

The potential liability when deploying a static site remained a concern. While both of those stories ended with users getting their bills waived, I think there really needs to be more solutions offered with spend caps.

A very comprehensive comparison breakdown for AWS Amplify vs Cloudflare Pages can be found on this page titled Cloudflare Pages vs AWS Amplify. From the side-by-side comparison, we can see Cloudflare Pages is an extremely competitive alternative to Amplify. Not just in terms of performance, but also in terms of available features and cost.

Cost Savings

When using cost to compare AWS Amplify vs Cloudflare Pages, it becomes apparent that Cloudflare Pages is extremely competitive. In fact, to set up a static site you don't even have to provide payment information.

Another huge benefit of moving to Cloudflare is the pricing model for R2. R2 has a very generous free tier which doesn't charge for bandwidth of data egress. Furthermore, R2 makes it really easy to connect the bucket to a custom domain. Doing that with AWS would setting up a CloudFront distribution, creating an SSL cert, and then updating DNS records to point to the distribution.

For this site moving forward, I expect I will be paying $0 per month. The only thing in my current design which could contribute to costs exceeding the free tier limit would be downloads from R2.

Performance

The thing which hit me first was just how insanely fast the website is now that I've moved to Cloudfldare. Using Seobility's free SEO Checker, I was able to get a scan of my previous post Why Every Developer, from Novice to Pro, Should Build Their Own Website. I don't have the exact number, but I remember my site would previously take around 0.7 seconds to load. Now it only takes 0.29 seconds to load. I know I should've recorded those earlier Amplify numbers for benchmarking, but it's too late for that at this point 🙃.

Another cool thing is Cloudflare has HTTP/3 turned on by default, which was something I would've had to configure with SST.

Small Code Changes

When compared to what SST needed, the code changes to get on Cloudflare were minuscule. Really, all I needed to do was add a new endpoint parameter to my S3 client to connect to R2, and also change the region to "auto":

const config: S3ClientConfig = {
  region: "auto",
  endpoint: import.meta.env.GALLERY_BUCKET_ENDPOINT,
  credentials: {
    accessKeyId: import.meta.env.GALLERY_ACCESS_KEY_ID,
    secretAccessKey: import.meta.env.GALLERY_SECRET_ACCESS_KEY
  }
};

However, I also renamed my environment variables to not explicitly mention S3 now that that's out of the equation.

Conclusion

In conclusion, transitioning from AWS Amplify to Cloudflare Pages proved to be a strategic move that aligned with my goals of achieving lower costs, improved performance, and simpler development. Cloudflare Pages offered an appealing alternative with a transparent pricing model, reduced overhead, and robust features like HTTP/3 by default. Its R2 storage solution and generous free tier provided a safer, cost-effective alternative to traditional S3 storage, without the risk of runaway billing. Moreover, the minimal code changes required made the migration seamless. The resulting speed boost and enhanced user experience on my website were immediate, reinforcing that Cloudflare Pages is a strong contender for anyone seeking a flexible, performant, and cost-efficient platform for their web projects.

Hopefully, others will find these comparisons between AWS Amplify vs Cloudflare Pages enlightening for their own work. Happy coding!