Skip to main content

SARIMA: A Complete Guide to Seasonal Time Series Forecasting

Learn how SARIMA extends ARIMA to handle seasonality, understand its seven parameters, and build a working model in Python from data collection through forecasting.
Jul 31, 2026  · 15 min read

Explore with AI

Open in ChatGPTOpen in ClaudeOpen in Perplexity

Every December, retailers stock up on holiday inventory. Every summer, electricity grids brace for air conditioning peaks. These patterns repeat year after year, and if you're building a time series forecast that ignores them, you're leaving accuracy on the table.

Seasonal AutoRegressive Integrated Moving Average models (SARIMA, for short) extend the widely used ARIMA framework to capture repeating seasonal patterns alongside regular trends. In this article, you'll learn what SARIMA is, how its components work, when to choose it over ARIMA, and how to build one step by step in Python.

What Is SARIMA?

SARIMA is a time series forecasting model that handles both non-seasonal and seasonal patterns in data. It builds directly on ARIMA, so if you've already worked with ARIMA, you'll recognize most of the mechanics. The key difference is that SARIMA adds a second layer of parameters specifically designed to model behavior that repeats at fixed intervals, like monthly, quarterly, or weekly cycles.

Formally, a SARIMA model is written as SARIMA(p, d, q)(P, D, Q)[S]. The first set of parameters, (p, d, q), handles the non-seasonal structure, identical to standard ARIMA. The second set, (P, D, Q)[S], accounts for seasonal patterns, where S is the length of the seasonal cycle. For monthly data with yearly seasonality, S = 12. For quarterly data, S = 4.

Key Components of SARIMA

SARIMA's seven parameters can feel like a lot at first. It helps to think of them in two groups: the familiar ARIMA trio (p, d, q) and the seasonal counterparts (P, D, Q, S) that mirror them at the seasonal scale. Each seasonal parameter does exactly what its non-seasonal twin does, just applied across seasonal gaps rather than adjacent time steps.

AutoRegressive (AR) part

The AR component uses past values of the series to predict future ones. The parameter p specifies how many lagged values to include. If p = 2, the model uses the two previous time steps as predictors for the current value.

On the seasonal side, P does the same thing but at seasonal lags. If P = 1 and S = 12, the model looks at the value from 12 periods ago, same month, prior year, as a predictor. This directly captures year-over-year patterns.

Integrated (I) part

The d parameter controls how many times the series is differenced to remove trends and make it stationary. Differencing means subtracting the previous observation from each observation, which removes a linear trend. If d = 1, you take first differences; if d = 2, you difference the already-differenced series.

Seasonal differencing works the same way but at seasonal lags. The D parameter specifies how many seasonal differences to apply. With D = 1 and S = 12, you subtract the value from 12 periods earlier from each observation. Using d = 1 and D = 1 together is common when a series has both a general upward trend and a repeating seasonal pattern.

Moving Average (MA) part

Unlike the AR component, which looks at past values, the MA component models the relationship between the current observation and residual errors from past predictions. The q parameter sets how many lagged error terms to include. If q = 1, the model uses the prediction error from the previous step to adjust its current forecast.

The seasonal counterpart Q applies this same logic at seasonal lags. With Q = 1 and S = 12, the model incorporates the forecast error from 12 periods ago. This matters when seasonal shocks, like an unusually hot summer driving energy demand, tend to persist into the same period the following year.

Seasonal component (S)

The S parameter defines the length of the seasonal cycle and ties the three seasonal parameters (P, D, Q) together. Getting S right matters: if your data is monthly with a yearly pattern, S = 12. Weekly data with a yearly cycle gives S roughly 52.

Here's where seasonality gets occasionally tricky. A year isn't exactly 52 weeks; it's closer to 52.18. For most practical purposes, rounding to S = 52 works fine. But some datasets have multiple seasonal periods: daily electricity demand often shows both a weekly cycle (S = 7) and an annual cycle (S = 365). Standard SARIMA handles one seasonal period, so multiple seasonalities require more advanced methods like TBATS or Facebook Prophet.

When S isn't obvious, time series decomposition helps. Decomposing the series into its trend, seasonal, and residual components visually surfaces the dominant repeating period. You can also inspect autocorrelation plots for spikes at regular lags.

ARIMA vs. SARIMA: What's the Difference?

Heer's what you're probably already thinking: when should you actually use SARIMA instead of the simpler ARIMA?

