PRODSovereign European BaaS platformOpen Dashboard →

Performance · 10 min read

SQLx vs Diesel vs SeaORM for a fast Rust backend

Affane Daylami · Fondateur · June 29, 2026

Back to blog

SQLx, Diesel and SeaORM do not answer the same question. SQLx is an asynchronous SQL toolkit, without DSL: you write SQL, checked at compile time if you want. Diesel is a type-safe, mostly synchronous query builder that checks your queries against the Rust type system. SeaORM is an asynchronous ActiveRecord-style ORM — and often relies on SQLx internally. The Aurabase aura-db service uses SQLx. Here's why, with the code to back it up — and why this choice won't necessarily be yours.

This English text was generated automatically from the French original and has not been reviewed yet.

This article compares the three libraries on verifiable criteria — verification philosophy, async support, ecosystem maturity (crates.io downloads, GitHub activity) — sourced and dated August 23, 2026. No Aurabase performance figures are included: for this pillar, see our Benchmarkspage, which documents the methodology rather than bare numbers.

The essentials
  • SQLx is a SQL toolkit, not an ORM: no DSL, two modes — macros checked at compile time (dev database required) or dynamic queries built at runtime.
  • Diesel checks queries in the Rust type system, without connection to a database at compile time. However, it remains synchronous by default (async goes through the separate crate diesel-async).
  • SeaORM is an ActiveRecord-style async ORM that declares sqlx/sqlx-core as optional dependencies on crates.io. Depending on the configuration, it can run entirely on SQLx as a low-level driver.
  • Aurabase uses SQLx in 100% dynamic mode — zero calls to the query! macro out of 532 query calls in the code. The reason: the target schema changes with each request (multi-tenant routing by search_path).
  • None of the three is “the fastest” in absolute terms: the real criterion is whether your schema is fixed at compilation or decided at runtime.
#
Overview

Three ways to attack Postgres from Rust

SQLx, Diesel and SeaORM are not three variations of the same tool. SQLx is a low-level toolkit — a Postgres driver augmented with an optional check. Diesel is a classic ORM in the Rust sense: a layer of types above SQL. SeaORM is an ORM in the Ruby/Python sense: entities, relationships, loading of objects. The table below sets out the verifiable facts, all dated August 23, 2026.

TypeSQL Toolkit (not an ORM)Query builder ORM type-safeAsync ORM like ActiveRecord
Checking queriesMacro compile-time (dev database required) or dynamicRust type system, without compile-time baseRuntime — entities generated from the schema
Native asyncYes, project foundationNo by default — via separate diesel-async crateYes
Supported basesPostgreSQL, MySQL, SQLitePostgreSQL, MySQL, SQLite (+ third-party Oracle/Firebird/DuckDB)PostgreSQL, MySQL, MariaDB, SQLite
Current version0.9.02.3.122.0.2
Downloads / 90 days33,4 M6,3 M3,8 M
GitHub Stars17 40514 1599 870
LicenseApache-2.0Apache-2.0Apache-2.0

Versions, downloads and stars: crates.io API and GitHub API, queried on August 23, 2026. SQLx repository tracked under transact-rs/sqlx (formerly launchbadge/sqlx).

crates.io downloads over the last 90 days, by Postgres Access Rust librarySQLx33.4 MDiesel6.3 MSeaORM3.8 M

Downloads over the last 90 days, in millions (recent_downloads field of the crates.io API). Source: crates.io, interviewed August 23, 2026.

#
SQLx

SQL is SQL — verified or not, it’s up to you

SQLx describes itself as "an async, pure Rust SQL crate featuring compile-time checked queries without a DSL" (official README, github.com/transact-rs/sqlx, accessed August 23, 2026). No query builder, no entities: you write SQL and SQLx offers two ways to execute it.

SQLx examples (generic, excluding Aurabase code)rust
// Mode 1 — compile-time macro: checked against a real dev database
let user = sqlx::query_as!(User, "SELECT id, email FROM users WHERE id = $1", user_id)
    .fetch_one(&pool)
    .await?;

// Mode 2 — dynamic: table/columns decided at runtime
let sql = format!("SELECT * FROM {table} WHERE id = $1");
let row = sqlx::query(&sql).bind(user_id).fetch_one(&pool).await?;

