What is missing
Three related gaps around hardware. A reader cannot pick most machines, cannot describe a machine
that is not on the menu, and cannot make any hardware spec change a result.
1. The catalog covers three component kinds. isSizedKind names eleven kinds, but only
service, db and cache carry a sizes array at any vendor. AWS ships 15 sizes, GCP 13, Azure
15. A worker, a replica set, a shard, a search index, a time series store, a graph store, a vector
store and a transcoder all get a product name and no picker, because VendorPanel renders the
picker only when mapping.sizes is non-empty.
That is not only a missing dropdown. costDesign pushes any mapped kind with no priced size onto
unpriced, so every design containing a worker reports a monthly total that silently excludes the
workers. Async worker topologies are a large share of the bundled examples.
The families on offer are also narrow. service gets general purpose only (t3, m6i, n2, e2,
D_v5). There is no compute optimised or memory optimised shape, which is the first thing anyone
sizing a real service compares.
2. There is no custom machine. An infra team runs shapes a catalog will never hold: a reserved
instance, a bare metal box, an on-prem server, a Kubernetes pod request and limit. Today those
cannot be expressed, so the tool can only price what the vendor files happen to contain. GCP
already uses custom machine types in this repo (db-custom-4-16384), so the vocabulary exists.
3. Specs that are collected but never used. VendorSize carries memory, network and
maxIops, each cited. Only vcpu does anything: derive.ts turns it into capacity. memory
prints as text in VendorPanel.tsx:79. network and maxIops are read nowhere in src/. So a
reader picks db.r6g.large, sees 16 GiB and "Up to 10 Gigabit", and neither number can ever
change a result.
Smaller, in the same area: chosen sizes live in localStorage keyed vendor:nodeId (sizing.ts),
so share links and exported .breakscale files arrive unsized and unpriced.
What would it teach
That CPU is rarely what breaks first. A student sizes a service for throughput, watches the queue
stay short, and still sees it die because each in-flight request holds 40 MB and the box has 16
GiB. Or the queue is healthy and the NIC is full at 1.2 Gbps. Right now the only way to fail in
Breakscale is to run out of slots or time, and that is the least common outage in practice.
A custom machine adds the sizing exercise itself: put the box you already own next to the box on
the menu and see which one survives the load.
The byproduct is that an infra or devops reader can take a design to provisioning: this is the
fleet, this is the shape, and this is the resource that binds first.
Rough shape
- Sizing becomes part of the design. Move the chosen size out of
localStorage and into the
topology, so export, import and share links carry it. This is a prerequisite for anything
custom, since a machine the reader defined is worthless if it does not travel with the design.
- Widen the catalog. Sizes for the eight sized kinds that have none, and compute optimised
and memory optimised families for service. Same rule as today: published spec, source URL,
date read. This closes the hole in the cost total on its own.
- A custom machine. Name, vCPU, memory, network, IOPS, price per hour, entered by the reader.
It runs through the same deriveFromSize and the same cost arithmetic as a catalog size.
- Resources become simulation dimensions. Per-request demand and per-node limit for memory,
IOPS and bandwidth. Memory exhaustion sheds; IOPS and bandwidth saturation adds delay rather
than failing outright. Mechanics are yours to decide; that is one plausible split.
- A provisioning readout. Per component: kind, shape, fleet, and the resource with the least
headroom.
Keeping it honest
A custom machine is labelled user defined everywhere it appears. It never carries a source URL and
is never mixed into anything that claims to be published spec. Where a total is priced from a
reader's own figure rather than a published rate, the readout should say so.
Per-request demand would be user set, defaulting to unset. Unset shows nothing rather than a
guessed number, the way derive.ts returns null where there is nothing honest to say. No resource
figure would be derived from an instance size, and the derivation stays in one file.
This is the argument cost.ts already makes for money: a design trade-off the simulator cannot
currently show. And derive.ts already tells readers who want real behaviour to set the knobs
themselves. This is more knobs to set.
Anything you already tried
Checked against what is planned. TODO lists a networking layer (bandwidth and loss), which step 4
should fold into rather than duplicate. Issue #13 covers documenting how vendor sizes become
simulator numbers, which is adjacent: that explains the current derivation, this widens what a
size can affect.
What is missing
Three related gaps around hardware. A reader cannot pick most machines, cannot describe a machine
that is not on the menu, and cannot make any hardware spec change a result.
1. The catalog covers three component kinds.
isSizedKindnames eleven kinds, but onlyservice,dbandcachecarry asizesarray at any vendor. AWS ships 15 sizes, GCP 13, Azure15. A worker, a replica set, a shard, a search index, a time series store, a graph store, a vector
store and a transcoder all get a product name and no picker, because
VendorPanelrenders thepicker only when
mapping.sizesis non-empty.That is not only a missing dropdown.
costDesignpushes any mapped kind with no priced size ontounpriced, so every design containing a worker reports a monthly total that silently excludes theworkers. Async worker topologies are a large share of the bundled examples.
The families on offer are also narrow.
servicegets general purpose only (t3, m6i, n2, e2,D_v5). There is no compute optimised or memory optimised shape, which is the first thing anyone
sizing a real service compares.
2. There is no custom machine. An infra team runs shapes a catalog will never hold: a reserved
instance, a bare metal box, an on-prem server, a Kubernetes pod request and limit. Today those
cannot be expressed, so the tool can only price what the vendor files happen to contain. GCP
already uses custom machine types in this repo (
db-custom-4-16384), so the vocabulary exists.3. Specs that are collected but never used.
VendorSizecarriesmemory,networkandmaxIops, each cited. Onlyvcpudoes anything:derive.tsturns it intocapacity.memoryprints as text in
VendorPanel.tsx:79.networkandmaxIopsare read nowhere insrc/. So areader picks
db.r6g.large, sees 16 GiB and "Up to 10 Gigabit", and neither number can everchange a result.
Smaller, in the same area: chosen sizes live in
localStoragekeyedvendor:nodeId(sizing.ts),so share links and exported
.breakscalefiles arrive unsized and unpriced.What would it teach
That CPU is rarely what breaks first. A student sizes a service for throughput, watches the queue
stay short, and still sees it die because each in-flight request holds 40 MB and the box has 16
GiB. Or the queue is healthy and the NIC is full at 1.2 Gbps. Right now the only way to fail in
Breakscale is to run out of slots or time, and that is the least common outage in practice.
A custom machine adds the sizing exercise itself: put the box you already own next to the box on
the menu and see which one survives the load.
The byproduct is that an infra or devops reader can take a design to provisioning: this is the
fleet, this is the shape, and this is the resource that binds first.
Rough shape
localStorageand into thetopology, so export, import and share links carry it. This is a prerequisite for anything
custom, since a machine the reader defined is worthless if it does not travel with the design.
and memory optimised families for
service. Same rule as today: published spec, source URL,date read. This closes the hole in the cost total on its own.
It runs through the same
deriveFromSizeand the same cost arithmetic as a catalog size.IOPS and bandwidth. Memory exhaustion sheds; IOPS and bandwidth saturation adds delay rather
than failing outright. Mechanics are yours to decide; that is one plausible split.
headroom.
Keeping it honest
A custom machine is labelled user defined everywhere it appears. It never carries a source URL and
is never mixed into anything that claims to be published spec. Where a total is priced from a
reader's own figure rather than a published rate, the readout should say so.
Per-request demand would be user set, defaulting to unset. Unset shows nothing rather than a
guessed number, the way
derive.tsreturns null where there is nothing honest to say. No resourcefigure would be derived from an instance size, and the derivation stays in one file.
This is the argument
cost.tsalready makes for money: a design trade-off the simulator cannotcurrently show. And
derive.tsalready tells readers who want real behaviour to set the knobsthemselves. This is more knobs to set.
Anything you already tried
Checked against what is planned. TODO lists a networking layer (bandwidth and loss), which step 4
should fold into rather than duplicate. Issue #13 covers documenting how vendor sizes become
simulator numbers, which is adjacent: that explains the current derivation, this widens what a
size can affect.