Skip to content

Capacity Blocks for ML: instance-count gating, CB-only types, eligibility allowlist, 24h floor, utilization break-even #109

Description

@scttfrdmn

Summary

truffle capacity-blocks / truffle capacity --blocks surface Capacity Block
offerings, but a few behaviours of DescribeCapacityBlockOfferings are easy to
get wrong and produce misleading output. Filing what I verified live so the
handling can be hardened (and because the numbers are useful reference data).

All verified 2026-07-27, account 942542972736.

1. --instance-count silently gates results (highest-impact)

I initially concluded p5.48xlarge and p6-b200.48xlarge had zero capacity
block offerings. That was an artifact of asking for --instance-count 8. At
--instance-count 1, all four accelerator types had offerings:

p5.48xlarge      us-east-2 / us-west-2   24h  $ 996.67  = $41.53/inst-hr
p5e.48xlarge     us-west-2               24h  $1146.24  = $47.76/inst-hr
p5en.48xlarge    us-east-2 / us-west-2   24h  $1318.08  = $54.92/inst-hr
p6-b200.48xlarge us-west-2               24h  $2372.16  = $98.84/inst-hr

An empty result for a large count reads as "no capacity exists" when the truth is
"not that many at once." Probing count=1 first, or noting the count in the
"no offerings" message, would avoid a wrong conclusion. (us-east-1 genuinely has
0 offerings at every count I tried — region matters independently of count.)

2. Capacity blocks routinely UNDERCUT on-demand

Type CB $/inst-hr On-demand $/hr CB discount
p5.48xlarge (8×H100) $41.53 $55.04 −24.5%
p5en.48xlarge (8×H200) $54.92 $63.30 −13.2%
p6-b200.48xlarge (8×B200) $98.84 $113.93 −13.2%
p5e.48xlarge (8×H200) $47.76 no on-demand price exists

The discount is per-family and reportedly drifts over time, so it shouldn't be
hardcoded anywhere — worth computing from the two live sources when both exist.

3. Some accelerator types are Capacity-Block-ONLY

p5e.48xlarge has zero AWS Price List rows of any kind — no OnDemand, no
CapacityBlock — yet DescribeInstanceTypeOfferings lists it in us-east-2
(2a/2b/2c) and us-west-2 (2c), and capacity blocks are purchasable at
$47.76/inst-hr. Any code path that resolves a price via the Price List first will
report this type as unpriced/unavailable when it is in fact buyable — and at a
rate that beats p5en.48xlarge for the same 8×H200 hardware.

4. "Capacity Blocks for ML" is a restricted per-region allowlist

GPU does not imply eligible. Rejected in us-west-2:

g7e.4xlarge     -> InvalidParameterValue: The instance type 'g7e.4xlarge' is not
                   supported for Capacity Blocks in 'us-west-2'
c7i.4xlarge     -> same
trn2.48xlarge   -> same   (Trainium, also rejected)

So the API distinguishes ineligible (error) from eligible but sold out
(empty list). Worth surfacing differently — "this type can't use capacity blocks
here" is a different answer for a user than "none available right now."

5. Duration constraints

  • 24h minimum, 24h granularity. 1/4/6/8/12h are all rejected with
    InvalidParameterValue: The duration is not valid. 24/48/72h valid. 168h
    returned no offerings.
  • Booking horizon ~9 days. DescribeCapacityBlockOfferings rejects end dates
    beyond it: The end date is not valid. End date must not be later than Wed Aug 05 14:47:53 UTC 2026. A helpful error message when a user asks for a
    window further out would beat passing the raw API error through.

6. Price List marketoption=CapacityBlock rows are always $0.0000

p6-b200.48xlarge  marketopt=CapacityBlock  capstatus=Used  $0.0000
p6-b200.48xlarge  marketopt=OnDemand       capstatus=Used  $113.9328

Real capacity block cost lives only in DescribeCapacityBlockOfferings as
UpfrontFee. Anything reading the Price List CapacityBlock rows will report free
H200s.

7. Don't assume the returned block matches the request

AWS can return shorter, partially-used blocks that a previous holder didn't
consume — potentially the best value on offer. I could not reproduce this in the
current window (every offering came back exactly as requested), but the safe
handling is to read CapacityBlockDurationHours, StartDate, EndDate and
InstanceCount off each offering and compute from those rather than from the
request parameters.

8. Worth surfacing: utilization break-even

Because the block is prepaid and non-refundable, effective cost is
UpfrontFee ÷ hours actually used. For p5.48xlarge:

used of 24h effective $/used-hr vs on-demand
24h $41.53 −25%
18h $55.37 +1%
12h $83.06 +51%
8h $124.59 +126%
2h $498.36 +805%

Break-even is 18.1h of 24h (75% utilization.) Below that on-demand is cheaper
despite the headline discount. A short burst job on a capacity block can pay 5–8×
the on-demand rate per useful hour. Given truffle's cost-advisory role, a note or
--utilization hint alongside the upfront fee would help users avoid this.

Context

Found while building a Hugging Face model → AWS deployment tool that compares
Bedrock vs SageMaker vs EC2 (on-demand / spot / capacity block) for serving the
same model. Related: #107 (SageMaker Hosting component), #108 (obtainability).

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions