How much does hosting a blog with AWS Lambda cost?

One of the major challenges of using Ymir to host a WordPress site on AWS Lambda is estimating cost. AWS uses usage-based pricing for a lot of its services. This makes calculating the cost of hosting a WordPress site on AWS challenging.

I’ve been running my personal site on AWS Lambda for a few months now. This has given me a few months of data on the cost of host a WordPress site using Ymir. While this is just one example, it’s still an excellent opportunity to look at the real world cost of using AWS Lambda to host a WordPress site.

Caveats

Before we begin, it’s worth noting a few drawbacks to the analysis that we’ll see in this article.

First, this won’t be very complex cost model. We’re going to look at costs and traffic for a period. We’ll then use that data to see how much it costs per 1,000 visits.

The region that you have your project in can also impact your cost. I’m using US-EAST-1 which is the cheapest region. If you’re in a more expensive region, you might pay a bit more for certain services.

It’s also worth noting that the bills that I have include the AWS free tier for certain services. We want to exclude anything that we got for free. So we’re going to extrapolate the full cost of the service for the month.

In a similar vein, this AWS account is also the one that I use for the development of Ymir. This means that some services have costs that aren’t related to hosting my personal site. We’ll go over those and estimate the actual cost using historical billing.

Next, there’s media usage. Some WordPress use a lot of images and video. Others don’t. This amount of media that your WordPress site uses affects your costs.

In my case, my personal site is a technical site where I write programming articles. It’s mostly text with a few images. This means that I have lower than average media hosting costs.

Last, there’s the Ymir project configuration. The default Ymir project configuration tries to minimize your costs as much as possible. But my personal site doesn’t use the default project configuration, so my costs are higher than they would with a default project configuration.

The data

With this out of the way, let’s bring in the data! Below is the bill for February 2021. It’ll be the main bill that we’ll look at for this analysis.

Next, we need the traffic information for the website. I use Fathom Analytics to track visitors. You can see the traffic details for February below.

So this is our initial data. I paid $28.98 to AWS in February 2021. And during that period, I had 16,700 visits to my personal site.

Breaking down usage costs

Now that we have everything, we’ll start breaking down the costs. We’re going to start with the usage-based services. This will allow us to calculate how much a visit costs.

API Gateway

The first usage-based service in the bill is API Gateway. This service acts as the bridge between AWS Lambda and the internet. I paid $4.55 for over 1.3 million requests.

First, it’s worth nothing that we can ignore the $0.02 cost for ApiGatewayHttpApi which is the API Gateway V2. This cost comes from Ymir’s development and not hosting my personal site.

With that out of the way, API Gateway costs are one area where your project configuration can have a significant impact on cost. My personal site is a WordPress subdomain multisite installation. (There’s a Spanish subsite.) Because of this, the site has to use API Gateway V1. (This is because of a limitation with CloudFront.)

Note: Ymir makes using API Gateway V1 simple for you. All you need to do is set the gateway configuration option to rest.

This has a significant impact on cost. First, you can’t use CloudFront to do page caching. (API Gateway V1 still uses CloudFront to do some caching though.) Second, API Gateway V1 costs significantly more per request. ($3.50/million requests vs $1/million requests.) So not only are fewer requests cached, but each request costs more.

To give you an idea, the $4.53 for 1.3 million requests I paid for API Gateway V1 would be $1.29 so over 1/3 the cost. But also expect a lot fewer requests, since CloudFront will do page caching as well. So, as you can see, the API Gateway you use has some significant impact on your cost.

CloudFront

Next in the bill is CloudFront. This is the AWS content delivery network. I paid $2.39.

Parsing a CloudFront bill is more work because it’s broken down by region. But if we look at the United States region, you can see that most of the costs come from requests and bandwidth. Bandwidth is also going to be the larger unknown on a project since it varies depending on how much media your WordPress site has.

CloudWatch

After CloudFront, the following bill item is CloudWatch. This is where all your AWS logs go, and it’s also what runs WP-Cron. While CloudWatch shows as $0.00 on the bill, that’s only because of the AWS free tier. CloudWatch will always cost a bit each month because of AWS Lambda logs. (Each Lambda requests has two mandatory log entries.)

If we expand the CloudWatch bill item, you’ll see that my personal site generated 0.426 GB of logs. The first 5 GB are always free, but you can hit that easily if you’re not careful. (CloudWatch logs are one of the common AWS bill surprises.) By default, Ymir keeps your log clean so it would take a lot of Lambda requests to hit 5 GB.

But if we weren’t using the free tier, how much would 0.426 GB of logs cost? Well, it’s $0.50 per GB. So our basic log usage would be $0.21.

Data transfer

Next up is “Data transfer”. Data transfer represents the cost of moving data between various parts of AWS. It’s another common bill items that can cause unexpected surprises.

