This experimental DuckDB patch tries a short adjacent scan before falling back to DuckDB's existing exponential-plus-binary search.
An ASOF join answers questions such as:
- Which market quote was active when a trade happened?
- Which exchange rate was current when a payment arrived?
- Which machine configuration was active when a sensor reading was recorded?
For ordered, dense time-series data, consecutive left-side timestamps often match consecutive or nearby right-side rows. The unmodified implementation performs a logarithmic search for each match. This patch remembers whether the previous match advanced by at most four rows. If so, the next probe checks up to four adjacent rows first.
If the correct boundary is not found within those four checks, execution falls back to the original exponential-plus-binary search. The shortcut therefore targets dense local movement without removing the general search path.
The patch modifies only:
src/execution/operator/join/physical_asof_join.cpp
It adds task-local state named adjacent_probe_likely, a four-row adjacent-probe limit, exact comparisons on every adjacent step, and the unchanged logarithmic fallback.
Base DuckDB commit:
5366dc3925ce0f981c2110cf4bf8e39fa1dd6fde
Patch SHA-256:
c7aef68b0974162830f0ef8d16d60ad009fe719a58b12e814f0e110517921c45
The candidate was built in Release mode on arm64 macOS with Apple Clang 21 and CMake 3.31.3. The candidate binary SHA-256 was:
1f7a086c0c65f83a7760a08990a330df105f2b040710467c69d1bb1e8c936d55
Correctness checks included:
- Six frozen evaluator cases.
- Ten semantic/schema cases at one thread and four threads.
- A direct baseline-versus-candidate ASOF differential covering
>=,>,<=, and<, duplicate timestamps, NULLs, equality prefixes, dense probes, and sparse probes. - Exact output hashes for every timed workload.
Timing used two warm-up pairs followed by nine paired baseline/candidate trials. Each timed block executed its SQL workload ten times. Trial order was varied using fixed seeds. The primary exploratory metric was the median of the nine within-pair baseline_time / candidate_time ratios.
| Workload | Rows/pattern | Paired median | Approx. runtime reduction | Candidate wins |
|---|---|---|---|---|
| Dense contiguous | 1M left, 1M right; adjacent timestamps | 1.1443x | 12.6% | 8/9 |
| Sparse | 1K left, 1M right; jumps of 1,000 | 1.0068x | 0.7% | 5/9 |
| Held-out mixed | Dense runs separated by large jumps | 1.0192x | 1.9% | 8/9 |
| Held-out bursty | Mostly adjacent with medium/large gaps | 1.0058x | 0.6% | 5/9 |
This is a promising narrow result, not a production-ready or general DuckDB speedup.
The dense synthetic workload showed a strong exploratory improvement, but the predeclared held-out promotion rule required at least 1.05x on both held-out workloads, or 1.10x on one with no regression on the other. The mixed and bursty workloads did not pass that gate. All timings above are therefore non-claim-bearing exploratory measurements.
The next useful test is a clean, quiet-machine benchmark on a representative trade/quote or other dense temporal workload, followed by Linux and customer-hardware validation. Do not infer customer savings from these synthetic results.
01_adaptive_asof.patch— exact source patch with inline comments.02_workloads.sql— the four performance workloads and the differential correctness workload.03_results.json— compact evidence summary and claim limits.
Prepared and signed by GPT on 2026-08-13.
DuckDB is licensed under the MIT License. This experimental patch is provided for evaluation without warranty.