Written by
Halkwinds Editorial Team
Halkwinds Research & Editorial

Time Series Forecasting with Machine Learning: A Practical Guide
How to choose, train, and deploy forecasting models for demand, revenue, and operational use cases — from ARIMA to transformers.
Time series forecasting sits at the intersection of data engineering discipline and statistical modeling — and it's where a lot of production ML pipelines quietly break. Unlike a static classification problem, forecasting introduces temporal dependencies, data leakage traps, and evaluation pitfalls that don't exist elsewhere. If you're a data engineer tasked with building demand, revenue, or operational forecasts, the hard part is rarely picking an algorithm. It's building a reproducible pipeline that respects time ordering, handles messy real-world data, and can be retrained and monitored without manual babysitting. This guide walks through the practical decisions — from classical ARIMA to modern transformers — with the tooling and operational considerations that matter when time series forecasting ML systems go to production.
- Background / Why This Matters
- Core Concepts and Architecture
- Implementation Strategy
- Scaling and Operational Considerations
- Common Mistakes / What to Avoid
- Frequently Asked Questions
- Conclusion
Background / Why This Matters
Forecasting drives real money. Inventory planning, cloud capacity provisioning, staffing, cash-flow projections, and ad-spend allocation all depend on a number that predicts the future. When that number is wrong, the cost is concrete: overstocked warehouses, missed SLAs, or over-provisioned infrastructure burning budget every hour.
What makes forecasting deceptively hard for data engineers is that the tooling looks simple. You can fit a Prophet model in five lines of Python and get a nice-looking chart. The trap is that a good-looking backtest often hides a leaky pipeline or an evaluation that would never survive real deployment. Estimates vary, but a large share of forecasting projects underperform in production not because the model was bad, but because the surrounding data engineering — feature timing, retraining cadence, missing-data handling — was never built for the temporal constraints of the problem.
The other shift worth naming: the field has moved. Five years ago, ARIMA and exponential smoothing dominated. Today, global neural models trained across thousands of related series (via libraries like NeuralForecast) frequently outperform per-series classical models, especially when you have many correlated series — think SKU-level demand or per-region traffic.
Takeaway: Treat forecasting as a data engineering problem first and a modeling problem second. The pipeline determines whether the model survives contact with production.
Core Concepts and Architecture
Before choosing tools, get the vocabulary and structure right, because they dictate your pipeline design.
The three shapes of a forecasting problem
- Univariate, single series: One target over time (e.g., total daily revenue). Classical methods often shine here.
- Multivariate: The target depends on external regressors (promotions, holidays, weather, price).
- Global / panel: Thousands of related series forecast by one shared model. This is where neural approaches earn their keep.
Key concepts that shape your pipeline
- Forecast horizon: How far ahead you predict. A 1-day horizon and a 90-day horizon are almost different products.
- Frequency and granularity: Hourly, daily, weekly. Aggregation decisions change everything downstream.
- Seasonality: Daily, weekly, yearly cycles. Multiple overlapping seasonalities are common (e.g., retail: weekly + yearly).
- Exogenous variables: Split into known-future (holidays, planned promos) and only-known-past (competitor actions). This split is non-negotiable for correct feature timing.
- Backtesting with rolling origin: Never random splits. Always train on the past, test on the future, and slide the window forward.
The model landscape
| Approach | Best for | Strengths | Weaknesses |
|---|---|---|---|
| ARIMA / SARIMA | Single, stable series with clear seasonality | Interpretable, well-understood, no GPU needed | Poor with many series, weak on exogenous features |
| Prophet | Business series with strong seasonality + holidays | Fast to prototype, handles missing data and holidays well | Struggles with high-frequency, non-additive patterns |
| Gradient boosting (LightGBM/XGBoost) | Tabular forecasting with many features | Excellent with engineered features and exogenous data | Requires manual lag/feature engineering, no native uncertainty |
| Neural (N-BEATS, NHITS, TFT via NeuralForecast) | Many related series, long horizons | Global learning, handles complex patterns, probabilistic outputs | Compute-heavy, needs more data and tuning |
| Transformers (PatchTST, TFT) | Long-horizon, high-dimensional panels | Captures long-range dependencies, strong benchmarks | Data-hungry, harder to debug and deploy |
A practical middle path: Darts gives you a unified API across ARIMA, Prophet, gradient-boosted models, and deep learning, which makes it ideal for structured model comparison without rewriting your pipeline for each library.
Takeaway: Match the model to the problem shape. One series with clear seasonality? Start classical. Thousands of related series? Go global neural. Rich exogenous features? Gradient boosting is often the pragmatic winner.
Implementation Strategy
Here's a sequence that has repeatedly proven robust across production forecasting builds.
1. Establish a baseline before anything else
Your first model should be embarrassingly simple: a seasonal naive forecast (predict last week's same day) or a moving average. Every fancier model must beat this baseline on a proper backtest, or you've wasted GPU budget. Research consistently shows that naive baselines are surprisingly hard to beat on many real business series.
2. Build the temporal data pipeline correctly
This is the data engineer's core responsibility. Get these right:
- Regularize the timeline. Fill missing timestamps explicitly. A gap means "no observation," not "zero" — decide which, and document it.
- Timezone and DST handling. Silent UTC vs local mismatches produce phantom seasonality.
- Feature timing / as-of correctness. When generating a feature for time t, only use data that was actually available at t. This is the single most common source of leakage.
- Lag and rolling features. For gradient-boosting approaches, generate lags (t-1, t-7, t-28) and rolling stats, computed strictly on past windows.
3. Backtest with rolling origin evaluation
Use expanding or sliding windows. For each fold: train on everything up to a cutoff, forecast the horizon, score, then move the cutoff forward. Darts and NeuralForecast both provide native cross-validation utilities for this. Report metrics across all folds, not a single lucky split.
4. Choose metrics that match the business
- MAE / RMSE: Good general-purpose error metrics; RMSE penalizes large misses.
- MAPE / sMAPE: Percentage errors — but MAPE breaks near zero, so avoid it for intermittent demand.
- Pinball loss: When you need quantile forecasts (e.g., "the 90th percentile of demand for safety stock").
For inventory and capacity, quantile forecasts usually beat point forecasts — you care about the cost of being wrong in each direction asymmetrically.
5. Iterate up the complexity ladder
Move from baseline → Prophet/ARIMA → gradient boosting → global neural only as each step earns its added cost. Track every experiment. This is where teams often bring in a partner like Halkwinds to stand up a reproducible experimentation and MLOps foundation so the iteration doesn't devolve into untracked notebooks.
Takeaway: Baseline first, correct temporal pipeline second, rolling backtest third. Model sophistication is the last lever, not the first.
Scaling and Operational Considerations
A forecast that works once in a notebook is not a system. Production forecasting has its own operational shape.
Retraining cadence
Time series drift. Consumer behavior shifts, promotions change, macro conditions move. Decide on a retraining schedule (nightly, weekly) and — critically — validate the newly trained model against the incumbent before promoting it. A blind auto-retrain can silently ship a worse model.
Handling thousands of series
Per-series classical models don't scale linearly in ops overhead — fitting 50,000 ARIMA models nightly is painful. Global neural models (NeuralForecast) train one model across all series, which is far more scalable and often more accurate for related series. When you must keep per-series models, parallelize with Dask, Spark, or Ray.
Serving patterns
| Pattern | When to use | Notes |
|---|---|---|
| Batch pre-compute | Daily/weekly forecasts consumed by dashboards or planning tools | Cheapest and most common; write forecasts to a table |
| On-demand API | Interactive what-if scenarios with changing regressors | Requires low-latency model loading; cache aggressively |
| Streaming/rolling | Short-horizon operational forecasts (traffic, load) | Highest complexity; needs feature stores and freshness guarantees |
Monitoring
Monitor prediction accuracy against actuals as they arrive — not just at training time. Track rolling MAE per series, flag series where error spikes, and watch for input data drift (a feed that goes stale or changes schema). Alert on the pipeline, not just the model. Halkwinds frequently helps teams wire this observability layer into existing data platforms so forecast degradation is caught before the business feels it.
Takeaway: Design for retraining, prefer global models at scale, default to batch serving, and monitor live accuracy against actuals — the model is a component, the pipeline is the product.
Common Mistakes / What to Avoid
Explore Further