> ## Documentation Index
> Fetch the complete documentation index at: https://docs.summand.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Forecast

> Time-series projection with 95% prediction intervals, using a Holt-Winters model under the hood.

The **Forecast** component projects future values for a single time-series target. It's a two-piece chain:

* `forecast_model` (internal) — fits a Holt-Winters / SES model on the aggregated history and persists the fit to S3.
* `forecast` (user-visible) — pulls the cached fit, calls `.forecast(steps=horizon)`, derives 95% prediction intervals, and emits the JSON the chat UI renders.

The split is deliberate: re-running with a different horizon shouldn't refit the model. Statsmodels' own docs are explicit on this — `refit` is for new observations, not for varying the projection horizon. Splitting the components lets the dispatcher cache the fit and only re-run the cheap projection step when only `horizon` changes.

## Inputs

| Input           | Type             | Required              | Description                                                                                     |
| --------------- | ---------------- | --------------------- | ----------------------------------------------------------------------------------------------- |
| `date_column`   | column reference | ✓                     | The timestamp column. Must parse as a date.                                                     |
| `target_column` | column reference | ✓                     | The numeric column to project forward.                                                          |
| `horizon`       | integer          | optional (default 12) | How many steps to forecast. Units depend on the inferred frequency (months, weeks, days, etc.). |

The frequency is inferred from the spacing of `date_column` values — daily, weekly, monthly, quarterly. The component picks an appropriate seasonal period (12 for monthly, 7 for daily, etc.).

## Output shape

```json theme={null}
{
  "frequency": "MS",
  "horizon": 12,
  "model": "Holt-Winters (additive seasonal, period=12)",
  "seasonality_period": 12,
  "rmse": 1842.5,
  "first_history_period": "2023-01-01",
  "last_history_period": "2026-04-01",
  "last_forecast_period": "2027-04-01",
  "series": [
    { "period": "2023-01-01", "value": 12450.0, "kind": "history" },
    { "period": "2023-02-01", "value": 13200.0, "kind": "history" },
    ...
    { "period": "2026-05-01", "value": 18900.0, "lower": 17050.0, "upper": 20750.0, "kind": "forecast" },
    { "period": "2026-06-01", "value": 19200.0, "lower": 17150.0, "upper": 21250.0, "kind": "forecast" },
    ...
  ]
}
```

The `series` array combines history and forecast — `kind` flags which is which, and `lower` / `upper` (the 95% interval) are present only on forecast points. The artifact lives at `forecast.json`.

## Display

The Forecast component ships with a chart-block renderer:

* **Line chart** of history + forecast in one series, with a shaded confidence band over the forecast portion.
* **Model details** key/value block — frequency, seasonality period, RMSE.
* **Forecast table** — per-period numeric output for copy-paste.

## Filtering from chat

The full `forecast` artifact is small (history + horizon points), so chat usually reads it whole rather than filtering. Summand surfaces summary fields like `rmse`, `last_history_period`, and `last_forecast_period` for at-a-glance answers, with the full series available on demand.

## Compute profile

| Component        | Profile | Memory | Timeout |
| ---------------- | ------- | ------ | ------- |
| `forecast_model` | Lambda  | 2 GB   | 180 s   |
| `forecast`       | Lambda  | 1 GB   | 60 s    |

Both run on Lambda — Holt-Winters fits in seconds for typical historical lengths. There's no Fargate path because the cost of a refit isn't worth the parallelism.

## Use cases

* **Revenue / cost projections** — monthly forecasts with prediction intervals for budgeting.
* **Headcount / capacity planning** — extending a weekly headcount series N weeks forward.
* **Operational metrics** — daily request volume, latency, or error rate trended forward.

## Common gotchas

<AccordionGroup>
  <Accordion title="Forecast looks flat or trivial">
    Holt-Winters captures level, trend, and seasonality but **not** structural breaks or external shocks. If your series has a known regime change (e.g. major launch, pricing change), the forecast will smooth across it. Filter the source to a stable post-change window via a [view](/concepts/views), then point the experiment at the view.
  </Accordion>

  <Accordion title="Forecast confidence interval is huge">
    Wide intervals mean the model has high residual variance — the historical series isn't well-explained by level + trend + seasonal pattern. Either the data is genuinely volatile, or there's missing structure (e.g. a covariate the model can't see). Holt-Winters is univariate; if you need multivariate forecasting, that's roadmap.
  </Accordion>

  <Accordion title="Inferred frequency is wrong">
    The inference looks at the spacing of `date_column` values. If your data has gaps or irregular cadence, frequency detection can pick the wrong period. Aggregating to a regular frequency in a [view](/concepts/views) before the experiment usually fixes this.
  </Accordion>
</AccordionGroup>
