ds@mcpanalytics.aiEmail your data and your question and get an answer about your own data, with the method shown.Email your data and question. Get an answer.

ARIMA vs Prophet: Which Forecasting Method for Your Business?

By MCP Analytics Team | Published , updated

By MCP Analytics Team | | Updated | 12 min read

If you're forecasting revenue, demand, or any business metric over time, you'll encounter two methods repeatedly: ARIMA and Prophet. They're two widely used time series forecasting approaches, and they work in fundamentally different ways.

ARIMA has been the default choice for decades: a statistical workhorse with strong theoretical foundations. Prophet, released by Facebook (now Meta) in 2017, was designed specifically for business data with the kinds of patterns (holidays, missing data, trend shifts) that make ARIMA difficult to configure. Both are legitimate. Neither is universally better. The right choice depends on your data, your goals, and how much manual tuning you're willing to do.

How ARIMA Works (Without the Math)

ARIMA stands for AutoRegressive Integrated Moving Average. In plain language, it works by finding patterns in how your data relates to its own past values.

To see where your own measure is heading, with a likely range, try the free forecasting tool.

Think of it this way: today's revenue is partly explained by yesterday's revenue, the day before, the day before that, and so on. ARIMA quantifies exactly how much each past day matters and uses those relationships to project forward. It also accounts for the "momentum" of recent changes, if revenue has been trending up, that momentum carries into the forecast.

The "Integrated" part means ARIMA can handle data that's trending up or down by first differencing the series (looking at changes rather than levels), which makes the pattern stationary: a technical requirement for the model to work properly.

ARIMA's Strengths

ARIMA's Limitations

How Prophet Works (Without the Math)

Prophet takes a completely different approach. Instead of modeling the autocorrelation structure, it decomposes the time series into three additive (or multiplicative) components:

  1. Trend: The long-term direction, modeled as a piecewise linear or logistic growth curve with automatic changepoint detection
  2. Seasonality: Repeating patterns at weekly and annual frequencies, modeled with Fourier series
  3. Holidays: User-specified point events with estimated individual effects

The forecast is the sum of these components. Each is interpretable on its own. You can see exactly how much of the forecast comes from trend vs. seasonality vs. holiday effects.

Prophet's Strengths

Prophet's Limitations

Side-by-Side Comparison

Factor ARIMA Prophet
Approach Autocorrelation modeling Decomposition (trend + season + holidays)
Seasonality Seasonal ARIMA (SARIMA) with fixed period Multiple seasonal periods via Fourier terms
Holidays External regressors (manual setup) Native holiday effects (specify dates)
Trend changes Not detected (averages entire history) Automatic changepoint detection
Missing data Equal spacing; gaps often filled first Handles natively
Interpretability Technical (ACF/PACF, coefficients) Intuitive (component plots)
Accuracy by horizon Won every horizon on our clean CO2 test Won every horizon on our messy sales test (with holiday list)
Data requirements Enough history to estimate the model; if the data is seasonal, several full seasonal cycles (a rule of thumb, not a fixed minimum) Runs on short series; with default settings it only fits a yearly pattern when the history spans at least 730 days (see the Prophet source code, listed below)
Tuning required Moderate (auto-ARIMA helps) Low (defaults are meant to work; check them)

A Test You Can Re-Run: ARIMA vs Prophet on Real and Simulated Data

Claims about which model wins are easy to make and hard to check. So we ran both models ourselves, on two series, and we show the code. Run it and you should get the same numbers. The software was Python 3.12 with statsmodels 0.15.0 and Prophet 1.5.0. We scored each model by mean absolute error (MAE): the average size of the miss, in the same units as the data. Lower is better.

Test 1: A clean, real series (CO2 in the air)

The data is the monthly average of atmospheric CO2 measured at Mauna Loa, Hawaii, from March 1958 to December 2001 (526 months). It ships with the statsmodels package, so anyone can load it. It is very regular: a steady climb plus a strong yearly cycle, with no holidays and few gaps. We forecast 12 months ahead from six different starting points (January of each year from 1996 to 2001). Each time the models only saw data before the starting point. ARIMA here is a seasonal ARIMA(1,1,1)(0,1,1,12). We did not search for better settings. Prophet used its defaults, with the weekly and daily cycles switched off because the data is monthly.

