What this is

The exact date is not predictable, and the payer's calendar beats the model

No, and the honest hit rate is about one in five. On 183,269 real invoices from a Dutch multinational's purchase-to-pay ledger (BPI Challenge 2019, CC BY 4.0), the best of five methods predicts the exact payment day 18.6% of the time — wrong more than four times in five. Gradient boosting on ten features adds 0.1 days of mean absolute error over simply looking up what that vendor did last time, which is the comparison cash-flow tools omit. What does help is free: 75.5% of settlements land on a Thursday because the payer runs payments on a schedule, and snapping any prediction to that weekday beats modelling. A quantile model asked for an 80% prediction interval delivers 64% realised coverage, so a treasury team sizing a facility on it is short of cover more often than the number implies. 13.3% of received invoices never clear inside the window and they are the slow tail, so dropping them — the tutorial default — flatters every figure.

This is a real analysis on a real dataset, not an illustration. The code is published, it runs in under two minutes, and a verification script re-runs it from scratch and fails if any headline number moves.

Every figure below is read from results.json, which is written by the analysis itself. Where the result is unflattering it is published unchanged — the findings and the limitations both come straight out of the run.

Source figures are in the currency of the data: sterling for the UK retail and wholesale sets, euro for the Portuguese bank set. Dollar amounts are converted at 1.55 USD/GBP and 1.40 USD/EUR, roughly the averages for the periods the data covers — stated assumptions, not live rates.

How this is checked

verify.py --only 23 deletes this project's results, re-runs it and diffs every published number before the page ships.

The pipeline
Findings

What the analysis found, including the results that went against us

Each of these came out of the run. None has been softened.

THE EXACT DATE IS NOT PREDICTABLE. Across 36,642 held-out invoices, the best of five methods hits the exact payment day 18.6% of the time (gradient boosting, snapped to the payment-run weekday). The category sells this as a solved problem; on real data it is wrong more than four times in five, and the honest output is a distribution rather than a date.

Settlements by weekday

Share of invoice settlements falling on each weekday. Settlement is heavily concentrated on one day because the payer runs payments on a schedule.

run.py section 3: share of clearing events falling on each weekday.

MACHINE LEARNING ADDS 0.1 DAYS OVER LOOKING UP WHAT THIS CUSTOMER DID LAST TIME. A per-vendor median lag gives MAE 13.4 days. Gradient boosting on ten features, temporally split, gives 13.3. That gap is the entire contribution of the model, and it is the comparison vendor material omits — the baseline is not a strawman, it is what a competent AP clerk already does.

How long invoices actually take

Distribution of how many days invoices actually took to clear, in weekly buckets. The spread is wide and right-skewed, which is why a single predicted date carries so little information.

run.py section 1: invoices cleared, by week of delay.

THE PAYER'S CALENDAR IS WORTH MORE THAN THE MODEL. 75.5% of settlements land on Thursday and 0.2% fall at the weekend, because a finance function runs payments on a schedule rather than continuously. Snapping any prediction to that weekday raises the exact-date hit rate by 10.3 points and costs nothing to implement. Knowing your customer's payment run beats modelling their behaviour.

Accuracy by tolerance band

Accuracy of a per-vendor lookup against gradient boosting at four tolerance bands. The two lines are close everywhere, which is the finding.

run.py sections 2 and 4: per-vendor lookup against gradient boosting.

THE STATED INTERVAL DOES NOT COVER. A quantile model asked for an 80% prediction band delivers 64% realised coverage on held-out invoices, with a median width of 27 days. A treasury team sizing a facility on that band is short of cover 16 percentage points more often than the number implies.

DROPPING THE UNPAID INVOICES FLATTERS EVERY FIGURE. 13.3% of received invoices never clear inside the window, and they are not missing at random — they are the slow tail. Complete-case analysis puts the median at 42 days; admitting the censored cases at the minimum duration they are known to have reached moves the median to at least 40 days, a shift of -2 days. That is a lower bound, not an estimate, and it moves in only one direction.

