# TimesFM max_context and max_horizon Constraints: Validation Rules and Code Examples

> Understand TimesFM max_context and max_horizon constraints. Learn validation rules and see code examples for setting these parameters correctly.

- Repository: [Google Research/timesfm](https://github.com/google-research/timesfm)
- Tags: deep-dive
- Published: 2026-04-02

---

**In TimesFM, `max_context` must be a multiple of the input patch size, `max_horizon` must be a multiple of the output patch size, and their sum cannot exceed the model's hard context limit; additionally, horizons are capped by the output stride when using continuous quantile heads.**

The `max_context` and `max_horizon` parameters in the `google-research/timesfm` repository control how much historical data the model processes and how far ahead it forecasts. These values are defined in `ForecastConfig` and undergo strict validation when the model is compiled for fast inference. Understanding these constraints is essential to avoid runtime errors and ensure efficient utilization of the compiled XLA and Torch kernels.

## Patch Size and Output Stride Alignment

TimesFM validates `max_context` and `max_horizon` at compile time to ensure they align with the model's internal patch architecture.

### Rounding Up to Input Patch Multiples

According to [`src/timesfm/timesfm_2p5/timesfm_2p5_torch.py`](https://github.com/google-research/timesfm/blob/main/src/timesfm/timesfm_2p5/timesfm_2p5_torch.py) lines 68-75 and [`src/timesfm/timesfm_2p5/timesfm_2p5_flax.py`](https://github.com/google-research/timesfm/blob/main/src/timesfm/timesfm_2p5/timesfm_2p5_flax.py) lines 4-11, **`max_context`** must be a multiple of the model's spatial-patch size `p`. If you provide a value that is not divisible by `p`, the system automatically rounds it **up** to the next multiple and logs a message:

```

When compiling, max context needs to be multiple of the patch size 16.
Using max context = 1024 instead.

```

### Rounding Up to Output Patch Multiples

Similarly, **`max_horizon`** must be a multiple of the output-patch size `o`. The validation logic in [`timesfm_2p5_torch.py`](https://github.com/google-research/timesfm/blob/main/timesfm_2p5_torch.py) lines 76-83 and [`timesfm_2p5_flax.py`](https://github.com/google-research/timesfm/blob/main/timesfm_2p5_flax.py) lines 12-19 rounds non-compliant values up to the nearest multiple of `o`.

## Combined Context Limit Constraint

The most critical hard limit involves the total memory buffer size. According to [`timesfm_2p5_torch.py`](https://github.com/google-research/timesfm/blob/main/timesfm_2p5_torch.py) lines 84-89 and [`timesfm_2p5_flax.py`](https://github.com/google-research/timesfm/blob/main/timesfm_2p5_flax.py) lines 20-25:

**`max_context + max_horizon` must be ≤ `self.model.config.context_limit`**

This constraint protects the compiled kernel from exceeding its static buffer allocation. If the sum exceeds the limit, compilation raises a `ValueError`:

```python

# Raises: ValueError: Context + horizon must be less than the context limit. 15000 + 2000 > 16384.

```

## Continuous Quantile Head Restrictions

When using advanced inference modes, additional limits apply. If `use_continuous_quantile_head=True`, the **`max_horizon`** must not exceed the model's output stride `os` ([`timesfm_2p5_torch.py`](https://github.com/google-research/timesfm/blob/main/timesfm_2p5_torch.py) lines 90-93 and [`timesfm_2p5_flax.py`](https://github.com/google-research/timesfm/blob/main/timesfm_2p5_flax.py) lines 26-29). This restriction exists because the continuous quantile head relies on single-step up-sampling that only functions correctly up to that specific stride value.

## Configuration Initialization Requirements

In [`src/timesfm/configs.py`](https://github.com/google-research/timesfm/blob/main/src/timesfm/configs.py) lines 51-53, both `max_context` and `max_horizon` default to `0`. Users must explicitly set **both** fields to non-zero integers satisfying the above rules before calling `compile()`. The model raises errors if you attempt compilation with placeholder values.

## Practical Code Examples

### Setting Valid Configuration Values

```python
from timesfm.configs import ForecastConfig
from timesfm.timesfm_2p5.timesfm_2p5_torch import TimesFM2p5Torch

# Initialize model (p=16, o=4, context_limit=16384)

model = TimesFM2p5Torch(...)

cfg = ForecastConfig(
    max_context=1024,   # Multiple of 16, valid

    max_horizon=256,    # Multiple of 4, valid

    per_core_batch_size=1,
)

model.compile(cfg)  # Succeeds

```

### Observing Automatic Rounding

```python
cfg = ForecastConfig(
    max_context=1023,   # Not multiple of 16

    max_horizon=255,    # Not multiple of 4

    per_core_batch_size=1,
)

model.compile(cfg)

# Logs: Using max context = 1024 instead.

# Logs: Using max horizon = 256 instead.

print(model.forecast_config.max_context)  # 1024

print(model.forecast_config.max_horizon)  # 256

```

### Triggering Context Limit Errors

```python
cfg = ForecastConfig(
    max_context=15000,
    max_horizon=2000,   # Sum = 17000 > 16384 (context_limit)

)

# Raises ValueError with specific message about the overflow

model.compile(cfg)

```

### Using Continuous Quantile Heads

```python
cfg = ForecastConfig(
    max_context=1024,
    max_horizon=128,          # Must be ≤ model.os (e.g., 256)

    use_continuous_quantile_head=True,
)

model.compile(cfg)  # OK if horizon ≤ os

```

## Summary

- **`max_context`** must be a multiple of the input patch size `p` (rounded up automatically).
- **`max_horizon`** must be a multiple of the output patch size `o` (rounded up automatically).
- **Combined limit:** `max_context + max_horizon` must not exceed `context_limit` (hard buffer constraint).
- **Quantile head limit:** When `use_continuous_quantile_head=True`, horizon must be ≤ output stride `os`.
- **Initialization:** Both values default to `0` in `ForecastConfig` and must be set explicitly before compilation.

## Frequently Asked Questions

### What happens if max_context is not a multiple of the patch size?

The TimesFM compile method automatically rounds the value **up** to the nearest multiple of the patch size `p` and logs an informational message. The compilation proceeds with the adjusted value, provided it still satisfies the combined context limit constraint.

### What is the maximum allowed value for max_context + max_horizon?

The sum must be less than or equal to the model's `context_limit` (typically 16,384 for TimesFM 2.5 models). This limit is enforced in [`timesfm_2p5_torch.py`](https://github.com/google-research/timesfm/blob/main/timesfm_2p5_torch.py) and [`timesfm_2p5_flax.py`](https://github.com/google-research/timesfm/blob/main/timesfm_2p5_flax.py) to prevent the compiled inference kernel from exceeding its static memory allocation.

### Why does the continuous quantile head limit the horizon?

The continuous quantile head implementation relies on single-step up-sampling that only works correctly up to the model's output stride (`os`). As implemented in [`timesfm_2p5_torch.py`](https://github.com/google-research/timesfm/blob/main/timesfm_2p5_torch.py) lines 90-93, setting `use_continuous_quantile_head=True` restricts `max_horizon` to be ≤ `os` to maintain statistical validity in the quantile estimation.

### Do I need to manually round values before compilation?

No. The validation logic in both PyTorch and Flax back-ends automatically rounds `max_context` and `max_horizon` to their required multiples. However, you should verify that the rounded values do not violate the combined size limit, as automatic rounding could push the total over the `context_limit` threshold.