Module cost

Module cost 

Source
Expand description

The placement cost model — §3.4’s node costs, edge costs and byte estimates.

docs/03-type-and-effect-system.md §3.4:

Node costs: ∞ for forbidden tiers; tier-specific compute cost otherwise (client CPU is expensive and untrusted; fold-engine compute is cheap and adjacent to state). Edge costs: for each signal edge or call that crosses tiers, latency + bytes × unit, bytes estimated from row types.

Everything here is an integer. Not for speed — the graphs are tiny — but because §3.4’s first guardrail is determinism, and a cost model in floating point makes “these two placements cost the same” a question about rounding. Costs are in hundredths of a notional millisecond, so a latency of 25 ms is 2_500.

§The numbers, and where they come from

They are not measured; they are ordered, and the ordering is what a placement decision reads. Every one is a ratio the design already states, so the model can be argued with rather than tuned in the dark:

quantityvaluefrom
compute weight, data1“fold-engine compute is cheap and adjacent to state” (§3.4)
compute weight, server2the middle
compute weight, client8“client CPU is expensive and untrusted” (§3.4)
latency, data ↔ server1 mssame pod network
latency, server ↔ client25 msPhase 0’s realistic RTT (18)
latency, data ↔ client26 msit goes through the server
bytes → cost×5 per byteso a 2 KB crossing (~100 ms) outweighs an RTT, which is the
trade a placement decision is actually making

There is no constant for “a fold that is not at the data tier”. node_cost charges such a fold an edge to the log, sized from the accumulator, because that is what it physically pays: the log is at the data tier, and an accumulator kept elsewhere crosses to it on every event. A constant would have been a number to tune; an edge is a number to derive.

§The one rule worth arguing with

A crossing is charged the smaller of its two endpoints’ values, and that is not a simplification — it is §5.1’s Mode A/B question, expressed as a cost instead of as a mode. Between a Signal[State] at the data tier and a Signal[Html] at the browser, the compiler may either send the state and render in the browser (Mode B: 2 KB of data patches) or render first and send the document (Mode A: 1 KB of DOM patches). It will pick the cheaper, so the cheaper is what the boundary costs. Phase 2 only implements Mode A, so today the minimum is a prediction rather than a choice — and it is the right prediction to be making when Phase 3 makes the choice real.

Constants§

ASSUMED_CARDINALITY
How many elements a collection is assumed to hold when nothing says otherwise.
BYTE_UNIT
The cost of moving one byte across a tier boundary.
FORBIDDEN
A placement that cannot be, kept finite so that sums never overflow and comparisons stay total.

Functions§

compute_weight
§3.4: “client CPU is expensive and untrusted; fold-engine compute is cheap and adjacent to state”.
edge_cost
The cost of an edge between two placed nodes.
estimate_bytes
Estimate the wire size of a value of this type — §3.4’s “bytes estimated from row types”.
latency
Round-trip latency between two tiers, in hundredths of a millisecond.
node_cost
The node cost of putting row on tier, given how much work the node does and — for a durable fold — what its accumulator looks like.

Type Aliases§

Cost
Costs are in hundredths of a millisecond.