GKE Demo Cost Model¶
This exists so the cost of the public demo is decided once and cited, rather than re-derived — badly — every time someone asks. Two earlier analyses disagreed by 3× on the model line and both omitted the static-IP charge.
Every dollar figure below is a point-in-time observation dated 2026-07-31, taken from the GKE/Compute Engine pricing pages on that date. Google states that Spot prices can change up to once every day, so treat any Spot line older than a month as unverified and re-check before quoting it. The repository facts (Terraform defaults, logging configuration, budget knobs) were re-verified against this checkout on 2026-08-01 and are cited by file.
1. The profile this prices¶
infra/terraform/demo.tfvars: one zonal e2-standard-4 node in europe-north1-b, Spot, 20 GiB boot disk, regional = false. The workload half — dropping HA and the optional stacks — is tracked separately in #1648; until it lands, the compute line below is right but the cluster will be tighter than intended.
1.1 Measured node requests¶
Derived from the rendered clusters/gcp-demo overlay on 2026-08-01 by summing every resources.requests block across its enabled Kustomization paths, then adding the LimitRange defaultRequest (25m / 64Mi, infra/namespaces/resource-quotas.yaml) for the four components that declare resources only in the production-HA composition this profile drops — Synapse, MAS, haproxy, and Element Web. The agentgateway data-plane proxy (50m / 128Mi) is counted separately from its 100m control plane.
| CPU | Memory | |
|---|---|---|
| Explicit requests (15 blocks) | 610m | 384Mi |
| LimitRange fallback (4 components) | 100m | 256Mi |
| Total requested | 710m | 640Mi |
e2-standard-4 allocatable (approx.) |
~3920m | ~13000Mi |
| Headroom | ~3210m | ~12360Mi |
These are requests, not consumption: they prove the profile schedules on one node with room to spare, not that it runs well under load. Actual usage is only measurable against a live cluster and is owed to #59.
The single largest reason this fits is that clusters/gcp-demo selects the vertex model path rather than inheriting clusters/gcp's vllm: the vLLM model server alone requests 4000m CPU, which exceeds the whole node. Prompts therefore leave the cluster on this profile.
2. Per-line monthly cost¶
| Line | Monthly | Basis |
|---|---|---|
| GKE cluster management fee | $0 | The free tier covers one zonal Standard cluster per billing account. Regional clusters are not eligible. |
Node — e2-standard-4 Spot |
$28.66 | europe-north1. The same node in europe-west1 was $52.12: region is the single biggest lever, ahead of machine size. |
| Boot disk — 20 GiB pd-balanced | ~$2 | Scales linearly with boot_disk_size_gb; 20 GiB is the validated floor. |
| Static external IP | $8.03 | google_compute_address.ingress_ip (infra/terraform/vpc.tf:32), consumed by infra/terraform/dns.tf:36. Both earlier analyses omitted this line. |
| Load-balancer forwarding rule | $20.44 | See §5 for why removing it is not the saving it appears to be. |
| Cloud Logging | $0 | First 50 GiB per project per month is free, and infra/terraform/gke.tf:108 limits export to SYSTEM_COMPONENTS. Widening that is what makes it non-zero. |
| Cloud DNS managed zone | ~$0.40 | One zone plus low query volume. |
| Model inference | variable | Not a fixed line. It is the only unbounded one, which is why §4 exists. |
var.regional must stay false. It defaults to false (infra/terraform/variables.tf:91), and flipping it silently costs about $73/month in cluster management fee alone — the free tier stops applying — before the node multiplication that node_count per-zone semantics cause.
3. What the Spot discount actually buys, and what it costs¶
State this plainly, because the tempting framing is wrong.
A single Spot node has no bounded recovery time. Google says Spot VMs "might not always be available", and a managed instance group can replace one only "when additional Compute Engine resources are available". Spot is excluded from the Compute Engine SLA. There is therefore no supported basis for publishing a recovery estimate — the "5–8 minutes of downtime" framing that circulated during the design pass must not appear in any Fgentic document, because nothing supports it and it converts an unbounded outage into an apparent SLA.
What is true: preemption can happen at any time with a 30-second termination notice, one node means any node event is a total outage, and recovery completes when capacity returns — which may be minutes or considerably longer. That is acceptable here only because the demo is rebuildable from Git in one pass and carries no availability commitment (operations handbook §8.4–8.5).
4. The layered spend ceiling¶
Google Cloud has no hard spend cap. A billing budget is a notification, not a limit; it does not stop spend. Anyone who believes otherwise will discover it during an incident. The ceiling is therefore layered, and only the inner two actually stop anything:
ROOM_TOKEN_BUDGET(primary, and the only one that fails closed on the request path). A per-room cumulative token budget over the period inROOM_TOKEN_BUDGET_PERIOD(apps/matrix-a2a-bridge/internal/config/config.go:152). A room that exhausts it is refused before the model is called, with a bounded notice. This is the control to set first.- Vertex requests-per-minute quota override (outer hard rate ceiling). A provider-side quota bounds the rate at which spend can accumulate even if every in-cluster control fails. It bounds velocity, not total.
- Billing budget alert (notification only). Useful for noticing, useless for stopping. Never describe it as a cap.
The per-sender and per-room rate limits and the per-azp cross-org reservation are admission controls, not spend measurements — a reservation is a ceiling on what a partner may request, never evidence of what was consumed.
5. The deferred hostPort option, priced honestly¶
Dropping the load balancer for hostPort looks like a −$20.44/month saving. Its true cost:
- +$8.03/month unless
google_compute_address.ingress_ipis also deleted and everything consuming it rewired — so the naive change saves $12.41, not $20.44. - ACME HTTP-01 renewal is unresolved against a rotating node IP.
- The DNS reconciler would be co-resident on the node it is supposed to recover, which is circular on a single-node cluster.
- No answer for Matrix federation against a firewall that only opens 80/443.
Deferred deliberately. Revisit only with answers to all four, not with the price alone.
6. Re-check cadence¶
Re-verify the Spot and node lines monthly, and always before quoting them externally or in a funding conversation. When you do, update the dates in this document rather than adding a second table — two dated tables is how the 3× disagreement happened.