Skip to content

Logistic growth benchmarks ​

58 of 58 cases match Python Prophet.

Each case runs the same input through Effect Prophet and Python Prophet 1.4.0, then compares every forecast row, the trend, each component and the fitted noise. A case matches when all of them agree within its tolerances, and only matching cases are timed.

Each case's dot shows its result: matches, matches with internal differences flagged, intentional difference, doesn't match. Hover over a dot for details.

How to read the tables:

  • Effect output and Python output are each library's final forecast value. Open a case to see every row side by side.
  • Largest difference is the biggest gap between the two forecasts, as a share of the input data's range.
  • Effect time and Python time are the median time for the timed step, usually fitting and predicting. Open a case for every step, including first-run and save/load times.
  • A timed step marked different work calls public operations that produce different outputs in the two libraries, so its times aren't a speed comparison. The case page explains the difference.
  • Flagged cases match, but the two libraries stopped their fitting search at slightly different points. The case page shows the internal numbers.
About this run
  • Run 2026-11-07T184211-397Z-3a5a6cec on 2026-11-07, commit 3a5a6ce
  • Both libraries ran in linux/arm64 containers on Apple M4 Pro
  • effect-prophet 0.0.0
  • effect 4.0.6
  • prophet 1.4.0
  • Full benchmark report

Timings come from one machine and describe this workload only. They are not a general speed ranking. Where Python is faster, it is often because Python runs Stan's optimizer as compiled C++, while Effect Prophet runs the same algorithm as WebAssembly with narrower vector instructions. The gap is widest for Newton's method on short histories with many parameters.

Country holiday calendars ​

Pinned country calendars, matching explicit-event controls, dynamic future years and portable saved models. Known-gap opt-in is partial provider output, not a completeness guarantee.

CaseInputEffect outputPython outputLargest differenceTimed stepEffect timePython time
US holidays, additive96 rows80.572780.5727< 0.0001%Fit and predict31.4 ms60.2 ms
Explicit US control, additive96 rows80.572780.5727< 0.0001%Fit and predict30.9 ms57.1 ms
US holidays, multiplicative96 rows86.008586.0085< 0.0001%Fit and predict43.4 ms66.5 ms
Explicit US control, multiplicative96 rows86.008586.0085< 0.0001%Fit and predict43.1 ms65.5 ms

Default settings ​

fit(history, { growth: "logistic" }) against Prophet(growth="logistic").fit(df) with nothing else set. Each library decides on its own which seasonal patterns, changepoints and optimizer to use. Warm-start cases fit the first rows, then refit the whole history from the parameters of that fit, as when new data arrives.

CaseInputEffect outputPython outputLargest differenceTimed stepEffect timePython time
Defaults, three months of daily data96 rows105.2798105.2798< 0.0001%Fit102 ms121 ms
Defaults, eight months of daily data256 rows113.0552113.05520.0012%Fit39.0 ms38.7 ms
Defaults, a year with changing growth365 rows193.9557193.95230.0086%Fit134 ms112 ms
Refit after a week of new data365 rows193.9774193.98530.039%Refit from an earlier fit117 ms94.2 ms

Growth curves and changepoints ​

An S-shaped curve rising toward a slowly changing ceiling, with no changepoints, one hand-picked changepoint or automatic ones, under both target scalings. Three cases sit either side of 100 rows, where both libraries switch from Newton to L-BFGS.

CaseInputEffect outputPython outputLargest differenceTimed stepEffect timePython time
No changepoints, absmax scaling96 rows105.2742105.2742< 0.0001%Fit6.87 ms13.3 ms
One hand-picked changepoint, absmax scaling96 rows105.2754105.2754< 0.0001%Fit7.91 ms15.4 ms
Three automatic changepoints, absmax scaling96 rows105.2760105.2760< 0.0001%Fit19.1 ms27.1 ms
No changepoints, minmax scaling96 rows106.7569106.7569< 0.0001%Fit8.53 ms15.7 ms
One hand-picked changepoint, minmax scaling96 rows105.7871105.7871< 0.0001%Fit17.0 ms25.5 ms
Three automatic changepoints, minmax scaling96 rows105.5809105.5809< 0.0001%Fit9.31 ms17.2 ms
No changepoints, loose prior, absmax scaling96 rows99.666699.6666< 0.0001%Fit118 ms128 ms
No changepoints, loose prior, minmax scaling96 rows93.116893.1168< 0.0001%Fit15.0 ms20.4 ms
99 rows: just under the optimizer switch99 rows105.3754105.3754< 0.0001%Fit17.2 ms24.3 ms
100 rows: just over the optimizer switch100 rows105.4111105.4111< 0.0001%Fit1.83 ms5.85 ms
Eight months of daily data256 rows113.6759113.6759< 0.0001%Fit2.95 ms7.03 ms
Weekly pattern, absmax scaling96 rows71.778671.7786< 0.0001%Fit and predict18.9 ms32.0 ms
Weekly pattern, minmax scaling96 rows71.906071.9060< 0.0001%Fit and predict20.3 ms35.9 ms
Weekly pattern, automatic changepoints96 rows71.900071.9000< 0.0001%Fit and predict19.4 ms32.6 ms
Weekly pattern, eight months256 rows98.080498.0804< 0.0001%Fit and predict4.70 ms13.0 ms

Floors and ceilings ​

Histories with an explicit floor as well as a ceiling, both changing over time. Values are measured from the floor, as in Prophet.

