SoftClouds

Navigating the cloud, one byte at a time

Cost analysis of a simple serverless API on AWS

As with any cloud-based service, cost is a major consideration when using these services. In this blog post, we will take a detailed look at the pricing models of AWS Lambda, API Gateway, and DynamoDB, and how they can be used to build a cost-effective serverless API on AWS.

The architecture that we use in our examples assumes the following setup:

AWS Lambda

The pricing model of AWS Lambda uses the concept of GB-seconds to calculate the cost of running a function. GB-seconds is a measure of the amount of memory that a function uses and for how long it runs. The more memory you allocate to a function, and the longer it runs, the more GB-seconds it consumes.

When you create or update a function, you specify the amount of memory you want to allocate to it. The amount of memory you allocate determines the amount of CPU and network resources that are made available to the function. AWS Lambda charges you for the amount of memory you allocate to a function, and the amount of time it runs, on a per-second basis.

The cost per GB-second is calculated by multiplying the allocated memory in GB by the number of seconds the function executes. For example, if you allocate 512MB of memory to a function and it runs for 200 milliseconds, it would consume 0.5GB-seconds (512MB ÷ 1024MB/GB = 0.5GB) * 0.2 seconds = 0.1GB-seconds.

The cost of running a function will depend on the total number of GB-seconds consumed, the selected architecture (x86 or Arm, respectively) and the region in which the function is running.

Example: Your API gateway invokes your lambda function 2 million times per month. The average function execution duration is 120 ms. You have configured your function with 256 MB of memory, on an ARM based processor. Your charges would be calculated as follows:

  • Amount of memory allocated: 256 MB x 0.0009765625 GB in a MB = 0.25 GB
  • 2,000,000 requests x 120 ms x 0.001 ms to sec conversion factor = 240,000.00 total compute (seconds)
  • Total compute (GB-s) = 0.25 GB x 240,000.00 seconds = 60,000.00
  • Total compute charges = 60000 GB-s x 0.0000133334 USD = $0.80
  • Monthly request charges = 2,000,000 requests x 0.0000002 USD = $0.40
  • Lambda cost (monthly): $1.20

AWS API Gateway for a REST API

The pricing model of AWS API Gateway is based on the number of requests and the data transfer of the API. There are two main charges for AWS API Gateway:

  1. Pay-per-request: This model charges you for each request made to your API. The cost per million requests is tiered and starts at $3.70, depending on the selected region.
  2. Data transfer: This model charges you for the data that is transferred out of the service. The cost per GB of data transfer out is tiered and starts at $0.09 per GB, depending on the selected region.

In addition to the pay-per-request and data transfer pricing, there are also additional charges for certain features such as caching, usage plans, and custom domains.

Example: An edge optimized API receives five million API calls per month, with each API call returning responses of 5 kilobytes (KB) in size with no caching.

  • API call charges = 5,000,000 requests x 0.0000037000 USD = $18.50
  • Total size of data transfers = 5KB * 5 million = 25 million/KB = 25 GB
  • Data transfer charges = 25 GB * $0.09 = $2.25
  • REST API cost (monthly): $20.75

One way to reduce your AWS lambda charges is to enable API gateway caching. This will not only provide significant performance benefits for your API, but it will also reduce the number of lambda invocations. When caching is enabled, API Gateway stores the responses to a request in a cache, and for subsequent requests for the same resource, it returns the cached response instead of kicking off a lambda function.

You can provision a dedicated cache to your API, and you will be charged an hourly rate, depending on the cache memory size. The minimum cache size is 0.5GB and starts at roughly $15 / month (charged per hour).

DynamoDB

The pricing model of DynamoDB is based on the amount of read and write request units (RRU and WRU) that you provision, and the amount of data stored. There are two main types of pricing models for DynamoDB:

  1. Provisioned capacity: This model allows you to provision RRU and WRU for your table. This ensures that your table can handle the specified number of read and write requests per second. The cost per hour for provisioned capacity is determined by the number of RRU and WRU that you provision, and the region in which your table is located.
  2. On-demand capacity: This model allows you to pay for the read and write requests you actually make, rather than provisioning a set number of RRU and WRU. This allows for more flexible and cost-effective scaling of your table, since you only pay for the requests you make. The cost per million requests is determined by the region in which your table is located.

Example: Your lambda functions make 5 million writes and 5 million strong consistent reads to DynamoDB every month and are storing 25GB of data. The average item size of the data that you are storing is 2KB and we’re using on-demand capacity mode. Your charges would be calculated as follows:

For the write capacity:

  • 2 KB average item size / 1 KB = 2.00 unrounded write request units needed per item
  • 5,000,000 number of writes x 1 standard portion x 1 write request units for standard writes x 2 write request units needed per item = 10,000,000.00 write request units for standard writes
  • 10,000,000.00 total write request units x 0.000001525 USD = $15.25 write request cost

For the read capacity:

  • 2 KB average item size / 4 KB = 0.50 unrounded read request units needed per item
  • RoundUp (0.500000000) = 1 read request units needed per item
  • 5,000,000 number of reads x 1 eventually consistent portion x 0.5 read request units for eventually consistent reads x 1 read request units needed per item = 2,500,000.00 read request units for eventually consistent reads
  • 2,500,000.00 total read request units x 0.000000305 USD = $0.76 read request cost

That adds up for a grand total of $23.66 for DynamoDB.

Conclusion

Using the example provided in the blog post, an API that receives 5 million requests per month, 5 million DynamoDB write requests and 5 million DynamoDB read requests, and 2 million Lambda invocations per month, would cost approximately $45.61 per month. This is a relatively low cost for an API with this workload.

In my personal experience, AWS Lambda is usually the smaller fraction of the total AWS bill when compared to for instance API Gateway, but this will depend highly on your use case.

It’s important to note that these costs can vary depending on the specific usage and the amount of data being transferred. In order to minimize the cost, it’s important to optimize the number of requests and the amount of data transferred and to choose the right capacity mode for DynamoDB.

By understanding the pricing models of these services and how to optimize their usage, it’s possible to build a cost-effective serverless API on AWS that can scale and meet the needs of any business or organization.

Please note that the costs provided in this blog post are subject to change, the actual costs may vary depending on the usage and the pricing changes from AWS.

Please also note that there are additional costs associated with running a serverless API on AWS, such as using CloudWatch for logging and monitoring and using Route 53 for DNS management. These costs can add up and should be taken into consideration when estimating the overall cost of a serverless API.