Ymir tries to keep your data transfer costs as low as possible. That said, they will vary depending on your media usage. That’s because the primary source of data transfer is the media used by your site.

You have to pay to transfer your media files between S3 and CloudFront. So if you don’t use a lot of media files, your data transfer costs will be low. If you’re a media heavy site, you can expect a heftier bill for data transfer.

Data transfer also has a monthly free tier of 1 GB. It’s not a lot unless you site gets almost no traffic. But taking this into account, the actual data transfer cost for the month was $0.86.

DynamoDB

DynamoDB will be a potential cost item in the future because it’ll be one way to use a WordPress object cache. But for now, the cost that you see here is due to Ymir development. So we can ignore that $0.01 charge.

Key management service (KMS)

Key management service (KMS) is an important AWS service. It’s the service that handles the encryption and decryption of data on AWS. You might not expect to see KMS on your AWS bill, but it serves a critical purpose.

KMS handles the encryption and decryption of your project secrets. By default, this is all your database credentials. But if you add more secrets, they are all encrypted using KMS.

The Ymir Lambda runtime will minimize requests to KMS by injecting the decrypted keys into the runtime. But you will still see some cost associated to it. This cost will scale based on how many requests your site gets each month.

KMS comes with a free tier for 20,000 requests. After that, it costs $0.03 per 10,000 requests. If we ignore the free tier, the actual KMS cost for the month was $0.22.

Lambda

Now, we’re at the bill item many people worry about: Lambda! Lambda is a complex beast to predict pricing for. That’s because AWS bills you for how many requests Lambda received, but also how long each request takes and how much memory it used.

Ymir tries to reduce these variables as much as possible. Page caching reduces requests and Ymir will give your Lambda runtime as little memory as possible by default. But you can still control the memory used by Lambda in your project configuration.

Lambda also has a very generous free tier. So much so that you might not see a charge for Lambda until your WordPress site reaches 10,000 visits or more. But this will depend on your project configuration.

Now, I paid $0.83 for Lambda with the free tier. But how much would it be without?

Let’s start with requests. Lambda costs a flat $0.20 per million requests. So excluding the free tier, I’d have paid $0.26 for 1.3 million requests to Lambda.

For the execution, Lambda charges $0.0000166667 for every GB-second. It’s a really difficult metric to estimate for. But since we know how many GB-second we used, we can see the actual cost easily. Without the free tier, we’d have $7.49 for the 449,522 GB-second Lambda used.

This is fairly expensive, but it’s important to remember that this is with API Gateway V1 which doesn’t have page caching. A normal Ymir project would use API Gateway V2 and CloudFront page caching, which would reduce this cost by a fair amount.

Route53

After Lambda, we have Route53. Route53 is the AWS DNS service. If Ymir manages your DNS (recommended), you’ll see some costs associated with it.

There are two cost categories to the Route53 bill sections: queries and hosted zones. The hosted zones section is a fixed cost, which we’ll cover later. The queries section is how many queries your DNS server received for DNS records. This scales with traffic.

I paid $0.04 for 111,793 queries.

Simple storage service (S3)

The last usage based service is the simple storage service better known as S3. S3 is without question the better known service by AWS. A lot of WordPress sites already use it to store their media library files. This is also what Ymir uses it for, but it’s also where all your asset files go during deployment.

S3 has different costs associated with it. There’s storage cost which is fixed. (We’ll talk about it later.) But also cost per request, which is broken down into two request types.

Most of the requests costs come from PUT, COPY, POST, or LIST requests. These are requests that only happen when you deploy.

In this case, they’re due to Ymir’s development and not hosting my personal site. I only deploy the site 1-2 per month. Meanwhile, I do hundreds of deployment per month developing Ymir. In practice, you’ll pay $0.01 unless you’re doing dozens of deployments per month.

The other request cost is for GET requests. These happen whenever someone makes a request for something stored on S3. These requests were all for my personal site and weren’t part of Ymir’s development.

Since S3 has no free tier, there’s no need to evaluate anything more. We can just add both storage and GET request costs. This puts our real S3 cost at $0.11.

Calculating the cost per visit

Now that we’ve gone over all our usage based bill items. We can calculate the real cost per visit for carlalexander.ca. All the costs are:

API Gateway$4.53
CloudFront$2.39
CloudWatch$0.21
Data Transfer$0.86
Key Management Service (KMS)$0.22
Lambda$7.49
Route53$0.04
Simple Storage Service (S3)$0.10
Total$15.85

So we get a total of $15.85 for 16,700 visits. If we go further and calculate the cost per visit, the cost becomes $0.95 per 1000 visits. This isn’t a great cost per visit, but it’s also probably near the worst you can expect.

That’s because of the API Gateway V1 usage that’s necessary with a subdomain multisite installation. Just converting API Gateway requests to V2, our cost goes down to $12.61 or $0.75 per 1000 visits.