Mode 1 requires a database accessible at the time of cargo build — the macro connects to it to check types. Mode 2 has no static checks, but accepts any SQL string constructed at runtime — including table names. This is the mode that Aurabase uses (section 06).

Astuce

Runtimes supported: tokio, async-std, actix (native TLS or rustls). Bases: PostgreSQL, MySQL, MariaDB, SQLite — MSSQL support has been removed since version 0.7. The crate uses #![forbid(unsafe_code)] excluding SQLite integration (official README, accessed August 23, 2026).

Common objection against mode 1: how to build in CI without an accessible dev base? sqlx-cli responds in an offline mode (official sqlx-cli doc, consulted on August 23, 2026):

  1. Locally, with a dev database connected, launch cargo sqlx prepare: the metadata of each verified request is written in a .sqlxfolder.
  2. Commit this .sqlx folder to the repository, next to the code.
  3. In CI, define SQLX_OFFLINE=true: the build reads the versioned metadata and no longer tries to connect to a real database.

The same tool also manages migrations (sqlx migrate add / run / revert) — a role that aura-migrations assumes separately on the Aurabase side.

#
Diesel

The type-safe query builder, mainly synchronous

Diesel presents itself as “a Safe, Extensible ORM and Query Builder for Rust” (official website diesel.rs, accessed August 23, 2026). The project also claims that it “eliminate[s] the possibility of incorrect database interactions at compile time”. The basic difference with SQLx: Diesel checks your queries in the Rust type system itself, without needing a database connected at build time.

The official Diesel comparison page (accessed August 23, 2026) itself locates the difference: Diesel “can also check parts of the query at compile time”. This allows you to build already verified dynamic queries — an IN on a Rust vector, a batch insert, a conditional clause. SQLx, conversely, “always needs to know the whole query at compile time” for its macro: these three cases remain outside the scope of mode 1 seen above.

Diesel is synchronous by default; async goes through the separate crate diesel-async. This same page reports that the crates.io team measured a gain of 20% on one of their endpoints after switching to diesel-async's PostgreSQL pipelining. The page indicates this functionality is missing from SQLx and SeaORM. This is a statement by Diesel on its own site about a single endpoint, not an independent measurement that we have reproduced or generalized: to be taken as such.

Diesel also includes its own migration and schema generation tools (official README, accessed August 23, 2026). diesel migration run applies versioned SQL files. diesel print-schema regenerates the Rust module schema.rs describing your tables — the part that the rest of the type-safe query builder then consumes to check your compile-time queries.

#
SeaORM

The asynchronous ORM like ActiveRecord, often built on SQLx

SeaORM describes itself as "an async & dynamic ORM for Rust" (official site sea-ql.org/SeaORM, accessed August 23, 2026), with a ActiveModel model inspired by Ruby/Python/Node ORMs. 1-1, 1-N, M-N and self-referenced relationships, intelligent loading by join or by data loader, entities that can be generated from an existing database via sea-orm-cli. The verification is done at runtime, not at compilation.

Often overlooked point: SeaORM is not always an alternative to SQLx, sometimes it is two layers on top. SQL generation goes through sea-query, its own dynamic query builder. It is a non-optional dependency of sea-orm 2.0.2 (crates.io description: “a dynamic query builder for MySQL, Postgres and SQLite”, verified August 23, 2026). Execution goes through sqlx/sqlx-core and sea-query-sqlx — three dependencies declared optional, activated by feature (sqlx-postgres, etc. — crates.io API, verified August 23, 2026). Concretely: choosing SeaORM with the standard Postgres backend means adding a query builder then entities/relations on top of SQLx, not replacing it.

Migrations follow the same dedicated tooling logic: sea-orm-cli migrate generate/up/down manages schema versioning. sea-orm-cli generate entity then regenerates the entity files from the updated database — a schema-to-code round trip closer to diesel print-schema than to SQLx's dynamic mode.

Info

SeaORM claims "250k+ weekly downloads" on its own homepage (self-reported source, accessed August 23, 2026). This figure is consistent with the 3.8M downloads over 90 days measured independently via the crates.io API.

#
Decision

When to choose SQLx, Diesel or SeaORM

