Inside GDPNow: A Complete Reverse-Engineering of the Fed’s Most-Watched Nowcast

The Atlanta Fed publishes a real-time estimate of U.S. GDP growth. They give you the math, the data, the parameters, and a downloadable spreadsheet — but they won’t share the code. Here’s how the machine actually works, end to end.


If you trade rates, manage macro risk, or just want to know what the U.S. economy is doing before the Bureau of Economic Analysis tells you, you’ve probably stared at the Atlanta Fed’s GDPNow tracker. As of May 21, 2026, it’s printing 4.3% (SAAR) for 2026:Q2. Whether that’s right or wrong is a different article. This one is about how it gets there.

GDPNow is the closest thing in macroeconomics to an open-source forecasting model that isn’t actually open source. The Atlanta Fed won’t release the code — they say so plainly in the FAQ — but they publish:

  • A 50-page working paper specifying every equation (Higgins 2014)
  • A “Modifications” PDF listing every change since 2014, including the recent gold-imports adjustment
  • An Excel workbook with all current raw data, the model’s intermediate forecasts, and the latent dynamic factor
  • A schedule listing every data release that triggers an update

That’s enough to reconstruct the model. So let’s do it.

What GDPNow is, in one paragraph

GDPNow is a bottom-up tracking model. It does not try to forecast GDP directly. Instead, it forecasts the 13 subcomponents the BEA itself adds up to produce the “advance” GDP estimate, then aggregates them using the same Fisher chain-weighted formula the BEA uses. It synthesizes two econometric traditions: the bridge equation approach (Lawrence Klein, Miller–Chin) and the dynamic factor model approach (Giannone–Reichlin–Small 2008). It runs eight steps, uses roughly 125 monthly time series plus a 34-variable price BVAR plus several block BVARs, and re-estimates itself six or seven times per month — whenever a relevant statistical release lands.

Why nowcasting exists at all

The BEA’s “advance” GDP estimate for a quarter lands roughly 25–30 days after the quarter ends. For policymakers and markets, that’s an eternity. Roughly 70% of the source data the BEA uses for its advance estimate is already public before the advance release — retail sales, the trade report, construction spending, ISM, durable-goods orders, personal-income-and-outlays. The trick is mimicking the BEA’s data-construction machinery accurately enough that you assemble the same number they will, before they do.

Faust and Wright (2009) showed Fed Board staff had been doing exactly this for decades — informally, with judgment. GDPNow is the same idea, with judgment stripped out and the econometrics formalized. The FAQ is emphatic: no subjective adjustments. Once the model starts forecasting a quarter, the code is frozen until after the advance release.

The 13 subcomponents

This is the spine of everything. GDP is decomposed into:

  1. PCE goods
  2. PCE services
  3. Residential investment
  4. Nonresidential equipment investment
  5. Nonresidential intellectual property products (IPP) investment
  6. Nonresidential structures investment
  7. Change in private inventories (CIPI)
  8. Federal government spending
  9. State + local government spending
  10. Exports of goods
  11. Exports of services
  12. Imports of goods
  13. Imports of services

Each gets its own forecasting recipe. The model also runs a parallel pipeline over the implicit price deflators of the same 13 series, because real-GDP chain-weighting needs both quantities and prices.

The eight-step pipeline

Step 1 — A quarterly Bayesian VAR over the 13 components

The model starts with a 5-lag Bayesian VAR over all 13 real-GDP subcomponents (plus a parallel BVAR over their 13 implicit price deflators), estimated from 1968 forward. The prior follows Bańbura, Giannone, and Reichlin (2008) — a Minnesota-style prior with shrinkage that lets you fit big VARs without overfitting.

For each subcomponent i, this produces a one-step-ahead forecast Δlog X̂ᵢ_{T+1, BVAR} and an in-sample fitted series Sᵢ from 1985:Q1 onward. The fitted series is critical: it’s the “BVAR-only” benchmark the model will later combine with the bridge-equation forecast.

Step 2a — A 12-lag price BVAR for deflators

Some monthly source data are nominal and arrive before the deflator that should accompany them — e.g., monthly retail sales prints before the CPI in some months. To deflate them in real time, the model runs a 34-variable BVAR over price indices (PPI subindices, CPI subindices, import/export price indices) with 12 lags, starting in 1983, using Waggoner–Zha (1999) conditional forecasting to handle the jagged release calendar.

