Exercise 21.2
Pick the Architecture -- Managed vs Self-Hosted Cost
Your service is quoted at \0.20 per 1,000 managed calls, or a \0.25/hr instance plus \$150/month of ops time if self-hosted. Compute the monthly cost of each at 2,000, 20,000, and 200,000 requests/day, and find the break-even volume. Your team forecasts 8,000 requests/day growing to 80,000 within a year. Which architecture do you start on, and at what point do you switch?
---
The same prediction service has two cost shapes: a managed endpoint that charges per call, and a self-hosted container that costs the same whether it is idle or saturated. Which is cheaper is not a matter of taste -- it is a crossover you compute from the request volume.
Use this exercise's pricing: \0.20 per 1,000 managed calls; or a \0.25/hr instance plus \$150/month of ops time if self-hosted. Write two functions:
def monthly_cost(requests_per_day, managed_per_1k=0.20, instance_per_hr=0.25, ops_per_month=150.0):
"""Return {'managed': $/month, 'self_hosted': $/month}. Assume 30 days, 24h."""
def breakeven_requests_per_day(**kw):
"""Smallest daily volume at which self-hosted is the cheaper choice."""Exact procedure: managed = requests_per_day 30 / 1000 managed_per_1k; self_hosted = instance_per_hr 24 30 + ops_per_month (round both to cents). breakeven_requests_per_day returns the smallest integer requests_per_day for which managed >= self_hosted (a binary search or a direct solve).
Expose: monthly_cost, breakeven_requests_per_day, breakeven = breakeven_requests_per_day().
> Think about it: the self-hosted box is a flat \$330/month here. Your team > forecasts 8,000 requests/day growing to 80,000 within a year -- which > architecture do you start on, and at what volume do you switch?
Stuck? Reveal hints one at a time — they progress from nudge to near-solution.
visibilityReveal reference solutionexpand_more
Try solving it yourself first — the hints walk you through it. The solution below is one valid approach; yours may differ and still be correct.
def monthly_cost(requests_per_day, managed_per_1k=0.20, instance_per_hr=0.25, ops_per_month=150.0):
"""Monthly cost of a managed endpoint (per call) vs a self-hosted box (always on)."""
reqs = requests_per_day * 30
managed = reqs / 1000 * managed_per_1k
self_hosted = instance_per_hr * 24 * 30 + ops_per_month
return {"managed": round(managed, 2), "self_hosted": round(self_hosted, 2)}
def breakeven_requests_per_day(**kw):
"""Smallest daily volume at which the always-on box becomes the cheaper choice."""
lo, hi = 1, 100_000_000
while lo < hi:
mid = (lo + hi) // 2
c = monthly_cost(mid, **kw)
lo, hi = (mid + 1, hi) if c["managed"] < c["self_hosted"] else (lo, mid)
return lo
breakeven = breakeven_requests_per_day()
print("at 2,000/day :", monthly_cost(2_000))
print("at 20,000/day :", monthly_cost(20_000))
print("at 200,000/day:", monthly_cost(200_000))
print("break-even :", breakeven, "requests/day")
lockCopying code is a Full Access feature.