import logging, warnings
import pandas as pd, numpy as np
import statsmodels.api as sm
from statsmodels.tsa.statespace.sarimax import SARIMAX
from prophet import Prophet
warnings.filterwarnings("ignore"); logging.getLogger("cmdstanpy").setLevel(logging.ERROR)
co2 = sm.datasets.co2.load_pandas().data["co2"].interpolate().resample("MS").mean()
print(len(co2), co2.index[0].date(), co2.index[-1].date())
H = 12
cuts = list(range(len(co2) - H - 60, len(co2) - H + 1, 12))   # 6 forecast origins, 12 months apart
err = {"ARIMA": {1: [], 3: [], 12: []}, "Prophet": {1: [], 3: [], 12: []}}
for c in cuts:
    train, test = co2.iloc[:c], co2.iloc[c:c + H]
    a = SARIMAX(train, order=(1, 1, 1), seasonal_order=(0, 1, 1, 12)).fit(disp=False).forecast(H)
    df = pd.DataFrame({"ds": train.index, "y": train.values})
    m = Prophet(weekly_seasonality=False, daily_seasonality=False).fit(df)
    p = m.predict(pd.DataFrame({"ds": test.index}))["yhat"].values
    for h in (1, 3, 12):
        err["ARIMA"][h].append(np.abs(a.values[:h] - test.values[:h]).mean())
        err["Prophet"][h].append(np.abs(p[:h] - test.values[:h]).mean())
for k in err:
    print(k, {h: round(float(np.mean(v)), 2) for h, v in err[k].items()})
print("origins", len(cuts), [co2.index[c].date().isoformat() for c in cuts])

Result when we ran it: average miss, in ppm of CO2, over the six starting points.

HorizonARIMA (MAE)Prophet (MAE)
1 month ahead0.230.91
3 months ahead0.330.88
12 months ahead0.460.86

On this series ARIMA won at every horizon, including the 12-month one. That is the kind of data we said ARIMA likes: clean, regular, one dominant pattern. It also shows that "Prophet is better for long horizons" is not a rule. Here the gap was smaller at 12 months (0.46 vs 0.86) than at 1 month, but ARIMA still led.

Test 2: Messy daily sales with holidays and gaps (simulated)

This series is made up on purpose, so we know what is hiding in it. It has three years of daily sales (2022 to 2024). It has a weekly cycle, a trend that speeds up in late 2023, four one-day spikes a year, and random noise. We then deleted a random 10% of the training days (100 of 1,004) to mimic missing data. We forecast the last 92 days of 2024. For ARIMA we filled the gaps by straight-line interpolation first. We tried ARIMA with and without a holiday column, and Prophet with and without a holiday list.

import logging, warnings
import pandas as pd, numpy as np
from statsmodels.tsa.statespace.sarimax import SARIMAX
from prophet import Prophet
warnings.filterwarnings("ignore"); logging.getLogger("cmdstanpy").setLevel(logging.ERROR)
rng = np.random.default_rng(42)
idx = pd.date_range("2022-01-01", "2024-12-31", freq="D")
t = np.arange(len(idx))
weekly = np.array([0, 2, 3, 4, 8, 14, 10])[idx.dayofweek]
trend = 100 + 0.05 * t + np.where(t > 700, 0.15 * (t - 700), 0)      # growth speeds up on day 700
hol = idx.strftime("%m-%d").isin(["02-14", "05-12", "11-28", "12-20"])
y = trend + weekly + 40 * hol + rng.normal(0, 3, len(idx))
s = pd.Series(y, idx)
holdout_start = "2024-10-01"                                           # forecast Oct-Dec 2024 (92 days)
train = s[:holdout_start].iloc[:-1].copy(); test = s[holdout_start:]
miss = rng.random(len(train)) < 0.10                                    # 10% of training days missing
train_gappy = train.mask(miss)
print("missing days:", int(miss.sum()), "of", len(train))
H = len(test)
def mae(f, h): return float(np.abs(np.asarray(f)[:h] - test.values[:h]).mean())
ex_all = pd.Series(hol.astype(float), idx)
res = {}
filled = train_gappy.interpolate()
a = SARIMAX(filled, order=(1, 1, 1), seasonal_order=(1, 0, 1, 7)).fit(disp=False).forecast(H)
ax = SARIMAX(filled, exog=ex_all[train.index], order=(1, 1, 1), seasonal_order=(1, 0, 1, 7)).fit(disp=False).forecast(H, exog=ex_all[test.index])
df = pd.DataFrame({"ds": train_gappy.dropna().index, "y": train_gappy.dropna().values})
hd = pd.DataFrame({"holiday": "promo", "ds": idx[hol]})
p = Prophet(holidays=hd, daily_seasonality=False, yearly_seasonality=False).fit(df).predict(pd.DataFrame({"ds": test.index}))["yhat"].values
p0 = Prophet(daily_seasonality=False, yearly_seasonality=False).fit(df).predict(pd.DataFrame({"ds": test.index}))["yhat"].values
print("test holidays in window:", int(hol[idx >= holdout_start].sum()), "train holidays:", int(hol[:len(train)].sum()))
for name, f in [("ARIMA no holiday", a.values), ("ARIMA + holiday regressor", ax.values), ("Prophet no holiday", p0), ("Prophet + holidays", p)]:
    print(name, {h: round(mae(f, h), 2) for h in (7, 30, 92)})