CaseInputEffect outputPython outputLargest differenceTimed stepEffect timePython time
Explicit floor, absmax scaling96 rows105.8329105.8329< 0.0001%Fit6.51 ms13.5 ms
Explicit floor, minmax scaling96 rows105.8329105.8329< 0.0001%Fit10.1 ms15.9 ms
Explicit floor with a regressor, absmax scaling96 rows72.219072.2190< 0.0001%Fit and predict20.9 ms36.5 ms
Explicit floor with a regressor, minmax scaling96 rows72.219072.2190< 0.0001%Fit and predict17.4 ms32.2 ms

Seasonality, events and regressors ​

Each supported effect on its own, then all of them together: a weekly pattern, a switchable weekly pattern, an event with a window, and additive and multiplicative regressors.

CaseInputEffect outputPython outputLargest differenceTimed stepEffect timePython time
Weekly pattern96 rows105.2764105.2764< 0.0001%Fit15.0 ms25.0 ms
Switchable weekly pattern96 rows105.2763105.2763< 0.0001%Fit17.1 ms27.1 ms
Event with a window96 rows105.2751105.2751< 0.0001%Fit9.53 ms18.5 ms
Additive regressor96 rows105.2753105.2753< 0.0001%Fit8.10 ms14.5 ms
Multiplicative regressor96 rows105.2751105.2751< 0.0001%Fit10.1 ms16.7 ms
Everything at once, absmax scaling96 rows105.8453105.8453< 0.0001%Fit28.2 ms42.9 ms
Everything at once, minmax scaling96 rows105.8453105.8453< 0.0001%Fit26.2 ms39.3 ms

Unusual data ​

Shuffled rows, repeated dates, a falling curve, a curve pinned at its ceiling, a perfectly constant series and values outside the bounds.

CaseInputEffect outputPython outputLargest differenceTimed stepEffect timePython time
Shuffled rows96 rows105.2754105.2754< 0.0001%Fit7.71 ms14.6 ms
Repeated dates96 rows103.2373103.2373< 0.0001%Fit5.85 ms13.0 ms
Falling curve96 rows4.24794.2479< 0.0001%Fit6.38 ms13.1 ms
Pinned at the ceiling96 rows109.5200109.5200< 0.0001%Fit10.5 ms18.3 ms
Perfectly constant96 rows49.930149.93017.9e-12Fit16.4 ms24.9 ms
Values outside the bounds96 rows106.0168106.0168< 0.0001%Fit8.97 ms16.2 ms

Uncertainty ranges ​

Both libraries simulate possible futures with random draws, so individual simulated values never match. Each range must still match Python's within the variation expected from that many draws. Anomaly cases also check that both libraries flag the outliers in a history.

CaseInputEffect outputPython outputLargest differenceTimed stepEffect timePython time
Anomalies in a history365 rows157.6301157.62720.073%Fit and find anomalies71.6 ms298 ms
Defaults, ranges with changing growth365 rows193.9557193.95230.0086%Simulate uncertainty (different work)23.3 ms293 ms
Defaults, ranges with changing growth, second seed365 rows193.9557193.95230.0086%Simulate uncertainty (different work)23.5 ms298 ms
Samples, weekly pattern96 rows71.906071.9060< 0.0001%Simulate uncertainty (different work)1.22 ms80.4 ms
Ranges, eight months256 rows98.080498.0804< 0.0001%Simulate uncertainty (different work)1.55 ms25.9 ms
Ranges with an explicit floor96 rows72.219072.2190< 0.0001%Simulate uncertainty (different work)1.01 ms92.3 ms
Samples with an explicit floor96 rows72.219072.2190< 0.0001%Simulate uncertainty (different work)733 µs24.1 ms
Ranges with mixed effects96 rows72.227072.2270< 0.0001%Simulate uncertainty (different work)760 µs30.3 ms
Samples with mixed effects96 rows72.227072.2270< 0.0001%Simulate uncertainty (different work)759 µs25.1 ms

Full Bayesian fitting ​

fit(history, { mcmc: { samples, seed } }) against Prophet(mcmc_samples=...) and fit(df, seed=...): both run Stan's NUTS sampler with the same settings. Their chains can't match draw for draw, so each forecast, component and coefficient, a posterior mean, must agree within 0.15 of the narrowest 80% range, and each range bound within the variation expected from that many posterior draws. Divergences and R-hat are reported, and flagged when Effect's chains mix clearly worse than Python's.

CaseInputEffect outputPython outputLargest differenceTimed stepEffect timePython time
Capacity, floor and a multiplicative regressor96 rows72.218972.21880.0091%Simulate uncertainty (different work)2.91 ms210 ms
A year of changing growth rates365 rows193.9262193.94050.027%Simulate uncertainty (different work)38.4 ms356 ms

Cross-validation and choosing settings ​

Rolling-origin cross-validation, metrics, baselines, settings search and a final holdout check on logistic models.

CaseInputEffect outputPython outputLargest differenceTimed stepEffect timePython time
Cross-validation and metrics96 rows59.134559.1345< 0.0001%Cross-validate (different work)17.1 ms59.5 ms
Cross-validation with ranges96 rows59.134559.1345< 0.0001%Cross-validate with ranges (different work)18.1 ms64.1 ms
Choosing settings and a final holdout96 rows59.134559.1345< 0.0001%Search settings (different work)35.5 ms115 ms
Cross-validation, eight months256 rows88.536788.52140.034%Cross-validate (different work)14.1 ms41.5 ms
Cross-validation with ranges, eight months256 rows88.536788.52140.034%Cross-validate with ranges (different work)15.1 ms56.4 ms
Twelve folds and a search, sequential and parallel256 rows90.783090.78740.079%Cross-validate (different work)61.3 ms170 ms
Monthly, custom and scaled metrics256 rows90.924190.92280.20%———

Inspired by Prophet from Meta. Not affiliated with Meta.