Skip to main content
Practical tips to improve performance when reconciling large hierarchies
When working with hierarchies containing thousands or millions of time series, default settings can lead to slow reconciliation and high memory usage. This guide covers concrete steps to improve performance. We will cover: 1. Using Polars instead of Pandas 2. Telling the library your data is balanced 3. Using sparse reconciliation methods 4. Choosing the right reconciliation method for your scale 5. Parallelizing non-negative reconciliation 6. Avoiding unnecessary computation 7. Profiling your pipeline

1. Libraries

2. Load Data

We use the TourismSmall dataset for demonstration. The same principles apply to much larger hierarchies.

3. Base Forecasts

4. Performance Tips

Tip 1: Use Polars instead of Pandas

HierarchicalForecast supports both Pandas and Polars DataFrames transparently via Narwhals. Polars is generally faster for the DataFrame operations used internally (sorting, joining, pivoting) and uses less memory due to Apache Arrow columnar storage. Simply pass Polars DataFrames to reconcile() β€” no code changes needed beyond the data loading step:
If you use aggregate() to build your hierarchy, pass a Polars DataFrame directly:
Note: The sparse_s=True option in aggregate() is currently only available for Pandas DataFrames. If you need sparse S matrices with Polars, pass a Polars DataFrame without sparse_s β€” the core reconciliation will still construct sparse matrices internally when using sparse methods.

Tip 2: Set is_balanced=True

If all your time series have the same number of observations (same start and end dates), set is_balanced=True in reconcile(). This skips an expensive pivot() operation and uses a fast reshape instead.
When can you use this? Most hierarchical datasets are balanced β€” every series has observations at every time step. If you built your hierarchy with aggregate(), the result is always balanced.

Tip 3: Use Sparse Reconciliation Methods

For large hierarchies, the dense summing matrix S (shape: n_hiers Γ— n_bottom) can consume significant memory and slow down matrix operations. Sparse methods use scipy.sparse matrices and iterative solvers instead of dense linear algebra. The library provides sparse variants of the main methods: MinTraceSparse constructs a scipy.sparse.linalg.LinearOperator for the projection matrix P and solves the system iteratively with bicgstab, avoiding materialization of the full dense P matrix. When to use sparse methods: When your hierarchy has thousands of bottom-level series or more. For small hierarchies (< 500 series), the overhead of sparse operations may negate the savings.

Tip 4: Choose the Right Reconciliation Method

Reconciliation methods vary significantly in computational cost. Here is a rough ranking from fastest to slowest: Key takeaways: - BottomUp and MinTrace(method='ols') are the cheapest and don’t require insample data (Y_df). - Methods requiring insample residuals (wls_var, mint_shrink, mint_cov) need the Y_df argument passed to reconcile(). Omitting Y_df when not needed saves computation. - For very large hierarchies, prefer MinTraceSparse over MinTrace to avoid dense matrix operations. - mint_shrink and mint_cov compute a full nΓ—n covariance matrix β€” this scales quadratically with the number of series.

Tip 5: Parallelize Non-Negative Reconciliation

When using nonnegative=True, a quadratic programming (QP) problem is solved for each forecast horizon step. Use num_threads to parallelize these independent QP calls:
The num_threads parameter controls the ThreadPoolExecutor pool size. Set it to the number of available CPU cores. Note that num_threads only takes effect when nonnegative=True. MinTraceSparse also offers a qp parameter (default True). Setting qp=False replaces the full QP solve with simple clipping of negative values β€” much faster but lower quality:

Tip 6: Avoid Unnecessary Computation

Skip probabilistic forecasts when not needed. If you only need point forecasts, don’t pass the level parameter:
If you do need intervals, intervals_method='normality' is the cheapest option. The 'bootstrap' and 'permbu' methods require many re-evaluations and are significantly slower. Skip diagnostics in production. The diagnostics=True flag computes coherence checks across all forecasts β€” useful for debugging but adds overhead:
Don’t pass insample data when not needed. Methods like BottomUp, TopDown(method='forecast_proportions'), MinTrace(method='ols'), and MinTrace(method='wls_struct') don’t use insample data. Omitting Y_df skips the data preparation for insample values:

Tip 7: Profile Your Pipeline

HierarchicalForecast provides built-in profiling tools to identify bottlenecks. execution_times attribute: After calling reconcile(), the HierarchicalReconciliation instance exposes a dictionary of per-method execution times:
CodeTimer context manager: Use this to time any block of code in your pipeline:

5. Summary Checklist

Here is a quick checklist to optimize your hierarchical forecasting pipeline:

References