The short answer: use ARIMA when your data has no meaningful seasonal pattern, and SARIMA when it does.

ARIMA models three things: autocorrelation in the series itself (AR), the number of differences needed for stationarity (I), and the lingering influence of past forecast errors on the current value (MA). It handles trends, cycles, and irregular noise well. What it can't do is model patterns that repeat at a fixed seasonal frequency. Those slip through as unexplained variance.

SARIMA adds exactly that capability. When clear seasonal peaks and troughs appear in your data, fitting a plain ARIMA model forces those patterns into the residuals, resulting in worse forecasts and residuals that aren't white noise. A SARIMA model captures them directly.

A practical rule: plot your data and look for repeating patterns at a fixed interval. If you see them, holiday sales spikes, winter energy surges, quarterly earnings patterns, reach for SARIMA. If the series is irregular or trend-driven without a regular cycle, ARIMA is simpler and sufficient.

Our ARIMA Models in Python course covers both frameworks with hands-on exercises to sharpen your intuition for when each applies.

How to Build a SARIMA Model in Python

Building a SARIMA model follows a logical sequence: collect data, check stationarity, identify parameters, fit the model, run diagnostics, and forecast. Here's how each step works in practice, using Python's statsmodels library.

Data collection

For a model that captures seasonality, you need enough history to observe the pattern at least twice, ideally several cycles. Monthly retail sales, temperature records, energy consumption figures, and passenger traffic counts are classic examples. Publicly available sources like the Federal Reserve Economic Data (FRED), the US Census Bureau, or Kaggle are good starting points.

The standard teaching dataset for this workflow is airline passenger counts: monthly data from 1949 to 1960 with a clear upward trend and strong annual seasonality. It is available through statsmodels via get_rdataset(), which fetches it from the Rdatasets collection. Learn the workflow on this dataset before applying it to your own data.

Data preprocessing

Before fitting any SARIMA model, you need a stationary series, one where the mean and variance don't change over time. The Augmented Dickey-Fuller (ADF) test checks this formally: a p-value below 0.05 suggests the series is stationary.

If it isn't, differencing fixes it. Apply regular differencing (d = 1) for trend, seasonal differencing (D = 1 at lag S) for seasonal nonstationarity, or both if needed. Handle missing values before this step. Forward fill or interpolation are standard approaches for time series data, since dropping rows breaks the temporal structure.

Model identification

With a stationary series in hand, you use the Autocorrelation Function (ACF) and Partial Autocorrelation Function (PACF) plots to identify the model parameters. Here's what to look for:

  • ACF shows the correlation between the series and its lags. A sharp cutoff after lag q suggests the MA order. Spikes at seasonal lags (12, 24, 36 for monthly data) inform Q.
  • PACF shows partial correlations with intermediate lag effects removed. A sharp cutoff after lag p suggests the AR order. Seasonal spikes inform P.

In practice, the plots give you candidate values, and you compare a handful of models using information criteria (more on this in diagnostics). If you'd rather automate the search, auto_arima() from the pmdarima package does a grid search over parameter combinations and selects the best-fitting model.

Parameter estimation

Once you've identified candidate parameters, statsmodels estimates them using Maximum Likelihood Estimation (MLE), finding the coefficient values that make the observed data most probable under the model. SARIMA estimation is more computationally intensive than plain ARIMA because the optimizer has to fit both non-seasonal and seasonal components simultaneously.

The fitting process can occasionally converge to a local optimum rather than the global one, so it's worth trying a few different starting values or parameter combinations when results look off.

Model fitting

Here's how to fit a SARIMA model in Python using the airline passenger dataset:

import pandas as pd
import statsmodels.api as sm

# Load the classic airline dataset
airline_data = sm.datasets.get_rdataset("AirPassengers", "datasets").data
airline_data.index = pd.date_range(start="1949-01", periods=len(airline_data), freq="MS")
passengers = airline_data["value"]

# Fit SARIMA(1,1,1)(1,1,1)[12]
sarima_model = sm.tsa.statespace.SARIMAX(
    passengers,
    order=(1, 1, 1),
    seasonal_order=(1, 1, 1, 12),
    enforce_stationarity=False,
    enforce_invertibility=False
)

sarima_result = sarima_model.fit(disp=False)
print(sarima_result.summary())	

The order argument takes (p, d, q) for the non-seasonal part; seasonal_order takes (P, D, Q, S). Setting enforce_stationarity=False and enforce_invertibility=False gives the optimizer more flexibility, which often helps convergence on real-world data.

