AWS docs explain How Spot Fleet Weighting Works under the “Spot Fleet Instance Weighting” section. I’ve read through the doc a few times now, and even so, when I come back to it months later, it still requires some mental wrangling to remember how it works. Been using some “mental” rules to understand how Spot Fleet Weighting works more quickly. Hopefully, you find these notes helpful also.
It’s a bit of work, but it’s worth it for a realizable 80% savings.
AWS Docs Explanation
First, let’s review a table straight out of the AWS Docs explanation:
|Instance type||Instance weight||Price per instance hour||Price per unit hour||Number of instances launched|
|r3.xlarge||2||$0.05||.025 (.05 divided by 2)||5 (10 divided by 2)|
|r3.8xlarge||8||$0.10||.0125 (.10 divided by 8)||2 (10 divided by 8, result rounded up)|
In the docs example, they use a spot fleet request with a target capacity of 10 units. This means you’re asking for at least a total of 10 capacity units. The capacity unit or weighting factor can be any arbitrary value you choose. This allows you to assign values to instance types based on your exact needs. It could be based on RAM, CPU, really anything. Then it is up to the Spot Fleet service to figure out which combination of instances will meet your need. Here are combinations that work for this example:
- Five r3.xlarge for an exact capacity of 10 units.
- One r3.xlarge and a one r3.8xlarge for an exact capacity of 10 units.
- Two r3.8xlarge for a capacity of 16 units. This is over the 10 target capacity but still meets the target capacity minimum of 10.
The Spot Fleet service work conservatively and will round up, slightly over provisioning, if the available instance types happen not to meet the 10 units perfectly. Here’s an example screenshot of a spot fleet request with weighting:
Spot weighting ultimately comes down to basic High School math.
Personal “Mental” Rules and Explanation
It is funny how High School math can still sometimes trip me up and requires mentally stopping, pausing, and taking the time to rationalize 😁 I once heard that a good math student always double-checks his solution after he arrives at his answer. He doesn’t just assume it to be correct. So, here are some logical “mental” rules that help double-check the spot weighting and pricing calculation.
- Spot weights are always 1 or higher.
- The normalized unit price will always be lower than the full instance price.
- We divide the full instance price with the unit weight to get the normalized price.
- That must mean the unit price will always be lower than the full instance price in absolute dollar terms.
Putting it another way, the unit price will always be lower than the full instance price, since a unit is a fraction of a full instance.
And yet another way to put it, the bid price for the capacity unit goes in the opposite direction in portion to the weight that we choose.
Okay, armed with rules let’s go through some Spot Fleet pricing example exercises. Here’s a first simple example.
- On-demand price for a full 10GB instance is $1/hr.
- We weight the instance with 10 units.
- Remember unit price will always be less than the full price.
- So the price per unit is $1 / 10 = $0.1/hr. The absolute dollar amounts confirm with the rules: $0.1/hr is lower than $1/hr.
Another way to think about this is that we’re paying $0.1/hr/GB. In this case, we are normalizing pricing on a per GB basis. With logical rules in place, we can now quickly rationalize that our spot weight pricing calculation makes sense and is correct.
Here’s another example with a slightly different table that includes RAM and CPU:
|Instance Type||RAM||CPU||Monthly Pricing|
The most important factor that we care about is usually RAM and CPU. If the application is running on a server with enough of these resources, then it performs just fine. RAM is often the most critical resource. For example, whenever an application runs out of RAM, it uses swap space if available. The server then gets unbearably slow. Think about what happens after you open 10 copies of Photoshop on your laptop. At that point, you’re pretty hosed. The pressure point can be CPU instead with some applications. It just depends.
For this example, let’s use RAM as the most important resource. A good approach that I’ve found helps make quick spot assessments and decisions is to use the amount of RAM as the weight itself. Here’s the table again with a weight column added:
|Instance Type||RAM||CPU||Monthly Pricing||Weight|
Now we can easily see how to ask for a spot fleet cluster with a total of 32GB of RAM. We ask for a capacity of 32 units. Several combinations can result in this target capacity. For example:
- Four m5.large = 32GB
- Two m5.xlarge = 32GB
- Two m5.large and one m5.xlarge = 32GB
The beauty of Spot Fleet is that AWS figures it all out for us.
Now, for the question that we’ve been working our way up to.
Using a weight of 8 for an m5.large instance that cost $70/mo, if we want pay at most 30% of the on-demand pricing how much should we bid?
Let’s go through this:
- The normal on-demand pricing for a m5.large is $70/mo and 30% of that is $21/mo.
- $21/mo would be the bid if weighting was not involved, but it is.
- We’re assigning the m5.large instance a weight of 8 because it has 8GB of RAM.
So should we divide or multiply by 8?
Remember the rules. The unit price is a fraction of the full instance price so the unit price will always be lower. So the answer is we divide. This gets us a lower absolute dollar number. The bid price always goes in the opposite direction of what we choose as the capacity unit.
Final answer: Our target bid price for a m5.large is $70 * 30% / 8 = $2.65/mo.
The same logic works for the m5.xlarge instance which has been assigned a weight of 16: $140 * 30% / 16 = $2.65/mo. The absolute dollar amount matches for both instance types because weighting normalizes the bid.
When I look at this and see such a small number of $2.65/mo I find myself sometimes questioning it. Then I remind myself that it is logically correct.
Pricing by Percentage Instead
Why can’t we just state the percentage of how much we’re willing to pay and be done with it? We can. It’s just math. Spot Fleet accepts dollar amounts for the bid option. So from the percentage, we can calculate and translate it to the bid dollar amount for Spot Fleet.
- Plug in current on-demand price for each instance type.
- Plug in the percentage you’re willing to pay.
- Plug in RAM (if that’s the weighting factor)
- Run it through the formula.
Hourly pricing x Percentage willing to pay / Weight = Your Bid Price
We covered in detail how Spot Fleet weighting works. Even though it’s basic math ultimately, it can trip you up if you don’t work with it often enough. I hope that these mental rules allow you to double-check things quickly and better understand Spot Fleet weighting and pricing. Ultimately, it’s worth understanding for the ridiculous 50%-90% savings that spot offers. If you’re interested learning more about Spot Compute, check out: BoltOps Learn videos on Spot.
Thanks for reading this far. If you found this article useful, I'd really appreciate it if you share this article so others can find it too! Thanks 😁 Also follow me on Twitter.
Got questions? Check out BoltOps.
You might also like
Kubes: Kubernetes Deployment Tool
Kubes is a Kubernetes Deployment Tool. It builds the docker image, creates the Kubernetes YAML, and runs kubectl apply. It automates the deployment process and saves you precious finger-typing energy.
Jets: The Ruby Serverless Framework
Ruby on Jets allows you to create and deploy serverless services with ease, and to seamlessly glue AWS services together with the most beautiful dynamic language: Ruby. It includes everything you need to build an API and deploy it to AWS Lambda. Jets leverages the power of Ruby to make serverless joyful for everyone.
Lono: The CloudFormation Framework
Building infrastructure-as-code is challenging. Lono makes it much easier and fun. It includes everything you need to manage and deploy infrastructure-as-code.