If you’ve never implemented Waggoner–Zha: it’s a Gibbs-sampler-style method for drawing from the conditional distribution of unobserved values given the observed values in a Gaussian VAR. It is what lets you say “I have January and February but not March; condition on Jan/Feb and project a coherent March.”

Step 2b — The dynamic factor model

This is where the Giannone–Reichlin–Small machinery lives. The model takes ~124–126 monthly time series — most of the same set the Chicago Fed uses for the CFNAI — standardizes them, and fits a single-factor dynamic factor model:

f_{t,h}    = ρ₁·f_{t,h−1} + ρ₂·f_{t,h−2} + ρ₃·f_{t,h−3} + u_{t,h}        (factor dynamics)
z^i_{t,h}  = γ^i₁·f_{t,h} + ε^i_{t,h}                                    (loadings)

Estimation follows Doz–Giannone–Reichlin (2006): seed the factor with principal components (using Stock–Watson’s missing-data trick), then OLS the loadings and factor AR, then refine the factor with the Kalman filter + smoother. Giannone–Reichlin–Small (2008) is what makes this work for the “jagged edge” of staggered releases — different series come in on different days, but you can still get a smoothed factor that conditions on whatever you have.

As of the 2018 modification, the idiosyncratic errors ε^i for each series follow their own AR(1):

ε^i_{t,h} = φ^i · ε^i_{t,h−1} + η^i_{t,h}

This was added specifically to dampen overreactions to the ISM Manufacturing release, which the Atlanta Fed found was causing predictable jumps in the nowcast every month.

Step 3 — Factor-augmented autoregressions to fill in the missing months

Once you have the factor — including forecasted values out into the future — you use it to fill in monthly source data that hasn’t been released yet. For each monthly series yⁱ:

Δlog(y^i_{t,h}) = α^i + Σ_{k=1..q} γ^i_k · Δlog(y^i_{t,h−k}) + Σ_{j=0..r} β^i_j · f_{t,h−j}

This is the Stock–Watson (2002) factor-augmented AR. Lag lengths q (1–12, originally; capped at 6 after the 2022 modification) and r (0–3) are chosen by AIC. For consumption variables specifically, q is bounded between 3 and 12 (or 6 and 12 in the original).

The 2022 modification also tacked on a set of 10 dummy variables capturing COVID months — one for March 2020, then nine more for the following months. The 2022 modification additionally swapped the AR(4) used for the “no monthly indicator” subcomponents (think: residential investment in dormitories) for an AR(1) with four quarterly COVID dummies.

Step 4 — Bridge equations for investment and government

This is the “bridge equation” part the model is named for. For each of the five coarse subcomponents — residential investment, nonresidential equipment, IPP, nonresidential structures, federal government, state+local government — the model:

(a) Partitions the subcomponent into “granular” pieces using BEA expenditure shares. Residential investment, for example, splits into:

Subcomponent 2012:Q4 share Monthly indicator Permanent-site construction 41.3% Spliced new housing construction Manufactured homes 0.9% Mobile home value Dormitories 0.8% (none — AR forecast) Improvements 39.2% Spliced building materials Brokers’ commissions 16.4% Existing + new home sale value Residential equipment 2.3% Retail sales, residential equipment Net purchases of used −0.9% (not used)

(b) Runs a bridge equation regressing each granular component’s quarterly log-growth on the quarterly aggregate of its monthly indicator:

Δlog(REALRESINV^i_t) = φ^i + Σ_k θ^i_k · Δlog(Ŷ^i_t)

where Ŷ^i_t is the indicator aggregated to quarterly frequency (potentially using forecasted months from Step 3).

© Aggregates the granular forecasts back up using time-T expenditure shares — which approximates Törnqvist weighting and, by extension, Fisher chain-weighting:

Δlog(REALRESINV_Bridge_{T+1}) = Σ_i SH^i_T · Δlog(REALRESINV^i_{T+1})

(d) Combines the bridge-equation forecast with the Step-1 BVAR forecast via restricted least squares. The combining regression has no constant (both inputs are already forecasts of the same target) and constrains the weight δ to lie in [0, 1]:

Δlog(REALRESINV_t) = δ · Δlog(REALRESINV_BVAR_t) + (1 − δ) · Δlog(REALRESINV_Bridge_t) + ε_t

