Requires
feature = "async". AsyncConnection and AsyncDatabase re-export at the crate root.Connection so DuckDB never blocks the
async executor: every call dispatches to tokio::task::spawn_blocking. Because a borrowing
DuckResult is not Send, the async methods materialize — they
return an owned ResultSet.
AsyncConnection is Clone + Send + Sync; clones share one connection serialized by an internal
mutex.
Methods
Open on a blocking thread.
Run
;-separated statements, discarding results.Run one statement, materialize the result.
Positional-parameterized execute. Binds are owned
DuckValues so they are Send.The primitive every other method builds on — run anything (a transaction, a prepared
statement) on the blocking thread.
Step the query one DuckDB task per dispatch, yielding to the runtime between tasks — see below.
Run a closure against a bulk-insert
Appender; the appender holds raw FFI
pointers, so it never leaves the closure.Wrap an existing
Connection; recover it if this is the last clone (Err(self) otherwise).Mutex-free control — works while a query holds the connection mutex on a blocking thread.
Running a transaction
A transaction must not span an.await. Keep the whole unit inside with_connection, which runs
on one blocking dispatch:
execute_pending
execute_pending is the async form of pending execution:
rather than run the whole query in one blocking call, each execute_task runs on its own blocking
dispatch, so a long query neither monopolizes a blocking thread nor blocks cancellation.
Cancellation (cancel-on-drop)
The query futures request interruption of the native query if the future is dropped. Because
spawn_blocking tasks cannot be aborted, the drop signals DuckDB to interrupt and lets the
blocking task wind down — it does not stop native work instantly. The connection becomes usable
again once that task releases the mutex. query_control() / interrupt() / progress() go
through a mutex-free control source, so they work while a query holds the connection mutex
on a blocking thread. Generation scoping
makes a late interrupt safe — a finished query’s control is stale.AsyncDatabase
AsyncDatabase mirrors Database for sharing one database across async
connections:
from_database(db) / database() bridge to and from a sync Database. Like AsyncConnection,
these methods panic outside a Tokio runtime.
See also
- Pooling — and
AsyncPool, which combines both features. - Result sets — what every async query returns.
- Transactions — the
.await-boundary rule.