Nixtla TimeGPT Tutorial: Foundation Model for Time Series Forecasting
Time series forecasting is one of the most critical tasks in data science, spanning sales prediction, demand forecasting, infrastructure monitoring, and financial analysis. However, building accurate forecasting models traditionally requires deep expertise in model selection, feature engineering, and hyperparameter tuning.
Nixtla introduces TimeGPT — a foundation model for time series that transforms how we approach forecasting. Similar to GPT for text, TimeGPT is a pre-trained model that can be used directly for forecasting without training from scratch. In this tutorial, we'll learn how to use Nixtla TimeGPT practically, from installation to advanced use cases.
What is Nixtla TimeGPT?
TimeGPT is the first foundation model for time series forecasting, developed by Nixtla. The model was trained on billions of data points from diverse domains, enabling zero-shot forecasting — meaning the model can provide predictions immediately without retraining on your specific data.
Key advantages of TimeGPT:
- Zero-shot forecasting: Immediate predictions without training
- Multi-horizon: Forecast across various time horizons
- Anomaly detection: Detect anomalies in time series data
- Exogenous variables: Support for external variables to improve accuracy
- Conformal prediction: Statistically calibrated prediction intervals
- Cross-validation: Built-in temporal cross-validation
- Fine-tuning: Can be fine-tuned on specific data for better performance
Installation
Using pip
pip install nixtla
Using conda
conda install -c conda-forge nixtla
Additional dependencies for visualization
pip install nixtla matplotlib plotly pandas
API Key Setup
TimeGPT uses API-based inference. You need to register at the Nixtla dashboard to get an API key.
from nixtla import NixtlaClient
Initialize client
nixtlaclient = NixtlaClient(apikey='yourapikeyhere')
Or set via environment variable
export NIXTLAAPIKEY=yourapikeyhere
nixtlaclient = NixtlaClient()
To validate that your API key works:
nixtlaclient.validateapikey()
Output: True if valid
Basic Usage: Simple Forecasting
Preparing Data
TimeGPT accepts data in pandas DataFrame format with at least two columns: timestamp and value.
import pandas as pd
from nixtla import NixtlaClient
nixtlaclient = NixtlaClient()
Create sample data
Example: daily sales data for 2 years
dates = pd.daterange(start='2024-01-01', end='2025-12-31', freq='D')
import numpy as np
np.random.seed(42)
trend = np.linspace(100, 200, len(dates))
seasonal = 30 np.sin(2 np.pi np.arange(len(dates)) / 365.25)
noise = np.random.normal(0, 10, len(dates))
values = trend + seasonal + noise
df = pd.DataFrame({
'timestamp': dates,
'value': values
})
print(df.head())
print(f"Shape: {df.shape}")
Your First Forecast
# Forecast 30 days ahead
forecastdf = nixtlaclient.forecast(
df=df,
h=30, # horizon: 30 days ahead
timecol='timestamp',
targetcol='value'
)
print(forecastdf.head())
Visualizing Results
# Plot forecast results
nixtlaclient.plot(
df=df,
forecastsdf=forecastdf,
timecol='timestamp',
targetcol='value',
maxinsamplelength=90 # Show 90 days of historical data
)
Working with Real-World Datasets
Example with Retail Data
# Using the AirPassengers dataset
from nixtla import NixtlaClient
import pandas as pd
nixtlaclient = NixtlaClient()
Load AirPassengers dataset
df = pd.readcsv(
'https://raw.githubusercontent.com/jbrownlee/Datasets/master/airline-passengers.csv',
parsedates=['Month'],
)
df.columns = ['timestamp', 'value']
Forecast 12 months ahead
forecastdf = nixtlaclient.forecast(
df=df,
h=12,
timecol='timestamp',
targetcol='value',
freq='MS' # Monthly Start frequency
)
Visualize
nixtlaclient.plot(
df=df,
forecastsdf=forecastdf,
timecol='timestamp',
targetcol='value'
)
Multiple Time Series (Panel Data)
TimeGPT can handle multiple time series simultaneously using a uniqueid column:
# Data with multiple series
data = []
for productid in ['SKU001', 'SKU002', 'SKU003']:
dates = pd.daterange('2024-01-01', '2025-12-31', freq='D')
np.random.seed(hash(productid) % 100)
values = (
np.random.uniform(50, 150) +
20 np.sin(2 np.pi np.arange(len(dates)) / 7) + # weekly pattern
np.random.normal(0, 5, len(dates))
)
for date, val in zip(dates, values):
data.append({
'uniqueid': productid,
'timestamp': date,
'value': max(0, val)
})
dfpanel = pd.DataFrame(data)
Forecast all series at once
forecastpanel = nixtlaclient.forecast(
df=dfpanel,
h=14, # 2 weeks ahead
timecol='timestamp',
targetcol='value',
idcol='uniqueid'
)
print(forecastpanel.groupby('uniqueid').size())
Advanced Usage
Prediction Intervals (Conformal Prediction)
TimeGPT supports statistically calibrated conformal prediction intervals:
# Forecast with prediction intervals
forecastwithintervals = nixtlaclient.forecast(
df=df,
h=30,
timecol='timestamp',
targetcol='value',
level=[80, 95] # 80% and 95% prediction intervals
)
print(forecastwithintervals.columns)
Output: ['timestamp', 'TimeGPT', 'TimeGPT-lo-95', 'TimeGPT-lo-80',
'TimeGPT-hi-80', 'TimeGPT-hi-95']
Visualize with intervals
nixtlaclient.plot(
df=df,
forecastsdf=forecastwithintervals,
timecol='timestamp',
targetcol='value',
level=[80, 95],
maxinsamplelength=60
)
Exogenous Variables
Add external variables to improve prediction accuracy:
# Adding exogenous variables
dfwithexog = df.copy()
dfwithexog['dayofweek'] = dfwithexog['timestamp'].dt.dayofweek
dfwithexog['month'] = dfwithexog['timestamp'].dt.month
dfwithexog['isweekend'] = (dfwithexog['dayofweek'] >= 5).astype(int)
Create future exogenous variables
futuredates = pd.daterange(
start=dfwithexog['timestamp'].max() + pd.Timedelta(days=1),
periods=30,
freq='D'
)
futureexog = pd.DataFrame({
'timestamp': futuredates,
'dayofweek': futuredates.dayofweek,
'month': futuredates.month,
'isweekend': (futuredates.dayofweek >= 5).astype(int)
})
Forecast with exogenous variables
forecastexog = nixtlaclient.forecast(
df=dfwithexog,
Xdf=futureexog,
h=30,
timecol='timestamp',
targetcol='value'
)
Anomaly Detection
TimeGPT can detect anomalies in time series data:
# Detect anomalies
anomaliesdf = nixtlaclient.detectanomalies(
df=df,
timecol='timestamp',
targetcol='value',
freq='D'
)
Visualize anomalies
nixtlaclient.plot(
df=df,
anomaliesdf=anomaliesdf,
timecol='timestamp',
targetcol='value'
)
Filter only anomalous data points
anomalouspoints = anomaliesdf[anomaliesdf['anomaly'] == True]
print(f"Number of anomalies detected: {len(anomalouspoints)}")
Cross-Validation
Perform temporal cross-validation to evaluate model performance:
# Cross-validation
cvresults = nixtlaclient.crossvalidation(
df=df,
h=30, # forecast horizon
nwindows=3, # number of windows
timecol='timestamp',
targetcol='value',
level=[90]
)
print(cvresults.head())
Calculate evaluation metrics
from sklearn.metrics import meanabsoluteerror, meansquarederror
mae = meanabsoluteerror(cvresults['value'], cvresults['TimeGPT'])
rmse = meansquarederror(cvresults['value'], cvresults['TimeGPT'], squared=False)
mape = np.mean(np.abs(
(cvresults['value'] - cvresults['TimeGPT']) / cvresults['value']
)) 100
print(f"MAE: {mae:.2f}")
print(f"RMSE: {rmse:.2f}")
print(f"MAPE: {mape:.2f}%")
Fine-tuning on Specific Data
For domain-specific data, you can fine-tune TimeGPT:
# Fine-tune TimeGPT on your data
forecastfinetuned = nixtlaclient.forecast(
df=df,
h=30,
timecol='timestamp',
targetcol='value',
finetunesteps=50, # number of fine-tuning steps
finetuneloss='mse' # loss function: 'mse', 'mae', 'rmse', 'mape'
)
Compare with default (no fine-tuning)
forecastdefault = nixtlaclient.forecast(
df=df,
h=30,
timecol='timestamp',
targetcol='value'
)
Visualize comparison
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(12, 6))
ax.plot(df['timestamp'].tail(60), df['value'].tail(60), label='Historical', color='black')
ax.plot(forecastdefault['timestamp'], forecastdefault['TimeGPT'],
label='TimeGPT (default)', linestyle='--')
ax.plot(forecastfinetuned['timestamp'], forecastfinetuned['TimeGPT'],
label='TimeGPT (fine-tuned)', linestyle='-.')
ax.legend()
ax.settitle('Default vs Fine-tuned Comparison')
plt.tightlayout()
plt.savefig('comparison.png', dpi=150)
plt.show()
Using the TimeGPT-1-Long-Horizon Model
For forecasting with long horizons, use the dedicated model:
# Long-horizon forecasting
longforecast = nixtlaclient.forecast(
df=df,
h=365, # Forecast 1 year ahead
timecol='timestamp',
targetcol='value',
model='timegpt-1-long-horizon', # Dedicated long-horizon model
level=[90]
)
nixtlaclient.plot(
df=df,
forecastsdf=longforecast,
timecol='timestamp',
targetcol='value',
level=[90],
maxinsamplelength=180
)
Integration with Popular Tools
Integration with MLflow
import mlflow
from nixtla import NixtlaClient
nixtlaclient = NixtlaClient()
with mlflow.startrun(runname="timegptforecast"):
# Forecast
forecastdf = nixtlaclient.forecast(
df=df, h=30,
timecol='timestamp', targetcol='value',
level=[90]
)
# Cross-validation for metrics
cvresults = nixtlaclient.crossvalidation(
df=df, h=30, nwindows=3,
timecol='timestamp', targetcol='value'
)
# Log metrics
mae = meanabsoluteerror(cvresults['value'], cvresults['TimeGPT'])
rmse = meansquarederror(
cvresults['value'], cvresults['TimeGPT'], squared=False
)
mlflow.logmetric("mae", mae)
mlflow.logmetric("rmse", rmse)
mlflow.logparam("horizon", 30)
mlflow.logparam("model", "timegpt-1")
# Save forecast as artifact
forecastdf.tocsv("forecastresults.csv", index=False)
mlflow.logartifact("forecastresults.csv")
print(f"MAE: {mae:.2f}, RMSE: {rmse:.2f}")
Integration with Pandas and Plotly
import plotly.graphobjects as go
Forecast with intervals
forecastdf = nixtlaclient.forecast(
df=df, h=30,
timecol='timestamp', targetcol='value',
level=[80, 95]
)
fig = go.Figure()
Historical data
fig.addtrace(go.Scatter(
x=df['timestamp'].tail(90),
y=df['value'].tail(90),
mode='lines',
name='Historical',
line=dict(color='black')
))
Forecast
fig.addtrace(go.Scatter(
x=forecastdf['timestamp'],
y=forecastdf['TimeGPT'],
mode='lines',
name='Forecast',
line=dict(color='blue')
))
95% interval
fig.addtrace(go.Scatter(
x=pd.concat([forecastdf['timestamp'], forecastdf['timestamp'][::-1]]),
y=pd.concat([forecastdf['TimeGPT-hi-95'], forecastdf['TimeGPT-lo-95'][::-1]]),
fill='toself',
fillcolor='rgba(0,0,255,0.1)',
line=dict(color='rgba(255,255,255,0)'),
name='95% CI'
))
fig.updatelayout(
title='TimeGPT Forecast with Prediction Intervals',
xaxistitle='Date',
yaxistitle='Value',
template='plotlywhite'
)
fig.show()
Best Practices
1. Proper Data Preparation
# Ensure complete data without missing values
def preparetimeseries(df, timecol, valuecol, freq='D'):
df = df.copy()
df[timecol] = pd.todatetime(df[timecol])
df = df.sortvalues(timecol)
# Create complete date range
fullrange = pd.daterange(
start=df[timecol].min(),
end=df[timecol].max(),
freq=freq
)
df = df.setindex(timecol).reindex(fullrange)
df.index.name = timecol
df = df.resetindex()
# Interpolate missing values
df[valuecol] = df[valuecol].interpolate(method='linear')
# Remove remaining NaN
df = df.dropna(subset=[valuecol])
return df
dfclean = preparetimeseries(df, 'timestamp', 'value')
2. Choose the Right Horizon
# Rule of thumb: use timegpt-1-long-horizon for h > 1 seasonality period
datafreq = 'D' # daily data
seasonalityperiod = 7 # weekly seasonality
horizon = 30 # 30 days
if horizon > seasonalityperiod:
model = 'timegpt-1-long-horizon'
else:
model = 'timegpt-1'
forecast = nixtlaclient.forecast(
df=df, h=horizon,
timecol='timestamp', targetcol='value',
model=model
)
3. Validate with Cross-Validation
Always validate your model before using it in production:
# Comprehensive evaluation
def evaluatetimegpt(df, horizons=[7, 14, 30], nwindows=5):
results = {}
for h in horizons:
cv = nixtlaclient.crossvalidation(
df=df, h=h, nwindows=nwindows,
timecol='timestamp', targetcol='value'
)
mae = meanabsoluteerror(cv['value'], cv['TimeGPT'])
rmse = meansquarederror(cv['value'], cv['TimeGPT'], squared=False)
results[h] = {'MAE': mae, 'RMSE': rmse}
return pd.DataFrame(results).T
evalresults = evaluatetimegpt(df)
print(evalresults)
4. Use Fine-tuning for Specific Domains
# Fine-tuning with evaluation
cvdefault = nixtlaclient.crossvalidation(
df=df, h=30, nwindows=3,
timecol='timestamp', targetcol='value'
)
cvfinetuned = nixtlaclient.crossvalidation(
df=df, h=30, nwindows=3,
timecol='timestamp', targetcol='value',
finetunesteps=50
)
maedefault = meanabsoluteerror(cvdefault['value'], cvdefault['TimeGPT'])
maefinetuned = meanabsoluteerror(cvfinetuned['value'], cvfinetuned['TimeGPT'])
print(f"MAE Default: {maedefault:.2f}")
print(f"MAE Fine-tuned: {maefinetuned:.2f}")
print(f"Improvement: {((maedefault - maefinetuned) / maedefault) 100:.1f}%")
5. Monitoring and Alerting
def forecastwithmonitoring(df, h, thresholdmape=10):
# Cross-validation check
cv = nixtla
client.crossvalidation(
df=df, h=h, n
windows=3,
timecol='timestamp', targetcol='value'
)
mape = np.mean(np.abs(
(cv['value'] - cv['TimeGPT']) / cv['value']
)) 100
if mape > thresholdmape:
print(f"WARNING: MAPE {mape:.1f}% exceeds threshold {thresholdmape}%")
print("Consider fine-tuning or adding exogenous variables")
# Actual forecast
forecast = nixtlaclient.forecast(
df=df, h=h,
timecol='timestamp', targetcol='value',
level=[90]
)
# Anomaly check on recent data
anomalies = nixtlaclient.detectanomalies(
df=df.tail(90),
timecol='timestamp', targetcol='value'
)
nanomalies = anomalies['anomaly'].sum()
if nanomalies > 0:
print(f"INFO: {nanomalies} anomalies detected in last 90 data points")
return forecast, mape
forecast, mape = forecastwithmonitoring(df, h=30)
Use Case: E-Commerce Demand Forecasting
Here's a complete end-to-end example for demand forecasting:
import pandas as pd
import numpy as np
from nixtla import NixtlaClient
nixtlaclient = NixtlaClient()
Simulate e-commerce data
np.random.seed(42)
dates = pd.daterange('2024-01-01', '2026-09-28', freq='D')
products = ['ProductA', 'ProductB', 'ProductC']
data = []
for product in products:
base = np.random.uniform(100, 500)
trend = np.linspace(0, base 0.3, len(dates))
weekly = base 0.2 np.sin(2 np.pi np.arange(len(dates)) / 7)
yearly = base 0.15 np.sin(2 np.pi np.arange(len(dates)) / 365.25)
noise = np.random.normal(0, base * 0.05, len(dates))
sales = np.maximum(0, base + trend + weekly + yearly + noise)
for date, val in zip(dates, sales):
data.append({
'uniqueid': product,
'timestamp': date,
'sales': round(val, 2)
})
dfecommerce = pd.DataFrame(data)
Forecast 14 days ahead for all products
forecast = nixtlaclient.forecast(
df=dfecommerce,
h=14,
timecol='timestamp',
targetcol='sales',
idcol='uniqueid',
level=[80, 95]
)
Summary per product
for product in products:
productforecast = forecast[forecast['uniqueid'] == product]
avgforecast = productforecast['TimeGPT'].mean()
lo95 = productforecast['TimeGPT-lo-95'].mean()
hi95 = productforecast['TimeGPT-hi-95'].mean()
print(f"{product}: Avg forecast = {avgforecast:.0f} "
f"(95% CI: {lo95:.0f} - {hi95:.0f})")
Comparison with Traditional Approaches
| Aspect | TimeGPT | ARIMA/Prophet | Custom Deep Learning |
|--------|---------|---------------|---------------------|
| Setup time | Minutes | Hours | Days-Weeks |
| Training data required | No (zero-shot) | Yes | Yes (lots) |
| Expertise needed | Minimal | Moderate | High |
| Multi-series | Native support | Per-series | Custom architecture needed |
| Anomaly detection | Built-in | Separate tool | Custom implementation |
| Scalability | API-based, auto-scale | Infra-dependent | Infra-dependent |
| Cost | Per API call | Own compute | Own compute |
| Customization | Fine-tuning | Full control | Full control |
Conclusion
Nixtla TimeGPT brings a new paradigm to time series forecasting. With the foundation model approach, TimeGPT eliminates the need to train models from scratch, enabling data scientists and engineers to immediately obtain high-quality forecasts.
Key takeaways:
TimeGPT is ideal for rapid prototyping, baseline forecasting, and use cases where delivery speed matters more than full model control. For production systems requiring high volume, consider combining TimeGPT with on-premise solutions.