As more monthly data arrives during the quarter, (1 − δ) generally increases — the bridge gets more reliable, the BVAR gets less weight. After the 2023 modification, this is now weighted least squares with weight 1 / (1 + t/16)² on observations t quarters before the latest official GDP estimate, putting more weight on recent observations. The 2022 modification also drops the COVID observations (2020:Q1–Q4) from this regression for everything except consumption, foreign trade, and inventories.

Step 5 — Net exports (the special case)

Net exports get bespoke treatment because the BEA constructs them from monthly Census/BEA trade data (FT-900) in a non-bridge-equation way. Here’s the recipe for goods (services is symmetric):

(a) Construct monthly real goods imports and exports by deflating the nominal series with weighted BLS import/export price subindices (the weights are NIPA Table 4.2.5 import shares from the prior quarter — to handle the BLS’s two-year lag in weight updates).

(b) Express the contribution of goods net exports to GDP growth using the Törnqvist-approximating formula:

contgoodsnetexp_{T+1,h} = (nomgoodsexp_{T+1,h−1} / nomgdp_{T+1,h−1}) · Δlog(realgoodsexp_{T+1,h})
                       − (nomgoodsimp_{T+1,h−1} / nomgdp_{T+1,h−1}) · Δlog(realgoodsimp_{T+1,h})

where monthly nominal GDP is a splice of Macroeconomic Advisers’ MA monthly GDP and Stock–Watson’s monthly GDP.

© Fit a factor-augmented AR (no constant, so long-horizon forecasts decay to zero) to the contribution series.

(d) Separately fit factor-augmented ARs to real goods exports and real goods imports, then solve for an adjustment factor α^NXadj that reconciles the export/import forecasts with the net-exports contribution forecast.

(e) Combine the monthly-data forecast with the Step-1 BVAR forecast via the same restricted-least-squares combination as Step 4.

The gold-imports modification (March/April 2025)

This is one of the most striking recent changes. The BOP-basis goods trade measure the BEA uses for GDP and the Census-basis measure that drives the headline trade report classify gold differently. HS code 7115900530 — “Articles of precious metal, in rectangular shapes, 99.5% or more by weight of precious metal” (i.e., gold bars) — is “finished metal shapes” on a Census basis but “nonmonetary gold” on a BOP basis. When gold flows surged in early 2025, the wedge became large enough to materially distort the nowcast.

The fix: subtract BOP gold imports and exports (MNMGLD, XNMGLD in the BEA’s IDS-0182 database) from the gross goods trade aggregates. For updates after the Advance Economic Indicators (AEI) report — which gives Census-basis aggregates but doesn’t separate gold from “industrial supplies and materials” — the model runs a five-variable BVAR (CFNAI, real industrial-supplies imports ex-gold, real industrial-supplies exports ex-gold, plus aggregated imports and exports of the other five Census-basis categories) and uses Waggoner–Zha conditional forecasting to pull out the ex-gold series.

Step 6 — Consumption (no bridge equations needed)

PCE is already monthly. The trick here is timing: the monthly PCE release comes about a week after retail sales and the CPI. For the goods PCE that’s estimated via the “retail control” method, the model uses the latest growth rate of retail sales excluding autos, gas stations, and building materials as a nowcast of nominal consumption growth for the equivalent PCE bundle. It then uses CPI subindices (mapped to PCE subindices via a static crosswalk) to nowcast the deflator.

PCE goods is partitioned into 4 buckets, PCE services into 5 (since the 2017 modification, which added electricity-and-gas, U.S. travel abroad, and foreign travel in the U.S. as separate categories, motivated by the BEA’s use of utility industrial production and travel-services trade data to construct these series).

Each bucket is forecast separately and aggregated with time-T expenditure share weights:

Δlog(REALPCE_Goods_{T+1}) = Σ_{k=1..4} (NOMGOODS^k_T / Σ_j NOMGOODS^j_T) · log(realgoods_aggregate)

For PCE motor vehicles, the model uses BEA unit auto/light-truck sales data plus BEA consumer-share data (published a week before retail sales) — a different release path because the BEA doesn’t use retail sales for vehicle PCE.

Step 7 — Inventories (the monster)

Inventories are roughly half the model’s complexity by themselves. The BEA’s accounting identity is:

CIPI^i_{t,h} = ΔInventory^i_{t,h,Book} + IVA^i_{t,h}

