Spot vs On-Demand Break-Even
Problem Statement
GPU spot instances are 60-90% cheaper than on-demand, but AWS can reclaim them with two minutes' notice. Each reclaim costs you the time to relaunch and restore from the last checkpoint. Work out whether spot is actually cheaper for a given training job, and at what spot price the two break even.
Background
The naive comparison — spot price versus on-demand price — is wrong, because interruptions make the job take longer, and you pay for that extra time too.
Model:
expected_interruptions = hours * interruption_prob # per-instance-hour reclaim probability
effective_hours = hours + expected_interruptions * restart_overhead_hours
on_demand_cost = hours * instances * on_demand_price
spot_cost = effective_hours * instances * spot_price
savings = on_demand_cost - spot_cost
savings_pct = 100 * savings / on_demand_cost
The break-even spot price is the price per hour at which spot costs exactly the same as on-demand:
break_even_spot_price = on_demand_price * hours / effective_hours
Below it spot wins, above it the restart overhead eats the discount. Note instances cancels out — it scales both sides equally.
Frequent interruptions with an expensive restart (a big model with slow checkpoint restore) can push savings negative even at a headline 70% discount. That is the answer this calculation is for.
Your Task
Implement:
def spot_vs_on_demand(hours, instances, on_demand_price, spot_price, interruption_prob, restart_overhead_hours):
Return a dict with keys "effective_hours", "on_demand_cost", "spot_cost", "savings", "savings_pct", "break_even_spot_price", in that order. Round the first five to 2 decimals and "break_even_spot_price" to 4.
Input Format
- hours: uninterrupted wall-clock hours the job would need.
- instances: number of instances.
- on_demand_price, spot_price: USD per instance-hour.
- interruption_prob: probability that an instance is reclaimed in any given hour.
- restart_overhead_hours: hours lost per interruption (relaunch plus checkpoint restore).
Output Format
- The dict described above.
Sample
print(spot_vs_on_demand(48, 4, 3.06, 0.90, 0.02, 0.25))
Output:
{'effective_hours': 48.24, 'on_demand_cost': 587.52, 'spot_cost': 173.66, 'savings': 413.86, 'savings_pct': 70.44, 'break_even_spot_price': 3.0448}
At 2% hourly reclaim risk you expect 0.96 interruptions over 48 hours, adding about 14 minutes of restart time. Spot still wins by a mile — you would only lose out above $3.0448/hr.
Example
print(spot_vs_on_demand(48, 4, 3.06, 0.90, 0.02, 0.25))
{'effective_hours': 48.24, 'on_demand_cost': 587.52, 'spot_cost': 173.66, 'savings': 413.86, 'savings_pct': 70.44, 'break_even_spot_price': 3.0448}48 hours at a 2% hourly reclaim rate gives 0.96 expected interruptions, each costing 0.25 h, so the job really occupies 48.24 instance-hours. On-demand is 48 * 4 * 3.06 = 587.52 while spot is 48.24 * 4 * 0.90 = 173.66, a 70.44% saving. Spot only stops paying once its price reaches 3.06 * 48 / 48.24 = 3.0448 per hour.
Constraints
- hours > 0, instances >= 1, prices >= 0
- 0 <= interruption_prob <= 1, restart_overhead_hours >= 0
- Expected interruptions is
hours * interruption_prob(no rounding to whole interruptions) savingsandsavings_pctmay be negative- Round
effective_hours,on_demand_cost,spot_cost,savings,savings_pctto 2 decimals andbreak_even_spot_priceto 4