Capacity Headroom
Resource utilization with a Holt projection to the ceiling and the probability of saturation before the horizon.
Capacity Headroom
80%
of capacity · 90% ceiling
- Utilization
- Projected
Utilization has a 44% chance of exceeding the 90% ceiling by Jul 2026.
| Week | Utilization % |
|---|---|
| Mar 9, 2026 | 64% |
| Mar 16, 2026 | 66% |
| Mar 23, 2026 | 65% |
| Mar 30, 2026 | 68% |
| Apr 6, 2026 | 70% |
| Apr 13, 2026 | 69% |
| Apr 20, 2026 | 72% |
| Apr 27, 2026 | 74% |
| May 4, 2026 | 73% |
| May 11, 2026 | 76% |
| May 18, 2026 | 78% |
| May 25, 2026 | 80% |
Infrastructure metrics · Holt linear-trend forecast · updated hourly
Demo data is illustrative. Replace with your own typed data prop.
How it computes
Utilization forecast via Holt(α=0.5, β=0.3) with P(exceeding the ceiling) and the first crossing week.
util = 100·load/capacity; forecast = holtLinear(...); P(breach) = Φ_above(forecast_H, se_H, ceiling)Assumptions
- Utilization is linearly trendable over the horizon (default 6 weeks).
- The ceiling is a hard limit with no flex.
- Residual σ from the in-sample Holt fit.
Honest about
- Prediction intervals use the ETS(A,A,N) SE, widening faster than √h rather than a random-walk √h.
- Needs ≥2 points or it shows an empty/error state.
- If the forecast never reaches the ceiling, the crossing week defaults to the horizon end.
Reference: Hyndman & Athanasopoulos, Forecasting: Principles and Practice
Use it with your data
Data contract
Passed via the data prop — an object: validated at runtime, so a bad shape degrades to the error state rather than crashing.
| Field | Type | Required |
|---|---|---|
| ceilingPct | number | yes |
| weeks | array | yes |
Static props
import { OpsCapacityHeadroom } from "@/components/blocks/ops-capacity-headroom/ops-capacity-headroom";
<OpsCapacityHeadroom data={myData} />Client fetch (SWR)
const { data, isLoading, error } = useSWR("/api/metric", fetcher);
// route isLoading/error through <ChartStates>, then:
<OpsCapacityHeadroom data={data} />Server component (RSC)
const data = await fetch(url, {
next: { revalidate: 3600 },
}).then((r) => r.json());
<OpsCapacityHeadroom data={data} />Map arbitrary rows
import { mapRows } from "@/lib/sextant/column-map";
const out = mapRows(rows, { /* contractKey: "yourColumn" */ }, dataSchema);
if (out.ok) <OpsCapacityHeadroom data={out.data} />;Make it yours
Every customization below is an optional prop — omit them all and you get the defaults shown above. Recolor, reformat, restyle, or drop the card chrome without forking the component.
Recolor or rename a series (utilization, projected)
<OpsCapacityHeadroom
series={{ utilization: { color: "var(--chart-3)", label: "…" } }}
/>Format numbers (currency / locale)
const eur = new Intl.NumberFormat("de-DE", {
style: "currency",
currency: "EUR",
notation: "compact",
});
<OpsCapacityHeadroom valueFormatter={(n) => eur.format(n)} />Replace or hide the narrative
<OpsCapacityHeadroom narrative="Your own one-liner." />
// …or hide it entirely:
<OpsCapacityHeadroom narrative={false} />Restyle any region
<OpsCapacityHeadroom
className="max-w-xl"
classNames={{ body: "bg-muted/20" }}
/>Drop the card chrome (headless plot)
import { OpsCapacityHeadroomPlot } from "@/components/blocks/ops-capacity-headroom/ops-capacity-headroom";
// Just the chart body — bring your own card/layout:
<OpsCapacityHeadroomPlot data={data} config={config} />