<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>DataFusion Nexus Blog</title>
        <link>https://datafusion.nexus/blog</link>
        <description>DataFusion Nexus Blog</description>
        <lastBuildDate>Thu, 23 Jul 2026 00:00:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <item>
            <title><![CDATA[DataFusion Nexus: Specialized GPU Algorithms, Now in SQL]]></title>
            <link>https://datafusion.nexus/blog/introducing-datafusion-nexus</link>
            <guid>https://datafusion.nexus/blog/introducing-datafusion-nexus</guid>
            <pubDate>Thu, 23 Jul 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Why we built a GPU query engine on top of Apache DataFusion — the problems it solves, the design principles behind it, and where it stands today.]]></description>
            <content:encoded><![CDATA[<p>DataFusion Nexus is a GPU query engine built on
<a href="https://datafusion.apache.org/" target="_blank" rel="noopener noreferrer" class="">Apache DataFusion</a>. It evaluates whole
relational physical-plan candidates and selects supported candidates for GPU
execution with <a href="https://docs.rapids.ai/api/cudf/stable/" target="_blank" rel="noopener noreferrer" class="">NVIDIA cuDF</a>. Graph
algorithms from <a href="https://docs.rapids.ai/api/cugraph/stable/" target="_blank" rel="noopener noreferrer" class="">cuGraph</a> are
explicit GPU islands callable directly from SQL, and data is read from
<a href="https://iceberg.apache.org/" target="_blank" rel="noopener noreferrer" class="">Apache Iceberg</a> tables and Parquet files — on
S3-compatible object storage or on local disk. A relational candidate that is
not selected keeps the executable DataFusion baseline. It embeds as a Rust
library inside your own service, or serves remote clients over Flight SQL.</p>
<p>Before walking through what Nexus does, this first post explains why it
exists: where today's GPU analytics stack falls short, and what we think
a fix should look like.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-problem-gpus-and-query-engines-live-in-different-worlds">The problem: GPUs and query engines live in different worlds<a href="https://datafusion.nexus/blog/introducing-datafusion-nexus#the-problem-gpus-and-query-engines-live-in-different-worlds" class="hash-link" aria-label="Direct link to The problem: GPUs and query engines live in different worlds" title="Direct link to The problem: GPUs and query engines live in different worlds" translate="no">​</a></h2>
<p>GPU libraries for data are not the missing piece — they already exist, and
they are excellent. RAPIDS ships cuDF for DataFrame operations on an
Arrow-like columnar layout, cuGraph for graph analytics, cuVS for vector
search, cuML for machine learning primitives, cuOpt for optimization. For the
workloads they target, the gap between CPU and GPU is not incremental: a heavy
join or aggregation over a large fact table, or a traversal over a graph with
tens of millions of edges, can run one to two orders of magnitude faster on a
modern GPU.</p>
<p>Yet almost none of that shows up inside the systems where enterprises actually
query their data. In practice, a team that wants GPU acceleration over its own
data ends up building a detour:</p>
<ol>
<li class=""><strong>An ETL pipeline out of the warehouse.</strong> The data an analysis needs is
spread across tables, databases, and domains — the familiar silo problem of
any lakehouse or warehouse estate. Before a GPU can touch it, someone has
to extract it, reshape it, and land it somewhere the GPU job can read.</li>
<li class=""><strong>A notebook-shaped job at the end of the pipeline.</strong> The GPU ecosystem
grew up around data science, not backend services. cuDF and cuGraph have
clean Python APIs, but they are libraries you <em>program against</em>, not
engines you <em>query</em>. So the GPU work becomes a scheduled script: load these
files, run these operations, write the result back.</li>
</ol>
<p>The result inherits the worst properties of both halves. Latency is measured
in pipeline runs, not query response times. The set of questions you can ask
is frozen at whatever the script was written to compute — there is no ad-hoc
query. Each new question means new glue code, each handoff between processes
means another serialization of intermediate data, and an expensive GPU sits
idle between batch windows. The common workaround — a dedicated graph database
here, a OLAP database there, each with its own copy of the data — only
multiplies the silos and the synchronization pipelines.</p>
<p>Meanwhile, the modern OLAP engines that do fit inside backend services—DataFusion,
DuckDB, and their peers—earned that fit through years of careful engineering
and iterative refinement. Full SQL support, projection pruning, predicate pushdown,
statistics-based planning, catalog integration, lakehouse table formats. None
of that work is GPU-specific, and none of it exists in the GPU library world.</p>
<p>So the situation, simplified, is this: <strong>the query-engine world has the
infrastructure but not the silicon, and the GPU world has the silicon but not
the infrastructure.</strong> Nexus is an attempt to close that gap without rebuilding
either side.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="why-now">Why now<a href="https://datafusion.nexus/blog/introducing-datafusion-nexus#why-now" class="hash-link" aria-label="Direct link to Why now" title="Direct link to Why now" translate="no">​</a></h2>
<p>Two developments make this the right moment to try.</p>
<p><strong>Single-GPU capacity crossed a threshold.</strong> A modern workstation-class GPU
offers up to 96 GB of VRAM and nearly two terabytes per second of memory
bandwidth, at a fraction of the cost of a top-tier LLM inference system.
Working sets that used to demand a scale-out CPU cluster — or a dedicated
graph database — now fit on one device: the
<a class="" href="https://datafusion.nexus/cugraph/demo-dataset">45-million-edge citation graph</a> used throughout the
cuGraph documentation loads alongside its metadata tables with room to spare,
and our published TPC-H SF100 run peaks below 60 GB of device memory. And
that scale is where most enterprises actually live.<sup><a href="https://datafusion.nexus/blog/introducing-datafusion-nexus#user-content-fn-1-77a163" id="user-content-fnref-1-77a163" data-footnote-ref="true" aria-describedby="footnote-label" class="anchorTargetStickyNavbar_Vzrq">1</a></sup> They will never buy a
top-tier AI server to run database queries; what they need — a mature
developer ecosystem, and a GPU with enough VRAM to hold the working set at a
price they can justify — only recently came to exist at once. At that scale
the interesting question is no longer "how do we shard this across GPUs?"
but "why does the query engine still route everything through the CPU?"</p>
<p><strong>DataFusion made the engine extensible at the right layer.</strong> DataFusion is
not just a query engine; it is a query engine <em>library</em>, with a public,
composable physical-plan representation. A GPU backend does not need to
reimplement SQL parsing, logical optimization, catalogs, or the DataFrame
API — it can accept DataFusion's physical plan and select a whole relational
candidate when its native contract is met.</p>
<p>This layer is also where the memory math above actually holds up. An
enterprise lakehouse can run to terabytes or beyond — past any single card's
VRAM — but an ad-hoc query rarely needs more than a few columns and the rows
that survive a selective filter: a date range, one tenant, one region. The
bytes that must reach GPU memory are usually a small fraction of the
table<sup><a href="https://datafusion.nexus/blog/introducing-datafusion-nexus#user-content-fn-2-77a163" id="user-content-fnref-2-77a163" data-footnote-ref="true" aria-describedby="footnote-label" class="anchorTargetStickyNavbar_Vzrq">2</a></sup> — <em>if</em> the engine can figure out which fraction before reading
anything. That is exactly what a mature query-engine library does:
projection pruning drops the unread columns, predicate pushdown and
Parquet/Iceberg statistics skip the row groups and files that cannot match,
and only the surviving bytes are handed to the GPU. Without
that planning, "load it onto the GPU" means loading a terabyte you mostly
throw away; with it, tens of gigabytes — the difference between fitting on
one card and not.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-nexus-is">What Nexus is<a href="https://datafusion.nexus/blog/introducing-datafusion-nexus#what-nexus-is" class="hash-link" aria-label="Direct link to What Nexus is" title="Direct link to What Nexus is" translate="no">​</a></h2>
<p>DataFusion Nexus is a physical optimizer rule plus a native execution engine —
not a replacement for DataFusion, and not a universal GPU port of it. When a
query is planned, Nexus evaluates the exact DataFusion physical candidate for
scans, filters, projections, joins, aggregations, sorts, and window functions
over the common relational types, then lowers selected candidates into its own
cuDF plan. Every decision is local and reported: an unsupported candidate, or
one not selected by an enabled cost rule, leaves the executable DataFusion
baseline intact. A caller that needs a final plan without DataFusion CPU
execution expresses that as a requirement on the completed physical plan, not as a different candidate
policy. Iceberg follows the same model: one unified scan owns both its native
facts and its executable CPU delegate.</p>
<p>Around that core, five design decisions define the project.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="a-library-that-lives-inside-your-backend">A library that lives inside your backend<a href="https://datafusion.nexus/blog/introducing-datafusion-nexus#a-library-that-lives-inside-your-backend" class="hash-link" aria-label="Direct link to A library that lives inside your backend" title="Direct link to A library that lives inside your backend" translate="no">​</a></h3>
<p>Nexus follows DataFusion's own philosophy: it is a library before it is a
server. Embedded in a Rust process, the entire engine — DataFusion planning,
the GPU executor, the Iceberg readers — runs inside your service as a single
process. There is a Flight SQL server for remote clients, but the embedded
path is the one we consider primary, because it removes the tax every
"database over there" architecture pays: query results do not cross a
network, do not pass through a driver, and are not serialized and
deserialized between your query engine and your application logic. A handler
that returns a large result set hands you Arrow batches in your own address
space; if you chase zero-copy all the way down, nothing in the design stops
you from serving memory-mapped data.</p>
<p>Being a Rust library matters beyond raw copies. High-performance backends are
increasingly written in Rust on Tokio, and Nexus drops into that ecosystem as
a crate: your axum or tonic service can own a session, register tables, and
<code>await</code> query streams like any other async source. (One honest caveat: the
GPU work itself is not event-driven — device execution occupies real
threads — so Nexus integrates with the async runtime rather than pretending
kernel launches are <code>async</code> all the way down.) And because it is your
process, deep customization needs no plugin API or fork: register your own
DataFusion table providers and UDFs next to the GPU path, intercept planning
reports, or wire admission decisions into your service's own backpressure.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="gpu-capabilities-compose-in-sql-and-data-stays-on-the-gpu">GPU capabilities compose in SQL, and data stays on the GPU<a href="https://datafusion.nexus/blog/introducing-datafusion-nexus#gpu-capabilities-compose-in-sql-and-data-stays-on-the-gpu" class="hash-link" aria-label="Direct link to GPU capabilities compose in SQL, and data stays on the GPU" title="Direct link to GPU capabilities compose in SQL, and data stays on the GPU" translate="no">​</a></h3>
<p>The lesson of the ETL detour is that fragmentation — of languages, processes,
and copies — is the real cost. So in Nexus, GPU capabilities beyond relational
SQL are exposed <em>inside</em> SQL, as table functions. A cuGraph traversal is a
relation you can join, filter, and aggregate like any other:</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfbdb6;--prism-background-color:#10141c"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#bfbdb6;background-color:#10141c"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfbdb6"><span class="token keyword" style="color:#ff8f40">CREATE</span><span class="token plain"> </span><span class="token keyword" style="color:#ff8f40">VIEW</span><span class="token plain"> lstm_target </span><span class="token keyword" style="color:#ff8f40">AS</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfbdb6"><span class="token plain"></span><span class="token keyword" style="color:#ff8f40">SELECT</span><span class="token plain"> paper_id </span><span class="token keyword" style="color:#ff8f40">AS</span><span class="token plain"> vertex </span><span class="token keyword" style="color:#ff8f40">FROM</span><span class="token plain"> papers </span><span class="token keyword" style="color:#ff8f40">WHERE</span><span class="token plain"> title </span><span class="token operator" style="color:#f29668">=</span><span class="token plain"> </span><span class="token string" style="color:#aad94c">'Long short-term memory'</span><span class="token punctuation" style="color:#f29668">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfbdb6"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfbdb6"><span class="token plain"></span><span class="token keyword" style="color:#ff8f40">SELECT</span><span class="token plain"> b</span><span class="token punctuation" style="color:#f29668">.</span><span class="token plain">path_index</span><span class="token punctuation" style="color:#f29668">,</span><span class="token plain"> b</span><span class="token punctuation" style="color:#f29668">.</span><span class="token plain">distance</span><span class="token punctuation" style="color:#f29668">,</span><span class="token plain"> p</span><span class="token punctuation" style="color:#f29668">.</span><span class="token keyword" style="color:#ff8f40">year</span><span class="token punctuation" style="color:#f29668">,</span><span class="token plain"> p</span><span class="token punctuation" style="color:#f29668">.</span><span class="token plain">title</span><br></div><div class="token-line" style="color:#bfbdb6"><span class="token plain"></span><span class="token keyword" style="color:#ff8f40">FROM</span><span class="token plain"> cugraph_bfs</span><span class="token punctuation" style="color:#f29668">(</span><span class="token string" style="color:#aad94c">'citation_edges'</span><span class="token punctuation" style="color:#f29668">,</span><span class="token plain"> </span><span class="token number" style="color:#d2a6ff">2896457183</span><span class="token punctuation" style="color:#f29668">,</span><span class="token plain"> </span><span class="token string" style="color:#aad94c">'src'</span><span class="token punctuation" style="color:#f29668">,</span><span class="token plain"> </span><span class="token string" style="color:#aad94c">'dst'</span><span class="token punctuation" style="color:#f29668">,</span><span class="token plain"> </span><span class="token boolean" style="color:#39bae6">NULL</span><span class="token punctuation" style="color:#f29668">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfbdb6"><span class="token plain">                 </span><span class="token string" style="color:#aad94c">'{"output_mode":"path",</span><br></div><div class="token-line" style="color:#bfbdb6"><span class="token string" style="color:#aad94c">                   "target_vertices_table":"lstm_target",</span><br></div><div class="token-line" style="color:#bfbdb6"><span class="token string" style="color:#aad94c">                   "target_vertex_col":"vertex"}'</span><span class="token punctuation" style="color:#f29668">)</span><span class="token plain"> b</span><br></div><div class="token-line" style="color:#bfbdb6"><span class="token plain"></span><span class="token keyword" style="color:#ff8f40">JOIN</span><span class="token plain"> papers p </span><span class="token keyword" style="color:#ff8f40">ON</span><span class="token plain"> p</span><span class="token punctuation" style="color:#f29668">.</span><span class="token plain">paper_id </span><span class="token operator" style="color:#f29668">=</span><span class="token plain"> b</span><span class="token punctuation" style="color:#f29668">.</span><span class="token plain">vertex</span><br></div><div class="token-line" style="color:#bfbdb6"><span class="token plain"></span><span class="token keyword" style="color:#ff8f40">ORDER</span><span class="token plain"> </span><span class="token keyword" style="color:#ff8f40">BY</span><span class="token plain"> b</span><span class="token punctuation" style="color:#f29668">.</span><span class="token plain">path_index</span><span class="token punctuation" style="color:#f29668">;</span><br></div></code></pre></div></div>
<p>This query finds the shortest citation path from BERT (2018) back to the LSTM
paper (1997) over a 45-million-edge citation network. Both directions of the
composition matter. Upstream, SQL defines the graph the GPU sees: any view
over an edge-shaped relation can be passed to a <code>cugraph_*</code> function, so "run
PageRank over only the 2015–2020 subgraph" is a <code>CREATE VIEW</code> away, not a new
export pipeline. The view is nothing more than a named query — no data moves
when it is created; the rows behind it are read into GPU memory when a query
that uses it runs, and freed when that query completes. Downstream, the
algorithm's output is ordinary rows, enriched by joining back to the <code>papers</code>
table in the same statement — no second process, no intermediate files, and
intermediate data stays on the device between the relational and graph
stages.</p>
<p>Twenty-three cuGraph algorithms — BFS, SSSP, PageRank, Louvain, betweenness,
connected components, and more — are
<a class="" href="https://datafusion.nexus/cugraph/algorithms">documented and callable this way today</a>, each with
runnable examples. The same pattern is how the surface will grow: <code>cuvs_*</code>
table functions for GPU vector search are in progress, on exactly the same
contract.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="lakehouse-native-not-sidecar">Lakehouse-native, not sidecar<a href="https://datafusion.nexus/blog/introducing-datafusion-nexus#lakehouse-native-not-sidecar" class="hash-link" aria-label="Direct link to Lakehouse-native, not sidecar" title="Direct link to Lakehouse-native, not sidecar" translate="no">​</a></h3>
<p>Enterprises are converging on open table formats precisely to stop copying
data between engines. A GPU engine that requires its own ingestion format
would recreate the problem it set out to solve. Nexus therefore reads Iceberg
tables from REST and AWS Glue catalogs directly: table metadata drives file
selection at plan time, predicates are pushed into the Iceberg scan, and
KvikIO reads the surviving Parquet bytes from S3-compatible object storage
into GPU memory. The table your other engines query is the same table the GPU
reads — no export, no second copy to keep in sync.</p>
<p>Being a good lakehouse citizen also means a clear contract about what Nexus
will <em>never</em> do to your data: it does not write it. There is no INSERT,
UPDATE, DELETE, or COPY; no table Nexus exposes can be written into; and
nothing ever commits back to Iceberg or touches the files in storage. DDL
exists, but it is session-scoped metadata, not data: <code>CREATE EXTERNAL TABLE</code>
registers a pointer to Parquet files that already exist, and <code>CREATE VIEW</code>
saves a query definition — both live in an in-memory workspace overlay that
keeps the source catalogs read-only and disappears with the process. The data
behind a view is read into GPU memory only when a query that references it
executes, and is freed when that query completes. The deliberate exceptions
are the obvious ones: results are returned to the caller as host Arrow
batches, the opt-in source cache keeps scan bytes on local disk to accelerate
repeat reads, and a <code>CREATE TABLE ... AS</code> snapshot in the local workspace is
held in host memory for the session. Your lakehouse remains the system of
record; Nexus is a lens over it, not a second writer to it.</p>
<p>The same native reader also serves plain Parquet on local disk, registered
with ordinary <code>CREATE EXTERNAL TABLE</code> statements. That path matters more than
it sounds: when latency is the constraint, local NVMe is the fastest way to
feed the GPU, and it needs no catalog at all. One honesty note on I/O either
way: on hosts without GPUDirect Storage — which includes the cloud instances
we develop and benchmark on — KvikIO runs in its compatibility mode, staging
reads through a host-memory bounce buffer rather than DMA-ing straight into
the device. The programming model is the same; the "storage to GPU" arrow in
the diagram hides a hop through host RAM.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="explainable-planning-structured-errors">Explainable planning, structured errors<a href="https://datafusion.nexus/blog/introducing-datafusion-nexus#explainable-planning-structured-errors" class="hash-link" aria-label="Direct link to Explainable planning, structured errors" title="Direct link to Explainable planning, structured errors" translate="no">​</a></h3>
<p>A hybrid CPU/GPU engine has a failure mode all its own: a query runs on a
different execution domain than its owner expected and nobody knows why. We
consider this a contract problem, not a logging problem. Nexus records both
candidate selection evidence and the disposition of the exact final plan. You
can ask the question before running anything:</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfbdb6;--prism-background-color:#10141c"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#bfbdb6;background-color:#10141c"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfbdb6"><span class="token keyword" style="color:#ff8f40">SELECT</span><span class="token plain"> row_kind</span><span class="token punctuation" style="color:#f29668">,</span><span class="token plain"> gpu_path</span><span class="token punctuation" style="color:#f29668">,</span><span class="token plain"> candidate_shape</span><span class="token punctuation" style="color:#f29668">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfbdb6"><span class="token plain">       reason_code</span><span class="token punctuation" style="color:#f29668">,</span><span class="token plain"> remedy_code</span><span class="token punctuation" style="color:#f29668">,</span><span class="token plain"> remedy</span><span class="token punctuation" style="color:#f29668">,</span><span class="token plain"> coverage_json</span><br></div><div class="token-line" style="color:#bfbdb6"><span class="token plain"></span><span class="token keyword" style="color:#ff8f40">FROM</span><span class="token plain"> nexus_explain_coverage</span><span class="token punctuation" style="color:#f29668">(</span><span class="token string" style="color:#aad94c">'SELECT l_returnflag, sum(l_quantity)</span><br></div><div class="token-line" style="color:#bfbdb6"><span class="token string" style="color:#aad94c">                             FROM lineitem GROUP BY l_returnflag'</span><span class="token punctuation" style="color:#f29668">)</span><span class="token punctuation" style="color:#f29668">;</span><br></div></code></pre></div></div>
<p>The summary and candidate rows come back as columns and JSON, not prose:
<code>gpu_path</code> is <code>native</code>, <code>partial_native</code>, <code>cpu</code>, or <code>rejected</code>, while each
non-selected candidate carries a stable reason and actionable remedy. The
summary JSON retains the complete evidence; Flight SQL users can request the
same projection with <code>EXPLAIN GPU &lt;query&gt;</code>. A capability miss is not itself a
planning error. Errors cross the DataFusion boundary the same way — as typed
values with stable identity rather than log text.</p>
<p>This matters for the engineers operating the system, and it matters just as
much for the agents increasingly sitting between users and data. An agent
working against a Nexus session does not have to guess at the engine's
behavior: it can call <code>gpu_describe_function(...)</code> to read an execution
function's descriptor, <code>gpu_validate_call(...)</code> with a versioned envelope to
statically check named relations and options before spending GPU time on it,
and <code>nexus_explain_coverage(...)</code> to learn whether a query will hit the fast
path. As agents become a primary consumer of data infrastructure — issuing
more queries, and more varied ones, than the dashboards before them —
machine-readable contracts like these are how an engine earns a place under
them.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="gpu-memory-as-a-planned-resource">GPU memory as a planned resource<a href="https://datafusion.nexus/blog/introducing-datafusion-nexus#gpu-memory-as-a-planned-resource" class="hash-link" aria-label="Direct link to GPU memory as a planned resource" title="Direct link to GPU memory as a planned resource" translate="no">​</a></h3>
<p>GPU memory is the scarcest resource in the system, and "try it and catch the
OOM" is not a serving strategy. Integrating at the physical-plan layer gives
Nexus a better option: because planning already knows which columns, files,
and Parquet row groups a scan will touch, the engine can estimate the size of
a query's reads <em>before issuing them</em>, and use that estimate for admission
and scheduling. In the opt-in bounded mode, each query is planned against an
explicit device-memory budget: shapes without a provable memory contract are
rejected at admission with a structured reason, admitted queries receive
their reservation before execution, and runtime pressure is absorbed by
bounded chunk-split retries. A query that exhausts its retries fails with
structured facts about what it needed — not an opaque CUDA error that takes
the process down.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="where-it-stands-today">Where it stands today<a href="https://datafusion.nexus/blog/introducing-datafusion-nexus#where-it-stands-today" class="hash-link" aria-label="Direct link to Where it stands today" title="Direct link to Where it stands today" translate="no">​</a></h2>
<p>Correctness first: Nexus plans and executes the full TPC-H and TPC-DS suites
at scale factor 100 on a single GPU, with results matching CPU DataFusion
query for query. The <a class="" href="https://datafusion.nexus/reference/benchmarks">benchmark pages</a> publish the
per-query timings and full harness configuration for anyone who wants them.
We deliberately do not lead this post with those speedup numbers, because we
do not think they are the reason to adopt Nexus: the suites run against local
Parquet on one card, and an organization whose relational workload is large
enough to hurt on a modern CPU engine usually has far more data than one
GPU's memory — a scale Nexus, with no cross-GPU execution, does not chase.</p>
<p>The workload where a 96 GB card changes daily practice is graph. Traditional
query engines have no native graph search — a multi-hop traversal becomes a
tower of self-joins or a recursive CTE that falls over at depth — so
organizations that need one set up a separate graph database and feed it
with, once again, an ETL pipeline and a second copy of the data. That is
exactly the detour this project exists to remove: with cuGraph behind SQL
table functions, BFS, shortest paths, PageRank, community detection, and the
rest run on the GPU over graphs with tens of millions of edges, on the same
tables the rest of the query touches. We have not yet published an
end-to-end graph benchmark — one that measures the full query wall time,
graph construction and SQL enrichment included, at enterprise graph scale
against both a CPU engine and a dedicated graph database. That suite is in
preparation and will get its own post.</p>
<!-- -->
<p>In the spirit of setting expectations honestly, the current limitations are
just as concrete:</p>
<ul>
<li class=""><strong>A subset of Arrow types.</strong> Native execution covers the common relational
types — booleans, integers, floats, <code>Decimal128</code>, strings, dates,
timestamps, and durations. Nested and binary types and most list shapes
stay on the CPU path; on Iceberg scans, an unsupported projected type fails
planning instead.</li>
<li class=""><strong>Single-GPU queries.</strong> Independent queries can be placed on different
devices, but one query does not exchange data across GPUs.</li>
<li class=""><strong>No disk spill.</strong> A query's working set must fit the device memory budget;
Nexus does not spill intermediate state to host memory or disk (there is no
integration with out-of-core executors such as
<a href="https://github.com/NVIDIA/cuCascade" target="_blank" rel="noopener noreferrer" class="">cuCascade</a>). Bounded admission and
chunk-split retries manage pressure within the budget; they do not lift it.</li>
<li class=""><strong>No GPUDirect Storage in our tested environments.</strong> KvikIO currently runs
in compatibility mode on the instances we validate on, so reads — local
NVMe or S3 — stage through a host-memory bounce buffer on the way to the
device.</li>
<li class=""><strong>Parquet only</strong>, and Iceberg merge-on-read support is partial: position
deletes are applied natively (not yet on a fast path), while equality
deletes and delete vectors are unsupported. The unified Iceberg scan retains
its executable DataFusion CPU delegate when native acceleration is not
selected.</li>
<li class=""><strong>Read-only, by design.</strong> There is no INSERT, UPDATE, DELETE, or COPY, and
no path that writes to Iceberg or to storage. If your workflow needs to
persist query output back to the lakehouse, that is another engine's job.</li>
<li class=""><strong>SQL in, Arrow out.</strong> Queries enter as SQL text through an embedded
DataFusion session or Flight SQL; there is no Substrait plan input.</li>
</ul>
<p>The <a class="" href="https://datafusion.nexus/">documentation</a> states each boundary precisely, and
<code>nexus_explain_coverage</code> will tell you where any specific query lands.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="getting-started">Getting started<a href="https://datafusion.nexus/blog/introducing-datafusion-nexus#getting-started" class="hash-link" aria-label="Direct link to Getting started" title="Direct link to Getting started" translate="no">​</a></h2>
<p>Nexus embeds as a Rust library in a DataFusion session, or runs as a Flight
SQL server for remote clients. The <a class="" href="https://datafusion.nexus/integration">integration guide</a>
covers both paths, the <a class="" href="https://datafusion.nexus/cugraph">cuGraph SQL API</a> documents every graph
function with runnable examples over a public citation-network dataset, and
the <a class="" href="https://datafusion.nexus/build">build guide</a> covers source builds and the Docker image.</p>
<p>Once the server is up, here is the experiment we would most like you to try —
and the one we think the design rewards. Point an agent at your own lakehouse
and let it wander. The <a class="" href="https://datafusion.nexus/cugraph/algorithms">twenty-three cuGraph algorithms</a>
now callable from SQL unlock graph analyses that a CPU query engine could never
perform directly. Examples include identifying who sits on the most shortest
paths between two business units, finding which accounts form a tightly-knit
community, and measuring how far a compromised identity can reach in six hops. On a CPU workload those are the
questions you <em>can't</em> ask directly — they become a graph database procurement, an ETL
pipeline, and a quarter of glue code, so they quietly fall off the roadmap.
Behind a <code>cugraph_*</code> table function, over the tables you already have, they
are a <code>SELECT</code>. The machine-readable contracts described above are what make
this safe to hand to an agent: it can read an execution function's descriptor with
<code>gpu_describe_function(...)</code>, statically check a versioned call envelope with
<code>gpu_validate_call(...)</code> before spending GPU time, and ask
<code>nexus_explain_coverage(...)</code> whether the query it just wrote lands on the
fast path — so the exploration converges on queries that actually run on the
GPU rather than guessing.</p>
<p>When that wandering surfaces a query worth keeping, promote it. Register the
tables it touches, pin the SQL as a named workload on the Flight SQL server,
and run it against the CPU baseline on the same data. This is the loop the
whole architecture is built for: the interesting query and the production
workload are the same SQL, over the same lakehouse table, with no export step
between them. And it is the answer we are most curious about — not whether the
TPC-H numbers hold, but whether, turned loose on <em>your</em> graph at <em>your</em> scale,
Nexus lets you ask a question you had written off as too expensive to ask. If
you run that experiment, tell us what you found: the shape of the query, the
wall time against your old path, and whether it changed what you were willing
to ask. That is the feedback we are building toward.</p>
<p>GPU-accelerated SQL is an active space, and deservedly so. What we have not
seen elsewhere, and what Nexus is really about, is putting the <em>whole</em> GPU
data stack — relational execution today, graph algorithms today, vector
search next — behind one SQL surface, over the lakehouse and Parquet data you
already have, embeddable in the service you already run. If this is the kind
of system you want, we would love for you to try Nexus, file issues, and tell
us what breaks. The
<a href="https://github.com/DataFusion-Nexus/datafusion-nexus" target="_blank" rel="noopener noreferrer" class="">GitHub repository</a> is
the front door.</p>
<!-- -->
<section data-footnotes="true" class="footnotes"><h2 class="anchor anchorTargetStickyNavbar_Vzrq sr-only" id="footnote-label">Footnotes<a href="https://datafusion.nexus/blog/introducing-datafusion-nexus#footnote-label" class="hash-link" aria-label="Direct link to Footnotes" title="Direct link to Footnotes" translate="no">​</a></h2>
<ol>
<li class="anchorTargetStickyNavbar_Vzrq" id="user-content-fn-1-77a163">
<p>Two independent looks at real fleets agree on the order of magnitude.
Analyzing BigQuery customers, Jordan Tigani reports that the vast
majority store less than a terabyte in total
(<a href="https://motherduck.com/blog/big-data-is-dead/" target="_blank" rel="noopener noreferrer" class=""><em>Big Data is Dead</em></a>,
MotherDuck, 2023). In the Amazon Redshift fleet, most tables hold fewer
than a million rows, and 98% hold fewer than a billion (van Renen et
al., <a href="https://www.vldb.org/pvldb/vol17/p3694-saxena.pdf" target="_blank" rel="noopener noreferrer" class=""><em>Why TPC Is Not Enough: An Analysis of the Amazon Redshift
Fleet</em></a>, PVLDB
17(11), 2024, Table 8). <a href="https://datafusion.nexus/blog/introducing-datafusion-nexus#user-content-fnref-1-77a163" data-footnote-backref="" aria-label="Back to reference 1" class="data-footnote-backref">↩</a></p>
</li>
<li class="anchorTargetStickyNavbar_Vzrq" id="user-content-fn-2-77a163">
<p>The same two studies quantify this. Among paying BigQuery customers,
90% of queries processed less than 100 MB of data (Tigani, 2023). In
the Redshift fleet, the median query uses 0.6 GB of memory and the
99th-percentile query 21.4 GB (van Renen et al., 2024, Table 6) —
comfortably inside one card's VRAM. <a href="https://datafusion.nexus/blog/introducing-datafusion-nexus#user-content-fnref-2-77a163" data-footnote-backref="" aria-label="Back to reference 2" class="data-footnote-backref">↩</a></p>
</li>
</ol>
</section>]]></content:encoded>
            <category>announcement</category>
        </item>
    </channel>
</rss>