Model statistics and diagnostics

After fitting, run the built-in diagnostic plots with sarima_result.plot_diagnostics(). You're looking for four things:

  • Standardized residuals: Should look like white noise with no obvious patterns.
  • Histogram of residuals: Should be roughly normal.
  • Normal Q-Q plot: Points should fall close to the diagonal line.
  • Correlogram (ACF of residuals): No significant spikes, which would indicate unexplained autocorrelation.

Pay particular attention to seasonal lags in the correlogram. Spikes at lags 12, 24, and so on suggest the seasonal component isn't fully captured. Compare alternative specifications using AIC (Akaike Information Criterion) and BIC (Bayesian Information Criterion): lower values indicate better fit, with BIC penalizing complexity more heavily.

Forecasting

With a validated model, generating forecasts is straightforward. Split your data into training and test sets to get an honest read on forecast accuracy:

# Train on first 11 years, test on final year
train = passengers[:"1959"]
test = passengers["1960":]

# Refit on training data and forecast
sarima_train = sm.tsa.statespace.SARIMAX(
    train,
    order=(1, 1, 1),
    seasonal_order=(1, 1, 1, 12),
    enforce_stationarity=False,   # add this
    enforce_invertibility=False   # add this
).fit(disp=False)

forecast = sarima_train.get_forecast(steps=12)
forecast_mean = forecast.predicted_mean
conf_int = forecast.conf_int()

The get_forecast() method returns point predictions along with confidence intervals that widen as you forecast further out. That widening isn't a flaw; it's the model being honest about uncertainty. Evaluate accuracy using RMSE (Root Mean Squared Error) or MAPE (Mean Absolute Percentage Error) on the held-out test set.

Practical Applications of SARIMA

So many real-world signals are seasonal that SARIMA earns a permanent spot in any time series toolkit. A few examples across industries:

  • Retail: Forecasting monthly sales volumes for inventory planning, especially around holiday periods where demand spikes are predictable but vary in magnitude year over year.
  • Energy consumption: Predicting electricity and gas demand, which follows both daily and annual seasonal cycles driven by temperature and activity patterns.
  • Finance: Modeling quarterly earnings or trading volume patterns that repeat with fiscal calendars.
  • Weather forecasting: Projecting temperature, precipitation, and other climate variables that follow strong annual cycles.

In each case, the repeating structure is the signal, and SARIMA is built to capture it.

Limitations of SARIMA

Knowing where a tool works well is only half the picture. SARIMA is a solid baseline for seasonal time series, but knowing its limits is what separates people who use models well from those who use them blindly.

It handles exactly one seasonal period. If your data has multiple seasonalities, daily, weekly, and annual patterns layered on top of each other, SARIMA won't model all of them at once. Methods like TBATS, Prophet, or LSTM networks handle multiple seasonal frequencies more naturally.

SARIMA also assumes linearity. It models linear relationships between past values, past errors, and future observations. Nonlinear dynamics, common in financial time series or chaotic systems, require different tools. And like ARIMA, SARIMA relies solely on the history of the series itself. If you have external drivers affecting your forecasts, promotions, weather events, economic indicators, look at SARIMAX, which adds exogenous variables to the SARIMA framework.

Finally, parameter selection can be genuinely difficult. With seven parameters to tune, the search space is large, and fitting can be slow on long series. auto_arima() from pmdarima helps automate this. But there's no shortcut around understanding what the parameters actually mean, which is why we covered the components before touching any code.

Conclusion

I've always thought SARIMA gets undersold in introductory forecasting courses. It's taught as "ARIMA, but with seasonal stuff," which makes it sound like a minor extension. It isn't. The seasonal parameters aren't tacked on; they're doing real structural work, capturing a layer of your data's behavior that ARIMA simply can't reach.

What makes SARIMA click in practice is realizing the non-seasonal and seasonal components aren't separate models running in parallel. They interact. The AR and MA terms work alongside their seasonal twins, each handling a different timescale of autocorrelation. Once that clicks, reading ACF and PACF plots stops feeling like pattern matching and starts feeling like actually understanding your data.

If you're working with monthly, quarterly, or any regularly cycled data, SARIMA is the right starting point, not because it's always the final answer, but because it forces you to think clearly about the structure of your series. From there, SARIMAX adds external predictors, and methods like TBATS or Prophet handle the messier multi-seasonal cases. Our Time Series Forecasting Tutorial and ARIMA Models in Python course are both good next steps.