where IVA — inventory valuation adjustment — is the negative of holding gains from inventory-price changes. The Census Bureau publishes monthly book-value inventories for some industries before the advance GDP release. Nobody publishes IVAs in real time. So:

(a) Run the price BVAR from Step 2a to forecast monthly inventory deflators using a Denton interpolation procedure (which interpolates a low-frequency series with a related high-frequency one).

(b) Run a “core quantity” BVAR over 16 monthly series — industry-level employment, real sales, industrial production, plus the ISM composite manufacturing index and its inventories subcomponent.

© Run 6 separate “block” BVARs, one per inventory industry, where the first block is shared (the 16 core series) and the second block adds the industry-specific inventory variable scaled by 6-month-lagged industry nominal sales. Block structure ensures the ISM Manufacturing Index affects manufacturing inventories but doesn’t bleed into wholesale or retail.

(d) For the “Census inventory industries” — durable manufacturing, nondurable manufacturing, merchant wholesale, retail ex-autos — use the inventory identity above to back out implied IVAs from observed book-value data plus BVAR-forecast CIPI.

(e) Run an alternative IVA model using BEA’s BLS-PPI-based methodology: combine finished + work-in-progress PPI with intermediate-materials PPI, convert to “end-of-month” then “average monthly” prices, fit a turnover pattern (the share of inventories sitting on shelves for exactly x months, with x ≤ 5 and FIFO), and fit an AR(1) to the residuals between model-implied IVAs and reported IVAs.

(f) Combine the two IVA models by jointly maximizing the sum of their log-likelihoods, assuming independent errors across industries and models. This step is essentially MLE over the unobserved IVAs.

(g) With most-likely IVAs in hand for months where Census book values exist, back out the implied monthly CIPIs. For the rest of the months, use the big block BVAR with Waggoner–Zha to fill in.

(h) For “farm” and “construction + mining + utilities + other nonfarm” inventories where no useful monthly data exists, use an AR(4) on the quarterly series.

(i) Aggregate everything using BEA’s Fisher chain-weighting of inventory stocks.

The October 2017 modification added a small but consequential wrinkle: when the BEA’s Underlying Detail Tables for the third estimate of quarter t−1 are released, they include real and nominal manufacturing-and-trade inventory levels for the first month of quarter t. The model now plugs these in directly:

IVA^i_{t,1} ≅ 12·ΔInv^i_{t,1,BEA} − 12·ΔInv^i_{t,1,Census-Book}

and treats the implied first-month IVAs as observed data going forward.

Step 8 — Fisher chain-weighting aggregation

Finally, the 13 quantity forecasts and 13 deflator forecasts are aggregated using BEA’s exact Fisher chain-weighting formula. Imports enter with a minus sign. The inventory deflator is end-of-quarter, so the aggregation uses the average of current and prior end-of-quarter prices. The output is the headline number you see on the chart.

The data stack

Inferring this from the working paper, the modifications PDF, and the Excel workbook:

  • Data layer: Haver Analytics is the upstream provider (the paper notes that “many of the series are taken directly from Haver Analytics; these series generally have an ‘@’ appearing in the series name”). Haver Analytics also seems to run the X-13ARIMA-SEATS seasonal adjustment pipeline (the modifications doc references “the X-13 algorithm implemented by Haver Analytics” for filling shutdown-month missing values).
  • Series count: ~125 monthly series in the factor model + 34 price series in the price BVAR + the 13 quarterly GDP series and their deflators + the block-BVAR inventory inputs. Realistically the model touches 200+ time series end to end.
  • Estimation: Not disclosed. The combination of state-space estimation (Kalman filter/smoother), Waggoner–Zha conditional forecasting, Bayesian VARs with Minnesota priors, and AIC-based lag selection points to either MATLAB or a custom toolkit — the use of these techniques together was historically a MATLAB hallmark in central banking. Some shops have ported this to Julia or Python in recent years; the Atlanta Fed has not said.
  • Transparency layer: A single Excel workbook (GDPTrackingModelDataAndForecasts.xlsx) with tabs for ReadMe, Factor, every subcomponent's tracking detail, historical forecasts, and the track record. This is the closest thing to "open source" — every number that goes into the live forecast is in that sheet.
  • Output layer: PDF slide deck (RealGDPTrackingSlides.pdf) auto-generated for the website, plus an RSS feed, plus the JSON powering the EconomyNow app.

A minimal Python skeleton

You can’t perfectly replicate GDPNow without a Haver subscription, but you can build the architecture. Here’s the scaffolding:

