{# Spec 157 - Reservations right-sizing page. Renders one ``SlotDemandSnapshot`` row per active config: a hero stat strip (avg / p95 / peak / idle), the demand-curve chart with horizontal reference lines for current + recommended reservation size, and a recommendation card carrying the reasoning block + a copy-paste ALTER RESERVATION (or CREATE RESERVATION) SQL snippet. Empty state shows when no snapshot has been computed yet (typically a fresh install whose first scan hasn't run). Low-data state shows a soft caveat when fewer than 100 jobs went into the snapshot. #} {% extends "layout.html" %} {% block content %}

Reservations

{% if not snapshot %}

No reservation snapshot yet

Run a scan to compute the slot demand curve for your workload. It will appear here once at least one scan has completed.

Go to scan
{% else %} {% from "components/_stat_card.html" import stat_card %} {# Hero stat strip. Slot stats are unitless effective slots, measured per-minute over the scan window from the user's own jobs. #}
{{ stat_card("Avg slots used", "%.1f" | format(snapshot.avg_slots), tooltip="Average effective slot count across every 1-minute bucket of the scan window (zero-demand minutes included).") }} {{ stat_card("P95 slots used", "%.0f" | format(snapshot.p95_slots), tooltip="95th percentile demand - the 'burst floor': 95% of minutes used at most this many slots.") }} {{ stat_card("Peak slots used", "%.0f" | format(snapshot.peak_slots), tooltip="Maximum effective slot count in any 1-minute bucket of the scan window.") }} {{ stat_card("Idle fraction", ("%.0f%%" | format(snapshot.idle_fraction * 100)), accent="amber", tooltip="Fraction of 1-minute buckets with zero effective slot usage. High values suggest a bursty workload that could be split between a smaller reservation and on-demand overflow.") }}
{% if snapshot.low_data %}

Low-data caveat: Only {{ snapshot.low_data_job_count }} jobs in the scan window contributed to this snapshot. Below ~100 jobs the demand curve is noisy; rerun with a longer window or wait for more activity before drawing conclusions.

{% endif %} {# Demand chart - measured effective slots over time, with a horizontal reference line for the current reservation size when it's known (discoverable via bigquery.reservations.get). #}
{% from "components/_section_title.html" import section_title %}
{{ section_title( "Slot demand over the scan window", description="Per-minute effective slot usage, measured from your own jobs. Red line = current reservation size (when discoverable)." ) }}
{# Scan-window meta - lets the user verify they're looking at the right snapshot when reservations change over time. #}

Scan window: {{ snapshot.scan_window_start.strftime('%Y-%m-%d %H:%M UTC') }} → {{ snapshot.scan_window_end.strftime('%Y-%m-%d %H:%M UTC') }}

{# ECharts demand chart + copy-by-id helper. #} {% endif %}
{% endblock %}