Result when we ran it: MAE in sales units, by forecast length.

Model7 days30 days92 days
ARIMA, no holiday input1.662.273.20
ARIMA + holiday column1.702.352.41
Prophet, no holiday list1.592.103.01
Prophet + holiday list1.462.012.15

Here Prophet with its holiday list had the lowest error at all three lengths. The 92-day window held two of the spike days (November 28 and December 20), so the holiday inputs mattered most there: ARIMA fell from 3.20 to 2.41 once we gave it a holiday column, and Prophet fell from 3.01 to 2.15. Over 7 days there were no spike days in the window, and the four models landed within 0.24 of each other.

What these two tests do and do not show

How to run your own comparison

  1. Hold back the most recent stretch of your data, as long as the forecast you need (for example 30 days).
  2. Fit both models on everything before it.
  3. Compare the forecasts to what really happened, using MAE or a similar score.
  4. Repeat from a few earlier starting points, as Test 1 does, so one lucky window does not decide it. This is called rolling-origin evaluation. See Hyndman and Athanasopoulos, listed below.

When to Choose ARIMA

When to Choose Prophet

The Practical Answer

For business data with holidays, gaps and trend changes (revenue, sales, demand, traffic), Prophet is an easy place to start. It takes holidays and gaps with little setup. For clean, regular data without holiday effects, try ARIMA first: it won every horizon in our CO2 test. In both our tests the winner depended on the data, so hold back your last stretch of data, fit both, and compare the errors. Forecasts that disagree show real uncertainty in your data.

MCP Analytics runs both. Upload your time series data and run ARIMA or Prophet forecasting, or both. No coding needed: each report gives the forecast with a likely range. Compare the outputs and choose the forecast that best captures your data's behavior.

Working on this for your business? See the time series forecasting tool.

Sources

Tests run November 2, 2026 by the MCP Analytics Team. Page firstand revised November 2, 2026. About bylines: see our authors page.

Your turn

Bring your own data and the question you actually need answered.

MCP AnalyticsData science by email Send us your data and your question, and we will reply. ds@mcpanalytics.ai

Frequently Asked Questions

Is Prophet more accurate than ARIMA?

Neither is universally more accurate. In our two tests above, ARIMA won on a clean real series and Prophet won on a messy simulated series with holidays and gaps. Two tests are not a ranking. The result depends on your data, so hold back your last stretch of data, fit both, and compare the errors.

Can I use both ARIMA and Prophet on the same data?

Yes, and it's often a good idea. Running both lets you compare forecasts. If they agree closely, you have more confidence. If they diverge significantly, it highlights uncertainty that a single method might hide. MCP Analytics can run both on the same file, so you can compare the two forecasts.

Do I need to understand the math to use ARIMA or Prophet?

No. Upload your time series data and MCP Analytics fits the model and returns a forecast with a likely range and a written reading of it. Understanding the general concepts helps you interpret results.

Which method handles holidays and special events better?

Prophet was specifically designed for holiday effects. Specify holiday dates and Prophet estimates their individual impact. ARIMA can handle holidays through external regressors, but this requires manual specification. For data with significant holiday impacts, Prophet is the easier one to set up. In our simulated test it also scored best, but ARIMA with a holiday column closed most of the gap.

← Revenue Forecasting · Time Series Forecasting · CSV Analysis