THE THING BEING PREDICTED IS NOT STABLE. In the UK statutory register, 7,897 companies have filed at least four times. Their own reported average time to pay swings by a median of 17 days between their own filings, and 56.9% swing by more than a fortnight. A forecast keyed on 'this customer pays in N days' is keyed on a number that is not stable at six-month resolution, in a panel of 10,224 companies quite separate from the ledger above.

A TEMPORAL SPLIT IS NOT OPTIONAL HERE. The model is trained on invoices received up to 2018-09-24 and tested only on later ones, so it never sees the future of the payer it is predicting. 291 test invoices belong to vendors absent from training and fall back to the global median — a shuffled split would have hidden both effects and reported a better number.

The detail

Full results tables

What each method achieves

What each method achieves
MethodMAE (days)Exact dayWithin 7 daysWithin 14 days
Global median lag21.71.1%14.9%30.8%
Per-vendor median13.44.9%43.5%68.1%
Per-vendor + weekday snap13.615.2%49.0%70.4%
Gradient boosting13.34.1%44.7%67.9%
Gradient boosting + weekday snap13.218.6%53.0%71.2%

Where the invoices go

Where the invoices go
StageCountShare of received
Purchase-order items in the log251,734
Invoice received211,379100.0%
Cleared inside the window183,29386.7%
Never cleared inside the window28,08613.3%
Usable after excluding negative and >365d lags183,26986.7%

Do companies pay at a stable speed?

Do companies pay at a stable speed?
MeasureValue
Companies with four or more filings7,897
Median swing in own reported average17 days
Companies whose own average swings by over 14 days56.9%
Companies whose own average swings by over 30 days20.7%

Limitations

Stated by the analysis, not added afterwards. A project without these is not finished.

  • This is one corporate group's accounts-payable ledger: four buying entities, one industry, one country, roughly two years. The payment-run weekday is a fact about this group's finance function, not a law of business. The UK panel is included precisely because it is a separate population, but it measures self-reported averages rather than invoice-level timing.
  • The analysis is purely predictive and nothing here is causal. The log records no dunning calls, no collection actions, no discount offers and no disputes, so it cannot say why an invoice was paid when it was, nor what would happen if anything were changed.
  • This is a buyer's purchase-to-pay ledger read from the vendor's point of view. 'Clear Invoice' is the buyer's clearing event, which is the closest observable to the day the supplier was paid but is not identical to value landing in the supplier's account.
  • The censoring correction is a bound rather than an estimate. Treating 28,085 uncleared invoices as having lasted at least until the end of the window gives a median floor, not a median. A survival model would give a point estimate at the cost of a parametric assumption this file cannot check.
  • The UK register is a live statutory service that grows continuously and accepts amended filings. Every figure from it is computed on filings dated 2026-08-08 or earlier, and the file's digest is asserted at load, so a later re-run reproduces the published window rather than silently reporting a different one.
  • Exact-day accuracy is reported against calendar days, so an invoice cleared one working day late across a weekend counts as three days out. This is the right convention for cash management, where the calendar is what matters, but it is harsher than a working-day metric and figures here are not comparable to studies using one.

Data: BPI Challenge 2019 purchase-to-pay event log, CC BY 4.0. 1,595,923 rows, 2018-01-01 to 2019-02-28.

Libraries and methods this analysis used

Read from this project's own run.py when the page was built — 489 lines of it. Not a list of everything we know; a list of what this analysis imports and calls.

12 names from pandas appear in this analysis.

  • Categorical
  • agg
  • assign
  • astype
  • dropna
  • fillna
  • groupby
  • idxmax
  • reindex
  • sort_values
  • to_numeric
  • value_counts
Verification

How every number on this page is checked

A script deletes each result file, re-runs the project and diffs the output. If a headline figure moves, the check fails, and the page does not ship. That is the only reason to believe anything on this page.

Running this method on your own data

The method above transfers; the result will not. Send us a extract and we will tell you what is forecastable in it and what is not, before anyone signs anything.