SARIMA FAQs

What does SARIMA stand for?

SARIMA stands for Seasonal AutoRegressive Integrated Moving Average. It extends the standard ARIMA model by adding seasonal parameters—(P, D, Q) and the seasonal period S—that capture repeating patterns in time series data, such as monthly or quarterly cycles.

What is the difference between ARIMA and SARIMA?

ARIMA models non-seasonal patterns: trend, autocorrelation, and moving average effects. SARIMA adds a second layer of parameters (P, D, Q, S) that model the same effects at seasonal lags. If your data shows repeating patterns at a fixed interval—like higher sales every December—SARIMA captures those directly, while ARIMA leaves them as unexplained residual variance.

How do I choose the right SARIMA parameters?

Start by checking whether your series is stationary using the Augmented Dickey-Fuller test. Then inspect ACF and PACF plots: the non-seasonal AR (p) and MA (q) orders come from the pattern of cutoffs at non-seasonal lags, while the seasonal orders P and Q come from spikes at seasonal lags. You can also use auto_arima() from the pmdarima package to search over parameter combinations automatically, using AIC or BIC to select the best model.

How do I determine the seasonal period S for my SARIMA model?

The seasonal period S reflects how often the pattern repeats. For monthly data with annual seasonality, S = 12. For quarterly data, S = 4. For weekly data, S = 52 (or 52.18 rounded). If the period isn't obvious, use time series decomposition or inspect the ACF plot for regularly spaced spikes—those spikes reveal the dominant seasonal frequency.

Can SARIMA handle multiple seasonal periods?

Standard SARIMA handles one seasonal period at a time. If your data has multiple layered seasonalities—like daily electricity demand with both weekly and annual cycles—you'll need alternatives like TBATS, Facebook Prophet, or LSTM networks, which are designed to model multiple overlapping seasonal structures simultaneously.

What Python library is best for fitting SARIMA models?

Python's statsmodels library is the standard choice, offering SARIMAX() (which is flexible enough to fit SARIMA models without exogenous variables). For automated parameter selection, the pmdarima library's auto_arima() function performs a grid search and is worth adding to your workflow when you're not sure where to start with parameter values.

How do I evaluate whether my SARIMA model is a good fit?

After fitting, run plot_diagnostics() on the result object and check that residuals look like white noise with no structure—particularly no spikes at seasonal lags in the ACF. Compare competing model specifications using AIC or BIC (lower is better). For forecasting accuracy on held-out data, RMSE and MAPE are the most common metrics.

What is SARIMAX, and when should I use it instead of SARIMA?

SARIMAX adds exogenous variables—external predictors—to the SARIMA framework. Use it when you have measurable factors that influence your series beyond its own history: promotional spend affecting retail sales, temperature affecting energy demand, or macroeconomic indicators affecting quarterly revenue. If your only data is the series itself, SARIMA is sufficient; once you have relevant external drivers, SARIMAX lets you incorporate them directly.

Topics
Related

blog

AI Time Series Forecasting: A Beginners' Guide

Learn how AI is transforming time series forecasting through adaptability, uncovering hidden patterns, and handling multiple variables.
Stanislav Karzhev's photo

Stanislav Karzhev

8 min

Tutorial

ARIMA for Time Series Forecasting: A Complete Guide

Learn the key components of the ARIMA model, how to build and optimize it for accurate forecasts in Python, and explore its applications across industries.
Zaina Saadeddin's photo

Zaina Saadeddin

Tutorial

Time Series Forecasting Tutorial

A detailed guide to time series forecasting. Learn to use python and supporting frameworks. Learn about the statistical modelling involved.
Moez Ali's photo

Moez Ali

Tutorial

Time Series Analysis using R: Tutorial

Learn Time Series Analysis with R along with using a package in R for forecasting to fit the real-time series to match the optimal model.

Salin Kc

Tutorial

Facebook Prophet: A Modern Approach to Time Series Forecasting

Understand how Facebook Prophet models trends, seasonality, and special events for accurate and interpretable forecasts.
Vidhi Chugh's photo

Vidhi Chugh

Tutorial

Time Series Decomposition: Understand Trends, Seasonality, and Noise

Learn how to break down time series data into meaningful components like trend, seasonality, and residuals using additive and multiplicative models. Learn about both classical and STL methods. Explore seasonal adjustments and practice forecasting with decomposition models.
Josef Waples's photo

Josef Waples

See MoreSee More