SQLx Postgres Connection Pool
Technical Review Approved
Updated: 2026-09-13
Actix Web 4.x
RS Rust 1.75+
VERIFIED
How to properly configure a sqlx::PgPool as Application State in Actix Web.
Actix Web: 4.x
Rust: 1.75+
What You Will Build
A robust API that connects to PostgreSQL using SQLx and queries the current database time.
What You Will Learn
- How to initialize a database connection pool asynchronously
- How to pass a SQLx pool into Actix Web as shared state
- Why SQLx pools do NOT need a Mutex wrapper
Project Setup
src/main.rs
Edition 2024
1cargo new sqlx-actix2cd sqlx-actix
Dependencies (`Cargo.toml`)
src/main.rs
Edition 2024
1[dependencies]2actix-web = "4"3tokio = { version = "1", features = ["macros", "rt-multi-thread"] }4sqlx = { version = "0.7", features = ["runtime-tokio-rustls", "postgres", "macros"] }
Complete Code
src/main.rs
Click highlighted lines to inspect mechanics1use actix_web::{web, App, HttpServer, HttpResponse, Responder};
2use sqlx::{PgPool, postgres::PgPoolOptions};
3
4// Our handler extracts the PgPool directly
5async fn get_time(pool: web::Data<PgPool>) -> impl Responder {
6 // Execute an async SQL query
7 let result: Result<(String,), sqlx::Error> = sqlx::query_as("SELECT NOW()::text")
8 .fetch_one(pool.get_ref())
9 .await;
10
11 match result {
12 Ok((time,)) => HttpResponse::Ok().body(format!("Database time: {}", time)),
13 Err(e) => HttpResponse::InternalServerError().body(e.to_string()),
14 }
15}
16
17#[actix_web::main]
18async fn main() -> std::io::Result<()> {
19 let database_url = "postgres://user:password@localhost/mydb";
20
21 // Initialize the pool asynchronously BEFORE starting Actix Web
22 let pool = PgPoolOptions::new()
23 .max_connections(5)
24 .connect(database_url)
25 .await
26 .expect("Failed to connect to Postgres");
27
28 // Wrap the pool in web::Data
29 let app_state = web::Data::new(pool);
30
31 println!("Starting server on http://127.0.0.1:8080");
32
33 HttpServer::new(move || {
34 App::new()
35 .app_data(app_state.clone()) // Share pool across threads
36 .route("/time", web::get().to(get_time))
37 })
38 .bind(("127.0.0.1", 8080))?
39 .run()
40 .await
41}
Line 22 - 27
Expected Result
src/main.rs
Edition 2024
1$ curl http://127.0.0.1:8080/time2Database time: 2026-09-17 12:34:56.123456+00
How It Works
The `sqlx::PgPool` is initialized before the HTTP server starts. Because a `PgPool` internally manages its own connections and is designed to be cloned safely across threads, we wrap it directly in `web::Data<PgPool>`. Inside the handler, we call `pool.get_ref()` to yield a reference to the pool for the `fetch_one` query.