Skip to main content

Module cost

Module cost 

Source
Expand description

What a run cost, and what a plan will cost, with every figure labelled.

MicroVMs has no standalone pricing page. The rates appear only inside worked examples on the Lambda pricing page, which is why this module exists as data rather than as a paragraph someone re-derives: a consumer building a sandbox product should be able to ask “what did that run cost” without reading a pricing page sideways.

Two rules hold everywhere below. The Python client’s cost.py enforced both at runtime — a TypeError from a keyword-only field, a NotImplemented from __add__. Here they are the shape of the types, so the enforcement happens before the program runs.

Seconds are measured, dollars are estimated. DurationP is an enum whose every variant names its provenance, so there is no unlabelled constructor to call — not one that raises, one that does not exist (COST-1). And there is no type here for an actual dollar amount, only EstimatedUsd, which says so on every render. Only Cost Explorer knows the bill. That asymmetry is the point: we can time a suspension to the millisecond and still only infer its price.

Unknown is not zero. Amount::Unpriced carries a reason and is a distinct variant, so a consumer matching on an amount has to handle it (COST-3). AWS does not publish whether the server-side image build is billed as compute, so a report that summed it as $0.00 would be lying in the direction that flatters us. A Total over any unpriced line is a different variant, Total::AtLeast, which cannot be read without seeing the reasons beside the floor (COST-4).

§What this port strengthens

Three closures move up the strength ladder from the Python original.

  • No negative duration. cost.py validated seconds >= 0 in __post_init__, because an inverted clock renders as a credit on the report. DurationP wraps std::time::Duration, which cannot be negative, so the check is gone rather than moved: the only place a sign can go wrong is seconds_of, the one f64 boundary, and it is fallible.
  • No coercion to float. cost.py omitted __float__ and relied on the reader not writing float(x.amount). EstimatedUsd has a private field, no From/Into<f64>, no Deref, and no Serialize that emits a number — the coercion is not a discouraged spelling, it is absent (COST-2).
  • No x86 rate, by construction. pricing.py refused to substitute the x86 compute rate inside its fetch path, which meant a hand-built RateTable could still carry one. Here RateTable’s rate fields are private and there are exactly two ways to obtain one — the pinned pinned_rates, and RateTable::from_catalog, which rejects a catalog whose ARM line is missing (COST-9). No value of the type exists that was built from an x86 figure.

§The table carries its own staleness

pinned_rates is pinned to a retrieval date, and a table older than STALE_AFTER_DAYS attaches a warning to every report computed from it (COST-7), because a silently stale price is the same failure class as a silently stale schema. The warning is a fallback rather than the defence — it can only say that nobody has looked. RateCatalog is what looks.

Every rate here is recorded in docs/PLATFORM.md, “What actually costs money”. One of them, RateTable::storage_gb_month, is derived: the API quotes snapshot storage per GB-hour and this table holds per GB-month, so it is the hourly figure times HOURS_PER_MONTH. Billing reads SizeClass::baseline_gb and never the peak (COST-5).

Structs§

Budget
A ceiling on a report’s total, and what a breach of it does.
BudgetVerdict
A report’s total judged against a Budget.
CalendarDate
A calendar day, which is the only temporal resolution a rate table has.
CatalogEntry
A priced line item as the catalog states it: a group, a unit, and one USD figure.
CostReport
Per-phase attribution for one sandbox, measured or projected.
EstimatedUsd
Dollars derived from published rates. Not the bill.
LineItem
One phase’s one billing line: what was consumed, and what that costs.
PlanUsage
A plan’s phases, in plain seconds, before anything is spent.
RateCatalog
What a rate source offers for one region, before it becomes a RateTable.
RateTable
us-east-1 rates, pinned to when they were read and where from.
ResidencyComparison
Running versus suspended for the same VM over the same wall time.
RunUsage
What to attribute cost to, for one sandbox’s lifecycle.
UnpricedLine
One line item a total could not price: which phase it belonged to, and why.

Enums§

Amount
What a line item’s cost can be (COST-3).
BillingLine
The line items AWS bills, spelled as separately as AWS bills them.
CatalogLine
One rate the catalog has to carry, and what it fills.
CostPhase
The lifecycle a sandbox goes through, as the phases that cost money.
DurationP
Seconds, plus how we know them (COST-1).
OnBreach
What a breached budget does: report it, or refuse the plan. There is no default.
Provenance
Where a duration came from. There is no third option and no default.
Total
A report’s total, which is a lower bound whenever anything is unpriced (COST-4).

Constants§

BUILD_UNPRICED_REASON
Why the image build has no price.
DEFAULT_ESTIMATE_LABEL
The label an estimate carries when its caller names none: the CLI’s cost --estimate and both bindings’ estimate_run (#255).
DEFAULT_REPORT_CYCLES
The suspend/resume cycles a report counts when the caller names none: zero, the suspend_resume_cycles of RunUsage::default and PlanUsage::default, and what the CLI’s cost and cost --estimate and both bindings’ run_report and estimate_run apply.
DEFAULT_RESIDENCY_CYCLES
The suspend/resume cycles compare_residency prices when the caller names none: one, the fewest that make a suspension more than a termination.
DEFAULT_RUN_LABEL
The label a run’s report carries when its caller names none: the CLI’s cost and both bindings’ run_report.
HOURS_PER_MONTH
Hours in the month AWS’s GB-month rate assumes, derived from SECONDS_PER_MONTH rather than written again.
MINIMUM_RETENTION
Snapshot storage bills at least this long however briefly the snapshot exists (COST-8).
SECONDS_PER_MONTH
AWS bills storage per GB-month and defines a month as 730 hours, so a partial-month hold is that fraction of the monthly rate.
STALE_AFTER_DAYS
How old a rate table may get before it warns (COST-7).

Functions§

compare_residency
The warm-pool argument, with its own counter-argument attached.
duration_of_secs_f64
Seconds from a float for a figure on a report, refused when the float cannot be a duration.
estimate_run
What a plan will cost, before spending anything (COST-10).
gb_decimal
A float from a caller, converted into the money path exactly once (COST-6).
pinned_rates
Read 2026-08-07, us-east-1, and recorded in docs/PLATFORM.md under “What actually costs money”.
run_report
Per-phase attribution for one sandbox’s lifecycle.
seconds_of
Seconds as an exact Decimal, from the one representation that cannot be negative.