Choose SQLx if…

  • Schema decided at execution (multi-tenant, dynamic introspection)
  • You want to stay close to SQL, without DSL to learn
  • Non-negotiable native async

Choose Diesel if…

  • Stable schema, known at build
  • Pushed static verification without database connected to compile-time
  • Default sync acceptable, or diesel-async for pipelining

Choose SeaORM if…

  • ActiveRecord ergonomics: relationships, object graphs
  • Entities generated from an existing database
  • One more layer of abstraction above an SQL driver is no problem
#
Our choice

What the code shows: SQLx in 100% dynamic mode

The Aurabase Cargo workspace pins sqlx = "0.8" with the features postgres, runtime-tokio-rustls, uuid, chrono, json, derive and rust_decimal. The aura-db and aura-db-adapters services depend directly on it (verified in the Cargo.toml repository, August 23, 2026).

What matters more than a dependency line: no calls to the macro sqlx::query! or query_as! in this code (0 occurrences), compared to 532 calls to sqlx::query()/query_as(), the dynamic form. The reason is architectural, not a style preference. Each Aurabase project lives in its own Postgres schema, resolved at login by SET LOCAL search_path. The queried table name arrives in the HTTP request, not in the compiled binary.

Connection pooling itself remains standard SQLx: libs/aura-db-adapters opens its pool via PgPoolOptions::new() (verified in postgres/mod.rs, August 23, 2026), without proprietary overlay at this level. What is proprietary comes above: tenant routing, validation of table identifiers injected into dynamic SQL, and construction of WHEREclauses / PostgREST compatible filters.

simplified architecture — search_path per projectrust
// Target schema is resolved by query, not known at build
sqlx::query("SET LOCAL search_path TO $1, public")
    .bind(project_schema)
    .execute(&mut *tx).await?;

// Table/columns decided by dynamic REST layer (PostgREST compatible)
let sql = format!("SELECT * FROM {} WHERE {}", table, where_clause);

Diesel's static verification model assumes a known pattern at the time the binary is compiled. The opposite: a single binary that serves an unbounded number of patterns per project, discovered at runtime. SeaORM's entity generation makes the same assumption of a fixed schema. This is not a verdict on SQLx versus Diesel in absolute terms — it is a choice of architecture: pattern known at build versus pattern resolved at runtime. For details of schema-per-project partitioning and associated RLS policies, see our Database documentation and the RLS guide.

Product objective, not a verified fact

Aurabase does not publish any latency figures today comparing SQLx, Diesel and SeaORM on its own production load. Our Benchmarks page, cited in the introduction, documents the methodology used for this pillar — not bare figures.

#
Frequently asked questions

What we get asked most often

Is SQLx an ORM?+
No. SQLx does not offer query DSL or automatic object-relational mapping — it is an asynchronous SQL toolkit with optional compile-time checking (official README, github.com/transact-rs/sqlx, accessed August 23, 2026).
Can we use Diesel asynchronously?+
Yes, but not in the main diesel crate, which remains synchronous by default. Async goes through the separate diesel-asynccrate, maintained by the Diesel ecosystem, which also adds PostgreSQL pipelining.
Can SeaORM work without SQLx?+
On crates.io, sqlx and sqlx-core appear as optional dependencies of sea-orm, activated by features like sqlx-postgres — in the standard Postgres configuration, SeaORM therefore relies on SQLx as an execution driver.
Which library has the most adoption in 2026?+
By downloads over 90 days (crates.io API, August 23, 2026): SQLx (33.4 M) ahead of Diesel (6.3 M) and SeaORM (3.8 M). Adoption says nothing about the best choice for your scheme — see section 05.
#
In summary

There is no universal winner

SQLx, Diesel and SeaORM cover three different needs, not three places on the same podium. Diesel checks a pattern that you know in advance as early as possible. SeaORM saves you time on object usability if you accept one more layer of abstraction — often on top of SQLx itself. SQLx remains the most bare-bones of the three: that's what makes it suitable for a pattern you only know at runtime, likeaura-dbmulti-tenant routing.

If you are migrating an existing project to Postgres and you are looking for what really changes on the RLS schema and policies side, our migration guide Supabase → Aurabase details the subject.

READY TO DEPLOY?

Your backend in five minutes.

No credit card required · 500 MB free · 50,000 MAU