DEV Community

Hamza
Hamza

Posted on Originally published at tekmag.thsite.top

Craton Bolt — The Open-Source JIT-Compiled GPU SQL Engine That Compiles SQL to NVIDIA PTX at Runtime

Craton Bolt is a SQL execution engine written in pure Rust that compiles each query into a fresh NVIDIA PTX kernel at runtime, loads it via the CUDA driver, and runs it on the GPU. There is no C++ shim, no precompiled kernel library, and no FFI to a third-party query engine. The full pipeline — parse, plan, codegen, launch — is Rust on top of the raw CUDA driver API.

The project comes from Craton, a nearshore engineering shop based in Buenos Aires, and sits at github.com/craton-co/craton-bolt under the Apache 2.0 license. It is currently at version 0.7.0 and is actively developed. The authors describe it as an experiment in whether a modern Rust crate can do what cuDF has done for years — except without dragging in a massive C++ dependency tree.

Key takeaways

  • Craton Bolt is a JIT-compiled GPU SQL engine written in pure Rust, targeting NVIDIA GPUs via the CUDA driver API.
  • It compiles each query into a single PTX kernel at runtime, fusing operations to avoid intermediate memory writes.
  • Arrow-aligned device buffers enable zero-copy PCIe transfers — the GPU sees the same memory layout as the CPU.
  • Compile-time borrow checking replaces runtime memory bugs with compiler errors, a shift from typical CUDA C++ development.
  • Version 0.7.0 supports a substantial SQL surface including joins, CTEs, window functions, and set operations, but GPU string kernels remain opt-in.
  • CI does not run GPU code; correctness is validated on developer hardware. Production use is not yet recommended.
  • The project is pre-1.0 with an unstable public API, aimed at Rust-native analytics workflows rather than replacing established GPU database systems.

Why another GPU SQL engine

The analytics GPU space already has players. NVIDIA's RAPIDS suite, and cuDF in particular, has been around since 2018. Sirius, a collaboration between the University of Wisconsin-Madison and NVIDIA, recently posted record ClickBench numbers. Both are solid. Both require CUDA-toolkit-level C++ builds.

Bolt takes a different path. It targets the same problem — accelerating analytical SQL on GPUs — but tries to eliminate the integration tax that comes with heavy C++ libraries. A data engineer who wants GPU acceleration should not need to manage CMake, fight ABI mismatches, or install 2 GB of CUDA dependencies just to run a GROUP BY faster. Bolt aims to be a cargo add away. If you are already using Polars or DataFusion, adding Bolt means adding another dependency and passing Arrow buffers across the PCIe boundary.

That is a narrower ambition than cuDF. It is also a narrower scope. Bolt does not claim to replace them. It claims to show that the core of GPU-accelerated SQL can live inside a single Rust crate.

How it compiles SQL to PTX

The pipeline has four stages.

First, sqlparser-rs turns the SQL string into an AST. Bolt then builds a logical plan and a physical plan — essentially a tree of operators that will execute the query.

Second, the JIT compiler walks that physical plan and emits a single PTX program. Each operator in the plan becomes a section of PTX. Because the entire expression tree is visible at codegen time, Bolt can fuse operations that would otherwise be separate kernel launches. This is the same idea that Polars and DataFusion use on the CPU side — fuse the computation, keep intermediates in registers, write to global memory only at the end.

Third, the PTX string is passed to the CUDA driver API. The driver JIT-compiles it into SASS for the actual GPU on the system. This happens at query runtime, not at crate build time.

Fourth, the kernel launches with Arrow-aligned GPU buffers as arguments. Results come back as Arrow arrays.

The result is a system where the query shape determines the GPU code shape. Two identical queries on different datasets produce identical PTX. Two different queries produce different PTX. There is no lookup table of prebuilt kernels. The PTX is generated on demand.

The memory model: CUDA-Oxide

Bolt's other distinguishing feature is how it handles GPU memory.

Most GPU dataframe libraries treat host memory and device memory as separate domains. You copy data from one to the other, often transforming the layout in the process. cuDF does this. BlazingSQL does this. The data travels across the PCIe bus in a proprietary device format that the GPU understands but the CPU does not.

Bolt keeps Arrow's memory layout intact on the device. It allocates GPU memory using a Rust type called GpuVec<T>. This type mirrors Arrow's columnar array layout — contiguous buffers, validity bitmaps, the works. When data moves from host to device, it is a bitwise copy across PCIe. No transformation. No re-alignment.

The borrow checker adds a safety layer on top. GPU memory is accessed through GpuView<'a, T> for reads and GpuViewMut<'a, T> for writes. These are exclusive, non-Copy handles. The compiler rejects code that would create simultaneous mutable and shared access to the same GPU buffer. Use-after-free, double-free, and aliasing bugs that slip through in C++ CUDA code are caught at compile time in Rust.

This matters because GPU memory bugs are notoriously hard to debug. A segfault on the host is loud. A segfault inside a kernel that ran 400 milliseconds ago is not.

What Bolt supports

As of version 0.7.0, Bolt covers a broad chunk of standard SQL.

The core operators are all there: SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER BY, LIMIT. Joins include INNER, LEFT OUTER, RIGHT OUTER, FULL OUTER, and CROSS. Set operations cover UNION ALL, EXCEPT ALL, and INTERSECT ALL.

