SQLx in Rust: pooled async SQL, and the SQLite feature that drops the zero-unsafe rule
🧰 The Rust SQL Toolkit. An async, pure Rust SQL crate featuring compile-time checked queries without a DSL. Supports PostgreSQL, MySQL, and SQLite.
At a glance
- What is it?
- SQLx is an async Rust SQL toolkit where you write the queries and the crate handles pooling, per-connection statement caching and row streaming, with compile-time checking offered but not imposed. The interesting edges are all in the feature flags: the SQLite driver reintroduces unsafe and the C library, the mysql feature alone will not do RSA auth, and MSSQL is removed while still listed.
- Who is it for?
- SQLx fits a Rust service that owns its SQL and wants pooling, statement caching and row streaming without an ORM, and does not fit a team that needs SQL Server or a dependency list with no unsafe in it.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 4 days ago.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on November 14, 2026, and from our analysis. They are not legal advice.
Star history
- transact-rs/sqlx17,669 ★ · +182
| Repository | 2026-09-21 | 2026-11-14 |
|---|---|---|
| transact-rs/sqlx | 17.5k | 17.7k |
182 Stars in the last 54 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
sqlx::Pool, per-connection statement caches and rows decoded on demand
Connection handling is what SQLx takes off your hands. sqlx::Pool is the built-in pool, and when you go through the high-level sqlx::query API, statements are prepared and cached per connection instead of being re-prepared on every call. Rows are not materialized either: data is read asynchronously from the database and decoded on demand, which is what stops a large result set from becoming a large allocation in one go. If you want to skip the prepared path, the simple unprepared query execution still fetches into the same Row types the high-level API uses, and it supports batch execution, returning results from all statements in the batch. Transactions nest, with support for save points, so an inner block can roll back without discarding the outer work, and PostgreSQL gets asynchronous notifications through LISTEN and NOTIFY. None of that is a mapping layer. The README links a section titled SQLx is not an ORM, and compile-time checking is listed as something you take if you want it.
Runtime and TLS are separate features, and the combined ones may be removed
Adding SQLx is a feature decision rather than a command. It is compatible with async-std, tokio and actix, with the native-tls and rustls backends, and its examples select a runtime feature, with a separate TLS feature when encrypted connections are required:
# Cargo.toml
[dependencies]
# PICK ONE OF THE FOLLOWING:
# tokio (no TLS)
sqlx = { version = "0.9", features = [ "runtime-tokio" ] }
# tokio + native-tls
sqlx = { version = "0.9", features = [ "runtime-tokio", "tls-native-tls" ] }
# tokio + rustls with ring and WebPKI CA certificates
sqlx = { version = "0.9", features = [ "runtime-tokio", "tls-rustls-ring-webpki" ] }The distinction the docs press is small and real. For backward compatibility the runtime and TLS features can be chosen together as a single feature or separately, and for forward compatibility you should use the separate ones, because the combination features may be removed in the future. actix-web users get their own note: no separate runtime feature is needed because actix-web is fully compatible with tokio. Backend choice is platform-shaped too, since native-tls means OpenSSL on *nix, SChannel on Windows and Secure Transport on macOS, while tls-rustls is the cross-platform option and only speaks TLS 1.2 and 1.3.
The sqlite feature lifts forbid(unsafe_code) and links the C library
This is where the pure Rust claim narrows, and the README is explicit about it. The Postgres and MySQL/MariaDB drivers are pure Rust using zero unsafe code, and SQLx carries #![forbid(unsafe_code)] unless the sqlite feature is enabled. With SQLite, the driver invokes the SQLite3 API directly through libsqlite3-sys, which requires unsafe, because the only way to stay pure Rust would be porting all of SQLite. The default sqlite feature bundles and statically links SQLite. sqlite-unbundled links the system library instead, which lets you update SQLite independently of SQLx or use a fork, at three prices: you need SQLite installed or a path to the library at build time, a too-old system version causes link errors with 3.20.0 or newer recommended, and the build gets slower because bindgen runs. For orientation, a synchronous binding such as rusqlite sits on that same libsqlite3-sys layer, which is why SQLx points you at the rusqlite README for the build notes. The constraints are shared; what SQLx adds is the async surface and the pool.
MSSQL is declared removed and still carries a feature flag
Two parts of the same document disagree with each other. The database support list says MSSQL was supported prior to version 0.7, and that it has been removed pending a full rewrite of the driver as part of the SQLx Pro initiative. Further down, the Cargo feature flag list still carries an entry stating that mssql adds support for the MSSQL database server. Nothing alongside that flag says whether it still resolves to a working driver or is a leftover from before the removal. The consequence for a reader is direct: if you need SQL Server, the documentation offers you no supported path, and a feature name that reads like a promise is worse than an absent one. The same drift shows up in the crate description, which names PostgreSQL, MySQL and SQLite while the support list also carries MariaDB. Reading the support list rather than the flag list is the only way to know what you can actually connect to.
The mysql feature alone cannot authenticate a server that wants RSA
There is a flag trap in the MySQL support, spelled out in the feature list. The mysql feature does not enable mysql-rsa, and RSA auth without TLS requires mysql-rsa. The authentication plugins involved are caching_sha2_password and sha256_password when TLS is off. The guidance is to enable mysql-rsa only if you must connect without TLS to servers that require RSA auth, and to prefer using TLS. So the failure mode is narrow and quiet: a MySQL or MariaDB account on one of those plugins, reached over an unencrypted connection, on a build where someone enabled mysql and nothing else. The fix is the exact feature the documentation tells you not to reach for by default. TLS itself is offered for MySQL, MariaDB and PostgreSQL, and it is not listed for SQLite, which makes sense once you know SQLite is a local file with no network handshake to protect.
AnyPool reads the driver out of the URL scheme, and gives up static certainty
Almost everything in SQLx is database specific, and there is one deliberate escape hatch. The Any driver exists for changing the database driver at runtime, and an AnyPool connects to the driver indicated by the URL scheme. The case it serves is real: one connection type in your code, several databases underneath, a configuration string deciding which one. It is also where certainty about the database leaves the type system. On the typed path, the driver in your types is the driver you are talking to, and swapping backends is a compile error. With AnyPool, a scheme in a connection string is the only thing standing between a query and a protocol, so a configuration change is enough to move traffic onto a different database engine without anything failing to compile.
rust-version 1.94.0 and a pinned toolchain decide when you can build
The workspace Cargo.toml is where the maintenance facts sit. The version is 0.9.0, the licence is MIT OR Apache-2.0, with LICENSE-APACHE and LICENSE-MIT both at the root, and rust-version is 1.94.0, which is the compiler floor. The edition is still 2021, carrying a TODO comment to move to edition 2024 after pending pull requests merge, and a rust-toolchain.toml sits at the root, so cloning the repository pins the toolchain for everyone. The article found no GitHub releases, but a Git commit can also identify a source snapshot; the last push recorded for the repository was 2026-10-31. The tree is a workspace of nine crates, running from sqlx-core through sqlx-macros, sqlx-macros-core, sqlx-postgres, sqlx-mysql, sqlx-sqlite and sqlx-cli, with sixteen example crates under examples/ in the workspace for chat, listen, json, multi-database, multi-tenant, transaction, serialize and extension, plus benches/, contrib/, tests/ and a CHANGELOG.md with a gen-changelog.sh script beside it.
Editorial conclusion
SQLx fits a Rust service that owns its SQL and wants pooling, statement caching and row streaming without an ORM, and does not fit a team that needs SQL Server or a dependency list with no unsafe in it. Before adopting it, settle the TLS question rather than the runtime question: use the separate runtime and TLS features, because the combination features may be removed, and check whether your MySQL accounts use caching_sha2_password, since the mysql feature alone will not authenticate them over an unencrypted connection. Then confirm your toolchain can meet rust-version 1.94.0, because rust-toolchain.toml at the root pins the compiler for anyone who clones the repository.
Frequently asked questions
What is SQLx in Rust?
SQLx is an async, pure Rust SQL crate that offers compile-time checked queries without a DSL, and the checks are optional. It supports PostgreSQL, MySQL, MariaDB and SQLite, and it ships its own connection pool with sqlx::Pool.
Does SQLx support SQLite?
Yes, through the sqlite feature, which bundles SQLite and links it statically. The sqlite-unbundled feature links the system library instead, which allows updating SQLite independently of SQLx or using a fork, and recommends SQLite 3.20.0 or newer.
Which SQLx feature flags should I put in Cargo.toml?
Pick a runtime feature and a TLS feature separately, such as runtime-tokio with tls-native-tls or tls-rustls-ring-webpki. The combined features exist for backward compatibility and may be removed, so the separate ones are the forward-compatible choice.
Does SQLx support Microsoft SQL Server?
MSSQL was supported prior to version 0.7 and has been removed, pending a full rewrite of the driver as part of the SQLx Pro initiative. An mssql feature flag still appears in the feature list even though the support list says the driver is gone.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/transact-rs-sqlx)Star history chart for your README
[](https://hysenlabs.com/projects/transact-rs-sqlx)Was this useful?