This doesn’t include the reduced Lambda cost because we could use CloudFront for page caching. It’s hard to predict the cost reduction of that, but my guess is that it would be significant. You could be looking at $0.50 per 1000 visits.

Fixed costs

Unfortunately, your AWS costs don’t end here. There are also services that charge you per month. You need to take these in consideration when calculating your costs.

The good thing with fixed costs is that they’re a lot easier to predict than the usage based costs. If you know how big your media library is, how many domains you want to manage, how many database servers you need, you can know your costs before doing anything.

Another good thing with fixed cost is that most of them can be spread over projects. So the more projects you have using these fixed cost resources, the less they end up costing per project. Because I’m only using Ymir to host my personal site, I can’t leverage that fact, which increases how expensive it is for me to host it on AWS.

Relational database service (RDS)

The big one is the relational database service (RDS). This is the AWS service that hosts your database. RDS is expensive and is often a significant contributor to someone’s AWS bill.

Here, RDS pretty much doubles my AWS bill. This is while using the smallest database server possible with as little storage as possible. It’s safe to assume $14 to be about the lowest amount you can pay for RDS.

So if you’re only using Ymir to host a single site, RDS can increase your hosting cost significantly. This is the case with my personal site. I’m paying a lot for a database server that sees barely any use.

On the other hand, if you have a lot of websites, you can use one RDS database server for all of them. You can then split the cost of it over all those different websites. I built Ymir with this use case in mind.

You can create as many databases and database users as you need. You can then add them to your project configuration. Ymir will use the correct users and databases for your projects.

Route 53

We’re back to evaluating Route53 hosted zones. Hosted zones are domains managed by Route53. It costs $0.50 per domain per month.

I’m paying $5 for this, but those are mostly testing domains. carlalexander.ca is only one domain. So the real hosted zones cost is $0.50.

Simple storage service (S3)

Going back to the S3 section of the bill, we can see that I paid $0.03 for 1.4 GB of storage. The primary thing that will affect your S3 storage costs is your media library. If you have a very large media library, you can expect to pay more for storage.

That said, S3 storage prices are really inexpensive. Even if you had a 100 GB of media, you’d only pay $3. So the size of your media library shouldn’t have a significant impact on what you pay for S3. The request cost that we saw earlier will always have a larger impact.

Ymir

It would be disingenuous to not put Ymir as a fixed cost. It’s totally something you need to consider when evaluating everything! So that’s another $39 on top of everything else so far.

Total cost of hosting

Tabulating everything, we get a fixed cost of $53.36. If we add it to usage-based cost, we get a total of $69.21. Even if you exclude the cost of Ymir, it’s still $30.21. That’s a lot for one site getting 16,700 visits!

This is why I wouldn’t recommend Ymir if you’re looking to host just one low traffic site. I do it because I want to dogfood Ymir. But the reality is that your fixed costs are just too much to make this an attractive option.

Ways to reduce costs

Ymir already does as much as possible to reduce your costs. But there are few things you can do to reduce your costs further.

Using a free content delivery network

You can also reduce some of your usage cost by switching to a free content delivery network like Cloudflare. While I built Ymir to leverage CloudFront, Ymir also doesn’t force you to use it. It’s easy to change your project configuration so that you can use another content delivery network.

If you removed your CloudFront costs, you’d reduce your usage based costs by $0.14 per 1000 visits. That’s even more if you have a lot of media. So it’s a significant cost reduction change.

Spreading your fixed costs

The more projects you use Ymir with, the cheaper your fixed cost will get. That’s because Ymir makes it a breeze to use the same database server for multiple projects. So you can spread that $14/month cost over multiple projects. A small RDS instance can easily host dozens of WordPress sites.

The same goes with your Ymir cost. Ymir’s pricing has no usage based limitation. You pay $39 whether you’re using it for one project or dozens. So the more you use it for your projects, the cheaper it gets.

When does using Ymir for a single site start making sense?

Obviously, spreading your fixed cost doesn’t work if you only host a single site. So how much traffic do you need for Ymir to become competitive?

In general, your fixed costs won’t grow with your site traffic. This is especially true if you use CloudFront to do page caching. In that scenario, you’re probably going to pay closer to $0.50 per 1000 visits.

With that in mind, you’ll probably start seeing comparable pricing to managed hosting around 100,000 visits. Those plans cost around $100/month. Meanwhile, you’d pay about $50 in usage based costs and $53 in fixed cost for a total of $103.

How much do you value peace of mind?

I really like this tweet by Jack Ellis. (The whole thread is worth reading!) There are advantages to using AWS Lambda that you can’t see by just analyzing server costs like we just did.

If you’re a server person, it’s easy to see how you can pay less for hosting your WordPress site. But there’s something fantastic about never having to worry about a server again. And that’s something that’s hard to put a price on.