import numpy as np
import pandas as pd
from statsmodels.tsa.statespace.kalman_filter import KalmanFilter
from statsmodels.tsa.api import VAR

# --- Step 1: Quarterly BVAR over 13 GDP subcomponents (Minnesota prior) ---
def fit_minnesota_bvar(Y, lags=5, lambda_=0.2, start='1968Q1'):
    """
    Bańbura-Giannone-Reichlin (2008) Minnesota prior via dummy observations.
    Y: T x n matrix of subcomponent log-growths.
    Returns posterior mean of VAR coefficients + residual covariance.
    """
    # Build dummy observations Y_d, X_d that encode the Minnesota prior
    # Then OLS on stacked [Y; Y_d], [X; X_d]
    ...

# --- Step 2b: Single-factor DFM via Doz-Giannone-Reichlin two-step ---
def fit_dfm(Z, n_factors=1, factor_lags=3):
    """
    Z: T x N standardized monthly series, with NaNs for jagged edges.
    Returns: smoothed factor f, loadings gamma, AR coeffs rho, idio AR phi.
    """
    # 1. Initial factor: PCA with Stock-Watson missing-data EM
    f_hat = pca_with_missing(Z, n_factors)
    # 2. OLS loadings: z_it = gamma_i * f_t + eps_it
    gamma = ols_loadings(Z, f_hat)
    # 3. OLS factor AR
    rho = ols_ar(f_hat, factor_lags)
    # 4. Idiosyncratic AR(1) on residuals (2018 modification)
    phi = idio_ar1(Z - gamma @ f_hat.T)
    # 5. State-space form -> Kalman smoother for refined factor
    f_smoothed = kalman_smooth(Z, gamma, rho, phi)
    return f_smoothed, gamma, rho, phi

# --- Step 3: Factor-augmented AR with AIC lag selection ---
def factor_augmented_ar(y, f, q_range=(1, 6), r_range=(0, 3)):
    best_aic = np.inf
    best = None
    for q in range(q_range[0], q_range[1] + 1):
        for r in range(r_range[0], r_range[1] + 1):
            model = fit_far(y, f, q, r)
            if model.aic < best_aic:
                best_aic, best = model.aic, model
    return best

# --- Step 4: Bridge + BVAR combination via restricted WLS ---
def combine_bridge_bvar(y, bridge_fcst, bvar_fcst, drop_covid=True):
    """Restricted weighted least squares, weights = 1/(1 + t/16)^2."""
    if drop_covid:
        mask = ~((y.index >= '2020-01-01') & (y.index <= '2020-12-31'))
        y, bridge_fcst, bvar_fcst = y[mask], bridge_fcst[mask], bvar_fcst[mask]
    weights = 1.0 / (1.0 + np.arange(len(y))[::-1] / 16.0) ** 2
    W = np.diag(weights)
    X = np.column_stack([bvar_fcst, bridge_fcst])
    beta_unc = np.linalg.inv(X.T @ W @ X) @ X.T @ W @ y
    # Enforce sum-to-one
    e = np.ones(2)
    correction = np.linalg.inv(X.T @ W @ X) @ e * (e @ beta_unc - 1.0) / (e @ np.linalg.inv(X.T @ W @ X) @ e)
    beta = beta_unc - correction
    return np.clip(beta, 0.0, 1.0)

# --- Step 8: Fisher chain-weighting aggregation ---
def fisher_chain_aggregate(real_growths, deflator_growths, nom_shares_T, nom_shares_Tm1):
    """
    Aggregate 13 subcomponents into GDP growth using BEA's Fisher index.
    Imports get a negative sign.
    """
    laspeyres = np.exp(np.sum(nom_shares_Tm1 * real_growths))
    paasche   = np.exp(np.sum(nom_shares_T   * real_growths))
    fisher = np.sqrt(laspeyres * paasche)
    return 400.0 * (fisher - 1.0)  # SAAR

This is sketch, not implementation — the real model has more wiring around release-day logic, Waggoner–Zha conditional sampling, the IVA likelihood maximization, and a dozen edge cases. But the architecture is there.

The modifications timeline (the model is a living thing)

