How to reduce cloud bill

Serverless architecture is a great option for companies that are looking to optimize costs. We have written down 10 tips on how to reduce your cloud bill.

There are many areas that may offer you cost saving opportunities on cloud bill. For very low-cost systems, averaging around dozens or even hundreds of dollars per month, it might not be worth the time spent in optimizing them. But once the application traffic increases, the opportunities can really stand out.

Just like with all app building and developments, monitoring the performance of your implementation is crucial.

Tip 1: Prioritize Lambda optimizations

Optimizing Lambda functions can be time-consuming. One essential practice is prioritizing the ones that are contributing the most to the overall AWS bill.

It’s understandable that many will overlook this obvious practice since AWS does not provide much granularity into our cloud spending at first glance. Specialized monitoring services can take care of that. Dashbird, for instance, one of the most widely used platforms currently, shows our spending on a per-function basis, aggregated by time period.

Tip 2: Benchmark optimal Lambda memory settings

AWS doesn’t allow us to customize CPU for Lambda functions, but the more memory we allocate, the more computing power we get… and the faster our functions will execute our code! This can actually reduce your cloud bill.

There are a few caveats to this strategy, though. For example: over 2 GB of RAM, Lambda will allocate a second vCPU to the function. In this case, single-threaded programs won’t see any speed gains from increasing memory.

Below is an illustration of the strategy: when we increased memory from about 1.8 GB to 2 GB, it decreased the total billed duration from 600 to 500 milliseconds. Although the memory cost is higher, the lower duration more than offsets the additional memory cost, rendering an effective 5% cost reduction. And we even have the extra benefit of lower latency.

Memory settings help to reduce cloud bill

We published a sample benchmarker on this Github repository, which you can plug to any of your Lambda functions in order to emulate requests and find the memory sweet spot.

Tip 3: Use Lambda internal memory as a local cache

The Lambda internal memory can be used as a cheap and fast caching mechanism. As it’s widely known, anything loaded outside the handler function remains in memory for the next invocations.

We can keep a copy of information retrieved from a database, for example, so that in future requests the data can be pulled from the Lambda internal memory. This article we published recently illustrates this with a couple of basic examples and covers a few points to pay attention to when implementing this strategy.

Tip 4: Constantly monitor

Software projects are changing constantly, which makes cost optimization a moving target. For that reason, it’s important to have proper monitoring and alerting when our financial policies are not met so that we can act upon these incidents and fix them before they become a financial nightmare.

AWS offers spending alerts and expenditure information, but not on the granular level of a Lambda function, for example.

With services like Dashbird, you can set custom policies for one or more functions with very granular details. In the example below, it will send an email and Slack message whenever the selected functions cost more than $10 over the past hour.

Constantly monitor in order to reduce cloud bill

Tip 5: Reduce cold starts impact

We’ve already established the way AWS Lambda works and is priced so it’s going to be of no surprise when we say that cold starts are going to be expensive since you’ll have to pay for the time it takes to spin up those containers.

There are a couple of ways to address these but let’s first look at how you go about seeing which functions have cold start issues and how much of an impact they really have.

Going into Dashbird, you jump into the Lambda view and look on the right side of the screen. From here you can filter to view only the cold starts.

The little anomaly icon you see next to each function is a cold-start.

Now that we have a simple way to identify our cost increasing cold-starts, we need a way to address them.

Tip 6: Use a runtime that boots up fast

One of the most popular ways of dealing with cold-starts is by using a runtime that has faster bootup and right now the fastest way to do that is by using Python. Based on a simple benchmark Nathan Malishev did a while back, it’s clear that Python is the winner.

Tip 7: Use HTTP calls instead of HTTPS

Serkan Özal has looked into this claim and using a simple function that accessed DynamoDB, he concluded that using HTTP instead of HTTPS is a lot faster, especially when using Lambdas with lower memory settings since the transaction is much simpler.

HTTP helps to reduce cloud bill
HTTP helps to reduce cloud bill

Tip 8: Bump up the memory limit

This might seem counterproductive to the already established goal of saving money on your Lambdas, but since you get charged by execution, it might make sense to increase the memory of your function thus having it execute a lot faster. Lambda containers also spin up considerably faster when the function has more memory so while this is probably not a universal solution to the cold-start issue there are some cases where this might make a lot of sense.

Tip 9: Downgrade the memory of your functions

Sometimes we overestimate the memory needs of a function and instead of upgrading by small memory increments we throw caution to the wind and go big. Since AWS Lambda has a linear pricing model, 1024mb is 8 times more expensive than 128mb and 3008mb is 24 times more expensive than 128mb. So you can imagine a scenario where you could cut Lambda cost down 10x or even more just by making small memory adjustments.

Let’s jump back to our Dashbird Lambda panel to look at the execution speeds of our functions. After a few seconds, I see a function that looks suspicious.

Downgrading the memory of your functions helps to reduce cloud bill

As you see in the photo, our function uses only 3% of the 1024mb of RAM allocated. Before jumping into my AWS console to take drastic measures, let’s look at multiple invocations of the same function over several days to make sure that we’re looking at a one-off or some sort of exception to the rule.

I quickly filter out this function and compare the other invocations I see there, and I can easily tell that this function is using up to 6% of the memory allocated – I’m now comfortable reducing the memory of that function to 128MB saving me about $25 a month on this function alone. Now imagine doing this for 10, 25, or 100 functions. It adds up.

Tip 10: Decrease Lambda execution time

We’ve talked about how Python is great at reducing boot-up times for your containers but as it turns out, for overall execution speed for warm containers Python might not be the best choice.

Yun Zhi Lin wrote an excellent benchmark on this very subject where he went through all the runtimes available for AWS Lambda and compared the execution duration of each one. As it turns out, .Net Core 2.0 wins the race by a good margin with Node and Python coming in second and third.

Decreasing Lambda execution time helps to reduce cloud bill

To reap the benefits of a performance monitoring tool tailored for AWS Lambda, sign up today for Dashbird, it’s free and doesn’t require credit card.