tokio-postgres
A native, asynchronous PostgreSQL client for Rust built on Tokio
Repository Health
Technical Analysis
tokio-postgres is the asynchronous PostgreSQL driver in the rust-postgres workspace, providing a native, pipelined client built directly on the Tokio async runtime. It underpins most async Rust database stacks — including SQLx-adjacent tooling and connection pools like deadpool-postgres and bb8 — by handling the wire protocol, authentication, prepared statements, and streaming query results without going through libpq.
Because requests are pipelined rather than sent one at a time, the client can queue multiple queries and let the server process them concurrently, which matters for high-throughput services. It supports COPY in/out streaming, LISTEN/NOTIFY, binary and simple query protocols, and pluggable TLS via separate postgres-native-tls or postgres-openssl crates, keeping the core crate free of a hard-coded TLS dependency.
What You Get
- Fully asynchronous, pipelined query execution built on Tokio’s I/O primitives
- Prepared statement caching and parameterized queries with compile-time-friendly type conversions via postgres-types
- Streaming COPY in/out support for bulk data transfer
- LISTEN/NOTIFY support for Postgres pub/sub notifications
- Pluggable TLS negotiation through separate native-tls and openssl integration crates
- A
TransactionandTransactionBuilderAPI for isolation-level-aware transactional work
Common Use Cases
- Building async web services and APIs that talk directly to PostgreSQL without an ORM
- Powering higher-level connection pool crates such as deadpool-postgres and bb8-postgres
- Streaming large datasets in or out of Postgres via COPY for ETL and bulk-load jobs
- Implementing pub/sub or cache-invalidation patterns using LISTEN/NOTIFY
Under The Hood
Architecture - The crate splits responsibilities across a small set of focused modules: connection.rs drives the actual socket I/O loop and message dispatch, client.rs exposes the public Client API (query, prepare, transaction, copy_in/out) that sends requests over an internal mpsc channel to the connection task, and codec.rs frames raw bytes into postgres-protocol backend/frontend messages. Wire-level encoding/decoding and type conversion are deliberately factored out into the sibling postgres-protocol and postgres-types crates within the same workspace, so tokio-postgres itself focuses purely on async orchestration — pipelining requests, matching responses back to callers via RequestMessages, and managing connection lifecycle (connect.rs, connect_raw.rs, connect_tls.rs).
Tech Stack - Built on Tokio’s AsyncRead/AsyncWrite traits (runtime-agnostic beyond that), using futures-channel/futures-util for the internal request/response plumbing, bytes for zero-copy buffer handling, fallible-iterator for streaming rows, and parking_lot::Mutex for lightweight internal locking. TLS is not baked in; instead MakeTlsConnect/TlsConnect traits are implemented by separate crates (postgres-native-tls, postgres-openssl), keeping the core dependency tree minimal. The crate targets Rust 2024 edition with MSRV 1.85 and even supports a js/wasm32 feature path for browser/WASI targets.
Code Quality - The workspace has a dedicated test/ directory plus per-crate tests/ (e.g. tokio-postgres/tests/test/) exercising connection, query, COPY, transaction, and type-conversion behavior against a real Postgres instance via docker-compose, rather than relying purely on mocks. Error handling flows through a dedicated error module (error/mod.rs, error/sqlstate.rs) mapping Postgres SQLSTATE codes to typed Error variants instead of stringly-typed errors, and unwrap() usage in the library source is minimal (under 20 call sites across ~6,700 lines), concentrated in non-panicking paths. Naming is consistent with the sync postgres crate, which shares most of its API surface.
API Design - The client API is intentionally close to the synchronous postgres crate’s shape (query, query_one, execute, prepare, transaction), which lowers the learning curve for anyone coming from either side. Getting started requires spawning the returned Connection future alongside using the Client, a slightly unusual two-piece handshake that’s well documented in the crate-level example but is the one non-obvious wrinkle in an otherwise ergonomic, strongly-typed API.
Used by 6 apps in this directory
Arroyo
Data Engineering · Analytics
A distributed stream processing engine written in Rust that lets you write SQL to run stateful, real-time computations over data streams with subsecond results.
Huly Platform
Project Management · Team Chat · Collaboration
Open-source all-in-one workspace that replaces Linear, Jira, Slack, and Notion for product and engineering teams.
PeerDB
Data Engineering · Databases
Postgres-native ETL that streams change data capture in real time to Snowflake, BigQuery, ClickHouse, S3, and Kafka — up to 10x faster than general-purpose pipelines, managed through a familiar Postgres SQL interface.
QuestDB
Databases · Analytics
A high-performance, open-source time-series database built for financial market data, IoT telemetry, and real-time analytics, combining a zero-GC Java/C++ core with SIMD-accelerated SQL and a WAL-to-Parquet storage engine.
Stalwart
Collaboration
All-in-one secure mail and collaboration server covering IMAP, JMAP, SMTP, CalDAV, CardDAV, and WebDAV in a single memory-safe Rust binary.
Trieve
AI Development · Search · Developer Tools
All-in-one self-hostable platform for hybrid search, RAG, recommendations, and analytics built on Rust and Qdrant.