One underappreciated feature of GDPNow is that it changes — not during a quarter, but between quarters, with every change documented. The model evolves with the economy:

  • October 2017 — Net foreign travel and electricity/gas split out of PCE services. Computer-and-aircraft equipment now use the advance durable-goods and advance trade reports instead of waiting for the full M3. Government IPP investment finally added (it had been missing since the BEA’s 2013 NIPA revision — an “oversight” per the docs).
  • April 2018 — Idiosyncratic AR(1) added to the dynamic factor model’s measurement equation. The motivation, stated explicitly in the docs: ISM-day jumps in the nowcast were autocorrelated and predictable, which is bad if your model is supposed to be the optimal real-time estimate.
  • April 2020 — Stopped removing outliers from the factor-model inputs. The COVID-19 collapse was so large that the model’s standard outlier replacement (more than 10 IQRs from the median → replaced) was hiding signal.
  • April 2022 — COVID dummy variables added to every factor-augmented AR; max lag q reduced from 12 to 6; AR(1)-with-COVID-dummies replaced AR(4) for subcomponents with no monthly indicator; 2020 observations dropped from the bridge–BVAR combining regression for non-consumption, non-trade, non-inventory subcomponents.
  • January 2023 — The combining regression is now weighted least squares with exponential decay on past observations. Net exports and inventories now use the same combining framework (previously they did not).
  • March/April 2025 — Gold imports and exports excluded from goods-trade aggregates using the BOP measures from BEA’s IDS-0182 database. Driven by a measurable wedge between Census-basis and BOP-basis gold classifications during early 2025’s gold rally.
  • December 2025 — Two changes: (1) Data centers split from “general / financial / other” office structures (following the BEA’s September 2025 annual revision), with a new deflator built as a geometric mean of industrial-building and warehouse-construction PPIs weighted by Törnqvist nominal investment shares. (2) A special imputation rule for the October 2025 government shutdown: missing October CPI/MXPI values are filled with the geometric mean of adjacent September and November values, except for series the BLS doesn’t seasonally adjust (those go through Haver’s X-13 routine, which fills automatically).

That’s roughly one substantive update per year. None of them are cosmetic.

Performance — how good is it really?

The Atlanta Fed publishes the full track record. Since they began tracking GDP in real time in late 2011, the average absolute error of the final GDPNow forecast (made the day before the BEA’s advance release) is 0.77 percentage points, with a root-mean-squared error of 1.17 percentage points, covering 2011:Q3 through 2025:Q2.

Three honest observations from the working paper’s horse-race tables:

  1. GDPNow does not beat the Blue Chip consensus, on average. Professional forecasters with judgment still have an edge.
  2. GDPNow does beat naive statistical benchmarks — a rolling AR(2), a factor-augmented AR(2) using the CFNAI, a quarterly BVAR, and Schorfheide–Song mixed-frequency BVAR. The full tracking model has the lowest out-of-sample RMSFE of any of them (1.15 percentage points over 2000:Q1–2013:Q4).
  3. Nowcast accuracy stops improving about four weeks before the advance release. New data still moves the number, but the expected error plateaus. This is partly because the hardest subcomponents — inventories and net exports — are the ones the BEA itself estimates with the most lag and noise.

The decomposition of forecast errors is instructive: across every forecaster (GDPNow, Blue Chip, even the Fed’s Greenbook), change in private inventories and net exports contribute disproportionately to the variance. There’s a quote in the paper, originally from Larry Meyer when he was a Fed Governor, that captures it perfectly: forecasters often nail headline GDP while missing badly on the components, because of what Murray Weidenbaum called “St. Offset” — the patron saint of cancelling forecast errors. The decomposition tables show St. Offset helping Blue Chip and the Greenbook more than she helps GDPNow.

What the “no code” policy actually hides — and what it doesn’t

The Atlanta Fed’s FAQ says, plainly: “Do you share your code? At this point, no.” But the spreadsheet they publish on every update day contains:

  • Every raw monthly source-data series the model uses
  • Every estimated dynamic factor value (in the Factor tab)
  • Every bridge-equation coefficient
  • Every Step-1 BVAR-vs-bridge combination weight δ
  • Every subcomponent’s nowcast at every update for 2011:Q3 onward
  • The track record vs. BEA’s advance releases

What you can’t see in the spreadsheet:

  • The Waggoner–Zha conditional-sampling implementation
  • The Kalman filter/smoother setup for the DFM
  • The IVA-likelihood joint maximization in Step 7
  • The exact lag-selection logic and the data-snapshot pipeline
  • The release-day orchestration code (which release triggers which sub-pipeline)

