uber/orbit: Bayesian forecasting in Python with a fit-predict interface
A Python package for Bayesian forecasting with object-oriented design and probabilistic models under the hood.
At a glance
- What is it?
- Orbit wraps Stan and Pyro behind an initialize-fit-predict API for exponential smoothing, local trend models and kernel regression. It is a good fit when you need posterior intervals on a forecast, and a poor fit when you want a fast point forecast on a laptop.
- Who is it for?
- Adopt Orbit when you need a posterior distribution over a forecast and can accept a Stan toolchain and a compile step. Do not adopt it for high-frequency point forecasting where a least-squares model would finish before Orbit has drawn its first sample.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 130 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What Orbit solves, and who it is actually for
Most Python forecasting libraries return a single number per future period. Orbit returns a distribution. The package describes itself as being for Bayesian time series forecasting and inference, and its models are estimated by sampling rather than by closed-form least squares. That distinction drives everything else about it.
The intended user is someone who has to attach uncertainty to a forecast, not just produce one. Demand planners reconciling a range with a procurement commitment, analysts writing a nowcast where the credible interval is the deliverable, and researchers who want to inspect posterior draws directly rather than trust a point estimate. The README's quick start uses an insurance claims dataset with weekly seasonality of 52, which is a fair picture of the target workload: a few thousand observations, a handful of regressors, a forecast horizon of tens of periods.
It is not aimed at the person who wants to call one function and get a number. The object-oriented design is deliberate: you construct a model object with column names and structural settings, fit it, then predict. That object then holds the posterior, which you can hand to ArviZ. If you never look at the posterior, you are paying the sampling cost for nothing.
How the sampling actually gets done: Stan, Pyro and CmdStan
Orbit does not implement its own inference engine. The disclaimer in the README states that the project requires cmdstanpy as one of the core dependencies for Bayesian sampling, and the dependency list in pyproject.toml pins cmdstanpy>=1.2.1 alongside pyro-ppl>=1.4.0 and torch>=2.5.0. Those two stacks correspond to the two estimation paths.
The Stan path is the default for the concrete model classes. The repository ships model source under orbit/stan, and setup.py declares the model names it expects to find there: dlt, ets, lgt and ktrlite. That is the full set of concrete models the README lists: Exponential Smoothing, Local Global Trend, Damped Local Trend and Kernel Time-based Regression. The ktrlite name in setup.py is the tell that the kernel model has a separate, smaller Stan program rather than sharing the trend model code.
The Pyro path is the other half. The README lists three estimation methods: MCMC as full sampling, MAP as a point estimate, and Variational Inference as what it calls a hybrid-sampling method on an approximate distribution. VI is the one that does not need Stan at all, which matters if you are deploying somewhere that cannot compile C++ at install time. MAP gives you a point estimate, so it is the escape hatch when you want the model structure without the sampling budget.
setup.py also shows a detail worth knowing before you install: it reads a CMDSTAN_VERSION from orbit/config.json and, on install, walks ~/.cmdstan looking for cmdstan-* folders with an older version string and deletes them. That is convenient when it works and surprising when it does not. If you keep a specific CmdStan version for another project in that directory, the install will remove it.
Installing Orbit and fitting a first DLT model
The README gives three install routes: PyPI, source, and conda-forge. The PyPI route is the shortest.
pip install orbit-mlAfter that, the package still needs a working CmdStan behind cmdstanpy before any Stan-backed model will fit. The repository ships install_stan.py at the top level for that purpose, and the Dockerfile in the repo shows the full sequence it uses for a reproducible environment: upgrade pip and setuptools, install from requirements.txt and requirements-test.txt, then install the package in editable mode.
python install_stan.pyThe quick start in the README loads a bundled dataset, splits off the last 52 weeks as a test set, and fits a Damped Local Trend model with three regressors. Column names are passed as strings, which is the whole interface.
from orbit.utils.dataset import load_iclaims
from orbit.models import DLT
from orbit.diagnostics.plot import plot_predicted_data
df = load_iclaims()
test_size = 52
train_df = df[:-test_size]
test_df = df[-test_size:]
dlt = DLT(
response_col='claims', date_col='week',
regressor_col=['trend.unemploy', 'trend.filling', 'trend.job'],
seasonality=52,
)
dlt.fit(df=train_df)Calling fit triggers compilation of the Stan model on first use and then sampling. What you should see is a progress bar from cmdstanpy and, after it finishes, a fitted object. The predict step returns a dataframe rather than an array, which is the part people tend to like.
predicted_df = dlt.predict(df=test_df)plot_predicted_data then takes the training frame, the predicted frame, the date column, the actual column and the test frame, and draws the forecast against the held-out actuals. The README shows the resulting chart with a shaded interval around the prediction line. If you want the draws themselves, the README does not spell that out in the quick start, but the dependency on arviz is the documented route to posterior diagnostics.
Where Orbit is the wrong tool
The cost of the Bayesian approach is real and the README is upfront about the dependency, if not the runtime. Every Stan-backed fit compiles a model and then runs MCMC. On a first run in a fresh environment that compile can dominate the wall clock, and it is not a one-time cost across machines: containers, CI runners and fresh laptops each pay it once. If your workflow is refitting hundreds of short series nightly, that overhead is the thing that will decide whether this project works for you, and the documentation does not give a benchmark to help you estimate it.
The second limitation is version churn. The README's own disclaimer says the project is stable and being incubated for long-term support, and that it may contain new experimental code for which APIs are subject to change. The default branch of the repository is dev, and the README carries a user notice telling readers that the default page is on dev and pointing them to master for a stable version. So the first thing a visitor sees is not the stable code. Pin a release tag rather than installing from the default branch unless you intend to track changes.
The third is scope. Four concrete models is a small menu. If your problem is a hierarchical forecast across thousands of related series with shared parameters, or a multivariate model with cross-series structure, the README does not describe that capability. If you need a gradient-boosted or neural forecaster, this is simply a different category of tool. And if your series is short enough that a least-squares fit is adequate, the posterior buys you little.
How Orbit differs from Prophet and statsmodels
The natural comparison is Prophet, because both target business time series with trend, seasonality and regressors, and both are meant to be driven from a dataframe. The difference is in the estimation. Prophet fits by backfitting a set of components with MAP estimation and produces uncertainty intervals through a sampling procedure layered on top. Orbit fits the whole model jointly as a probabilistic program and gets the posterior from MCMC, MAP or VI, with the sampling method as an explicit user choice. That means Orbit's intervals come from the same joint model as the point forecast, and you can switch to VI when you want speed at the cost of an approximate posterior. Prophet does not expose that knob.
The other comparison is statsmodels, which ships ExponentialSmoothing and SARIMAX. Those are frequentist and closed-form or near it. They will fit in milliseconds where Orbit takes minutes, and for a single series with a clear seasonal pattern they are often enough. What they do not give you is a joint posterior over trend, seasonality and regression coefficients, which is what you need when the uncertainty on a derived quantity (a cumulative total, a probability of exceeding a threshold) is the actual question. The README's own citation points to an arXiv paper titled Orbit: Probabilistic Forecast with Exponential Smoothing, which is the right framing: this is exponential smoothing with a probabilistic treatment, not a replacement for ARIMA in general.
Maintenance, licensing and the cost of upgrading
The repository is not archived. The most recent push recorded on the default branch is 2026-05-22, and the same date carries release v1.1.5.1. Before that, v1.1.5.0 landed on 2026-03-03, and v1.1.4.9 on 2024-04-01. That gap between April 2024 and March 2026 is worth noticing: the project went roughly two years between releases, then shipped two in under three months. A single burst does not establish a cadence, so treat the release history as evidence that the project is alive rather than as evidence of a predictable schedule.
Upgrade cost is dominated by the dependency floor rather than by Orbit itself. pyproject.toml requires Python >=3.12 and pins numpy>=2.1.0, pandas>=2.2.3, torch>=2.5.0, matplotlib>=3.9.2, scipy>=1.14.1 and statsmodels>=0.14.3. The NumPy 2.x floor in particular means Orbit cannot be dropped into a legacy environment pinned to NumPy 1.x. The Dockerfile in the repository still starts from python:3.9, which does not satisfy the >=3.12 requirement in pyproject.toml, so that file is not a working recipe for the current release as written.
On licensing, the repository's LICENSE file is the authority and the metadata is not consistent with itself: pyproject.toml declares Apache License 2.0, while the GitHub licence field reports NOASSERTION. Apache 2.0 includes an explicit patent grant and requires attribution and notice retention, which matters if you redistribute Orbit inside a product. Read the LICENSE file in the tag you pin rather than relying on either metadata field. This is a description of what the files say, not legal advice.
Editorial conclusion
Adopt Orbit when you need a posterior distribution over a forecast and can accept a Stan toolchain and a compile step. Do not adopt it for high-frequency point forecasting where a least-squares model would finish before Orbit has drawn its first sample. Before committing, verify that cmdstanpy finds a working CmdStan installation on your platform, and check the changelog for API changes between the release you pin and the dev branch.
Frequently asked questions
What can uber/orbit do?
It performs Bayesian time series forecasting and inference in Python. The README lists four concrete models (Exponential Smoothing, Local Global Trend, Damped Local Trend and Kernel Time-based Regression) and three estimation methods: MCMC, MAP and Variational Inference.
How do you install uber/orbit?
The README gives pip install orbit-ml from PyPI, conda install -c conda-forge orbit-ml, or a source install via git clone followed by pip install -r requirements.txt and pip install . The package also requires cmdstanpy as a core dependency for Bayesian sampling.
Does uber/orbit require Stan to be installed?
The README states that the project requires cmdstanpy as one of the core dependencies for Bayesian sampling, and setup.py reads a CMDSTAN_VERSION from orbit/config.json. The repository ships an install_stan.py script at the top level, and Variational Inference is listed as a method that does not rely on full MCMC sampling.
Which Python versions does uber/orbit support?
pyproject.toml sets requires-python to >=3.12 and classifies the package for Python 3.12 and 3.13. The Dockerfile in the repository still uses python:3.9, which does not meet that requirement.
What licence does uber/orbit use?
pyproject.toml declares Apache License 2.0, while the GitHub licence field reports NOASSERTION. The LICENSE file in the repository is the authoritative source for the tag you install.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/uber-orbit)