Advanced SQL features are supported too. CTEs work, including recursive CTEs with linear, non-linear, and mutual recursion. Derived tables and LATERAL subqueries in FROM are handled. Uncorrelated subqueries work, and there is support for a single correlated subquery in WHERE using EXISTS, NOT EXISTS, or scalar forms. VALUES acts as an inline row source. generate_series provides a table-valued function for generating sequences.

Aggregation gets the full treatment: ROLLUP, CUBE, and GROUPING SETS. Window functions run on the host with named WINDOW clauses and QUALIFY support. DISTINCT ON is available.

Scalar operations include IN, BETWEEN, CASE, CAST, COALESCE, NULLIF, and LIKE. Decimal128 has complete GPU arithmetic for addition, subtraction, multiplication, division, and comparisons, plus grouped SUM, MIN, and MAX. Date32 and Timestamp types support arithmetic including Date minus Date and Timestamp minus Timestamp with Day intervals.

String handling has two paths. Dictionary-encoded strings fold into integer membership predicates on the GPU — equality, inequality, IN, and LIKE become pure integer ops. The non-dictionary path, including LIKE matching and string transforms like UPPER, LOWER, CONCAT, SUBSTRING, and TRIM, runs on the host by default. GPU-accelerated string kernels exist behind an opt-in environment variable.

One notable gap: CI runs the full test suite using cuda-stub, which exercises zero GPU code paths. There is no GPU runner in CI. GPU correctness is validated on developer hardware. A green CI build means the host logic and codegen shapes are sound, not that the GPU kernels have been execution-tested in automation.

Performance and practical limits

Bolt does not publish benchmark numbers in its README. The project tracks them in docs/BENCHMARKS.md, but those are internal benchmarks run against specific hardware configurations, not independent third-party results. The project is pre-1.0, and the authors are clear about that in docs/LIMITATIONS.md.

The intended sweet spot is medium-sized analytical workloads — datasets that fit in GPU memory, queries that benefit from kernel fusion, and workloads where the PCIe transfer cost is amortized over significant computation. Small queries that spend more time moving data than computing it will not benefit. So far, the project targets sm_70 (Volta) and newer, requiring CUDA Toolkit 12 or later.

The comparison point is not cuDF or Sirius on raw throughput. It is integration cost. Bolt's value proposition is that a Rust project can add GPU acceleration without leaving the crate ecosystem. If you are already using Polars or DataFusion, adding Bolt means adding another dependency and passing Arrow buffers across the PCIe boundary. No new languages. No new build systems. No new abstractions to learn beyond SQL.

Where it fits in the stack

Bolt occupies a narrow lane. It is not a full database. It does not manage storage, transactions, or persistence. It is a query execution engine that takes Arrow data and SQL text and returns Arrow data. It is closest in philosophy to what DataFusion is to the CPU side of the modern data stack — a composable execution layer that plugs into existing tooling rather than replacing it.

The broader context matters. The GPU-accelerated analytics space is moving fast. Sirius recently set new ClickBench records. Starburst has been integrating cuDF into Trino. DuckDB is exploring GPU offload. The market is proving that GPU acceleration is viable for analytical workloads, but the integration story remains messy. Most solutions require significant infrastructure investment.

Bolt tries a different approach. Instead of building a complete GPU database, it builds a GPU execution engine that assumes the data is already in Arrow format and just needs to move across PCIe efficiently. The assumptions are narrower. The integration story is simpler. Whether that is enough to attract users beyond the Rust-native analytics community remains to be seen.

The idea behind Bolt is not new. JIT-compiling query plans into GPU kernels has been explored in academia for years. Projects like rNdN and various VLDB papers have demonstrated the performance potential. What is newer is the Rust angle — applying the same codegen approach inside a language that gives you memory safety and a manageable dependency graph instead of C++ and CMake.

Whether that tradeoff pays off depends on what you optimize for. If raw performance across every SQL operation is the goal, established projects with deeper CUDA expertise still lead. If the goal is reducing the friction of adding GPU acceleration to an existing Rust data stack, Bolt makes a case for itself.

The project is young. The API is unstable. Some features, like non-dictionary string operations on GPU, are still behind opt-in flags. But the architecture is sound, the code is open, and the approach — generate PTX at runtime, keep Arrow alignment on the device, let the borrow checker enforce memory safety — is a legitimate contribution to the GPU SQL conversation.

For anyone building data pipelines in Rust and looking for a way to push analytical queries onto a GPU without managing a C++ build chain, Bolt is worth watching.

Frequently asked questions

Is Craton Bolt a database?

No. It is a query execution engine. It takes SQL and Arrow data, runs the query on GPU, and returns Arrow data.

Do I need CUDA Toolkit installed?

Yes. Bolt requires CUDA Toolkit 12 or later and targets sm_70 and newer GPUs.

Can I use this in production?

The authors say no. The public API is unstable pre-1.0, and minor version bumps may break it.

How does this compare to cuDF or Sirius?

Bolt is narrower in scope. It aims to be a lighter-weight, Rust-native option for projects already in the Arrow/Rust ecosystem.

What SQL dialect does it support?

Bolt uses sqlparser-rs, which supports ANSI SQL with some extensions. The full supported surface is documented in docs/SQL_REFERENCE.md on GitHub.

References

Top comments (0)