In other words: the model is open; the production system is closed. From a reproducibility standpoint that’s actually a reasonable trade-off — you have everything you need to verify their work and build your own, but you don’t get a black-box you can break by running it on the wrong vintage of Haver data.

What you’d actually need to build it

If you wanted to operationalize this:

  1. A Haver Analytics or equivalent subscription — or a stitching layer over FRED + Census + BEA + BLS + ISM that handles vintages and seasonal adjustment. The latter is doable but tedious; the model assumes you have it.
  2. A state-space + Kalman + Bayesian-VAR stack. In Python: statsmodels gets you most of the way for state-space and Kalman; PyMC or a custom Minnesota-prior implementation for the BVAR; you'll likely write Waggoner–Zha yourself (it's tractable — see Karlsson 2013 for clear pseudocode). In Julia, StateSpaceModels.jl is closer to production-ready.
  3. An X-13ARIMA-SEATS wrapper for the few series you have to seasonally adjust manually (the model does this for the petroleum import price index, for example).
  4. A release-day orchestrator. This is half the engineering. The model updates whenever one of seven trigger releases lands; you need a calendar-aware scheduler that knows which releases unlock which sub-pipelines.
  5. A vintage database. Some series get revised, and the model’s IVA logic specifically uses revised inventory data when available. ALFRED is the public version of this; if you want to backtest cleanly you essentially need it.

Pat Higgins, the GDPNow creator, has done this work — and not shared the code. But the math is fully documented. The most honest description of GDPNow is that it’s an open methodology with a closed implementation, where the methodology is detailed enough that the implementation is reproducible by anyone willing to write it.

So why does it work?

The deepest design choice in GDPNow is the marriage of two econometric traditions. Bridge equations are old-school: a regression of a GDP component on a monthly indicator, basically what Lawrence Klein was doing in the 1980s. Dynamic factor models are modern: a way to extract a single “state of the economy” signal from hundreds of overlapping, jagged-edge time series. Neither, alone, is enough. Bridge equations miss the news in series that aren’t in the bridge. Factor models miss the BEA’s specific data-construction logic.

GDPNow uses the factor model to fill in the future of the monthly source data the bridge equations then turn into subcomponent forecasts, then combines those with a quarterly BVAR that has no monthly information at all but captures the long-run subcomponent correlations. The whole thing then aggregates with the BEA’s actual chain-weighting formula. Each layer compensates for what the others miss.

That’s the model. The implementation is closed. The math is open. The data is partially behind a Haver subscription. The architecture, once you see it, is unreasonably elegant for a piece of central-bank infrastructure that updates on a Tuesday afternoon, every couple of weeks, for free, in public.


References:

  • Higgins, P. (2014). “GDPNow: A Model for GDP ‘Nowcasting’.” Federal Reserve Bank of Atlanta Working Paper 2014–7.
  • Modifications to GDPNow Model (Federal Reserve Bank of Atlanta, updated December 23, 2025).
  • Giannone, D., Reichlin, L., and Small, D. (2008). “Nowcasting: The Real-Time Informational Content of Macroeconomic Data.” Journal of Monetary Economics 55(4), 665–676.
  • Bańbura, M., Giannone, D., and Reichlin, L. (2008). “Large Bayesian VARs.” ECB Working Paper 966.
  • Stock, J. and Watson, M. (2002). “Macroeconomic Forecasting Using Diffusion Indexes.” Journal of Business & Economic Statistics 20(2), 147–162.
  • Waggoner, D. and Zha, T. (1999). “Conditional Forecasts in Dynamic Multivariate Models.” Review of Economics and Statistics 81(4), 639–651.
  • Chin, D. and Miller, P. (1996). “Using Monthly Data to Improve Quarterly Model Forecasts.” Federal Reserve Bank of Minneapolis Quarterly Review 20(2), 16–33.

About the Author

Brian Curry is a Kansas City-based Data Scientist, AI expert, and founder of Vector1 Research, where he explores the frontier of Artificial Intelligence, Causal Inference, Agentic Systems, and Economic Modeling.

His work focuses on building intelligent systems that reveal the causal structures driving performance across marketing, content, and economics. He is the creator of PyCausalSim (causal discovery through simulation), Papilon (complex system optimization), Daedalus (causal and economic analysis), and Memory-Node Encapsulation (data structures for artificial episodic memory).

Related research