Chapters
Try It For Free
December 31, 2024

Adaptive Adjustment of AWS RI Purchase Targets: A Sigmoid-Based Approach

Table of Contents
Adaptive Adjustment of AWS RI Purchase Targets: A Sigmoid-Based Approach

Adaptive Adjustment of AWS RI Purchase Targets: A Sigmoid-Based Approach

Introduction

At Harness, we help our customers maximize cloud savings by automating the purchase of AWS Reserved Instances (RIs).
 An important part of this process is ensuring we buy the right amount of commitment — enough to capture significant savings, but not so much that it leads to wastage.

While our forecasting models accurately predict future usage, we noticed an issue: our actual purchasing behavior was too abrupt.
 As we approached our target reservation coverage, the system would either buy too aggressively or stop too suddenly, leading to suboptimal results.

We needed a better way to smoothly adjust the target purchase cost as we got closer to our goals.
 This blog explains how we solved this using a sigmoid function, why we chose it over other approaches, and how it fits into our overall forecasting and purchasing system.

Our Forecasting and Purchasing Pipeline

Here’s a quick overview of how we make purchase recommendations:

  1. Collect Historical Data:
     We pull detailed compute usage history directly from customers’ AWS accounts — focused primarily on EC2.
  2. Forecast Future Usage:
     We send this data to our Forecasting Engine, which uses time series modeling to predict future compute demand.
  3. Target Coverage Setup:
     As part of initial onboarding, customers configure their desired target reservation coverage — for example, 70% or 80% — based on their risk appetite and cost savings goals.
  4. Generate Target Purchases:
     Based on the forecasted usage and the customer’s configured target coverage, the system calculates a target reservation cost — essentially, how much commitment we should purchase.
  5. Adjust Target Cost Dynamically:
     Before placing a reservation order, we pass the forecasted target through the cost adjustment function described in this blog to fine-tune the purchase amount based on real-time progress toward target coverage.
  6. Recommend and/or Auto-Purchase:
     Finally, the system recommends purchases to customers or automatically buys, depending on their configuration.

The Challenge

Our early approach simply compared current coverage to target coverage.
 If coverage was below target, we kept buying; if it was at or above target, we stopped.

Problem:

  • When close to the target, small fluctuations in usage would cause wild swings in purchase behavior.
  • We either over-purchased or under-purchased, leading to unnecessary cost or missed savings.
  • The transition between purchasing and stopping was too sharp and unpredictable.

We needed a way to:

  • Start reducing purchase targets before hitting 100% coverage
  • Gradually taper down purchasing as we approached target
  • Maintain smooth, controlled behavior

Early Alternatives We Explored

Before arriving at the sigmoid solution, we explored several approaches

Blog image

In the end, the sigmoid function provided the smoothest, most tunable, and most natural progression.

The Solution: Sigmoid-Based Adjustment

We implemented an adjustment function based on the classic sigmoid formula:

Blog image

Where:

  • x is the progress ratio (current coverage/target coverage)
  • x₀ shifts the center of the curve (we chose 0.5)
  • k controls how steep the transition is (we chose 4.0)

This allows us to:

  • Keep purchasing aggressively when coverage is low
  • Begin reducing cost gently after reaching ~50% of the target
  • Ramp down sharply as we get very close to the target
  • Fully stop once we hit or exceed the configured target coverage

go

func

/* Syntax highlighting for code blocks */ .hljs-keyword { color: #569cd6; font-weight: bold; } .hljs-string { color: #ce9178; } .hljs-number { color: #b5cea8; } .hljs-comment { color: #6a9955; font-style: italic; } .hljs-function { color: #dcdcaa; } .hljs-variable { color: #9cdcfe; } .hljs-type { color: #4ec9b0; } .hljs-built_in { color: #4fc1ff; } .hljs-operator { color: #d4d4d4; } .hljs-punctuation { color: #d4d4d4; } .hljs-attr { color: #92c5f8; } .hljs-property { color: #9cdcfe; } .hljs-title { color: #dcdcaa; } .hljs-class { color: #4ec9b0; } .hljs-meta { color: #569cd6; } .hljs-literal { color: #569cd6; } .hljs-symbol { color: #ce9178; } .hljs-regexp { color: #d16969; } .hljs-link { color: #3794ff; text-decoration: underline; } .hljs-selector-tag { color: #569cd6; } .hljs-selector-id { color: #ffd700; } .hljs-selector-class { color: #d7ba7d; } .hljs-addition { color: #4fc1ff; background-color: rgba(79, 193, 255, 0.1); } .hljs-deletion { color: #f85149; background-color: rgba(248, 81, 73, 0.1); }

Tuning the Constants

We tuned three main constants to balance smoothness and control:

csharp

const

/* Syntax highlighting for code blocks */ .hljs-keyword { color: #569cd6; font-weight: bold; } .hljs-string { color: #ce9178; } .hljs-number { color: #b5cea8; } .hljs-comment { color: #6a9955; font-style: italic; } .hljs-function { color: #dcdcaa; } .hljs-variable { color: #9cdcfe; } .hljs-type { color: #4ec9b0; } .hljs-built_in { color: #4fc1ff; } .hljs-operator { color: #d4d4d4; } .hljs-punctuation { color: #d4d4d4; } .hljs-attr { color: #92c5f8; } .hljs-property { color: #9cdcfe; } .hljs-title { color: #dcdcaa; } .hljs-class { color: #4ec9b0; } .hljs-meta { color: #569cd6; } .hljs-literal { color: #569cd6; } .hljs-symbol { color: #ce9178; } .hljs-regexp { color: #d16969; } .hljs-link { color: #3794ff; text-decoration: underline; } .hljs-selector-tag { color: #569cd6; } .hljs-selector-id { color: #ffd700; } .hljs-selector-class { color: #d7ba7d; } .hljs-addition { color: #4fc1ff; background-color: rgba(79, 193, 255, 0.1); } .hljs-deletion { color: #f85149; background-color: rgba(248, 81, 73, 0.1); }

Blog image

Behavior Visualization

Here’s how the cost adjustment multiplier behaves based on coverage progress:

Blog image
Blog image

Edge Cases and Safeguards

Our function safely handles:

  • Zero or negative targets → No adjustment applied
  • Low progress (< 50%) → No reduction, continue full spend
  • Exceeding target coverage (progressRatio ≥ 1) → Stop all purchasing
  • Negative adjusted costs → Clamp to 0

This ensures stable, predictable behavior even during volatile usage patterns.

Results and Impact

Since implementing sigmoid-based cost adjustment:

  • Cloud savings increased by 5–10% across test accounts
  • Overspending reduced
  • Purchasing behavior became much smoother and more predictable

Future Work

We are exploring:

  • Dynamic smoothing factors based on workload volatility
  • Alternative smooth curves (e.g., softplus) for even finer control
  • Customer-specific tuning based on risk appetite

Conclusion

Even small mathematical refinements — like introducing a sigmoid decay in purchasing behavior — can make a big difference in cloud cost optimization.

At Harness, we believe that combining robust forecasting with intelligent adjustment mechanisms is the key to maximizing savings, reducing risk, and delighting customers.

Sridhar Balijepalli

Sridhar Balijepalli is an engineer at Harness specializing in scalable Continuous Integration and Continuous Delivery (CI/CD) systems. With hands-on experience designing and optimizing deployment pipelines, he helps teams ship software faster, more reliably, and at enterprise scale. He holds a degree from The University of Kansas and is passionate about automation, developer productivity, and platform engineering.

Similar Blogs

No items found.
No items found.
No items found.
No items found.
No items found.