Rust and PostgreSQL: A Duet That Makes Your Code Faster
\n\nHave you ever wondered why more and more backend developers are switching to Rust? The answer is simple: Rust gives you control over memory and speed, while PostgreSQL gives you control over data. Together, they form a combination capable of handling hundreds of thousands of requests per second without slowdowns or memory leaks.
\n\nIn this guide, we'll break down how to make Rust and PostgreSQL work together. You'll learn how to set up a connection, execute queries, avoid SQL injections, and build asynchronous applications. Let's go!
\n\nWhy Rust and PostgreSQL?
\n\nRust is not just a trendy language. Its ownership system and borrow checker guarantee that you won't get a null pointer or dangling references. And PostgreSQL is not just a database. It's a powerful tool with support for JSON, full-text search, and complex transactions.
When you combine Rust and PostgreSQL, you get:
\n- \n
- Security — Rust won't let you accidentally send incorrect SQL. \n
- Performance — asynchronous drivers operate at the C level. \n
- Control — you decide when and how to pull data. \n
Installation and Environment Setup
\n\nBefore writing code, make sure you have installed:
\n- \n
- Rust (latest stable version) —
rustup update\n - PostgreSQL (locally or via Docker) —
docker run --name pg -e POSTGRES_PASSWORD=pass -p 5432:5432 -d postgres\n - The
libpq-devlibrary (for Linux) or its equivalent on Mac/Windows \n
Create a new project:
\n\ncargo new rust-postgres-guide\ncd rust-postgres-guide\n\nChoosing a Driver: tokio-postgres vs sqlx
\n\nThere are two main approaches to working with PostgreSQL in Rust:
\n- \n
- tokio-postgres — a low-level asynchronous driver. Gives full control. \n
- sqlx — a high-level asynchronous driver with compile-time query checking. \n
For advanced projects, I recommend sqlx — it's more convenient and safer. But for maximum control, use tokio-postgres.
\n\nLet's add dependencies to Cargo.toml:
[dependencies]\ntokio = { version = "1", features = ["full"] }\nsqlx = { version = "0.7", features = ["runtime-tokio-rustls", "postgres"] }\nserde = { version = "1", features = ["derive"] }\n\n\nFirst Connection: Rust and PostgreSQL Meet
\n\nLet's write a simple example that connects to the database and returns the PostgreSQL version.
\n\nuse sqlx::postgres::PgPoolOptions;\nuse std::error::Error;\n\n#[tokio::main]\nasync fn main() -> Result<(), Box<dyn Error>> {\n // Connection string: postgres://user:password@host:port/db\n let database_url = "postgres://postgres:pass@localhost:5432/postgres";\n \n // Create a connection pool (reusable connections)\n let pool = PgPoolOptions::new()\n .max_connections(5)\n .connect(database_url)\n .await?;\n\n // Execute the query\n let row: (String,) = sqlx::query_as("SELECT version()")\n .fetch_one(&pool)\n .await?;\n\n println!("PostgreSQL version: {}", row.0);\n Ok(())\n}\n\nRun the code: cargo run. If everything is set up correctly, you'll see the PostgreSQL version. Note the PgPoolOptions — a connection pool is mandatory for production. It reuses connections and doesn't create new ones for each request.
Creating Tables and CRUD Operations
\n\nNow let's create a users table and perform basic operations: insert, read, update, delete.
Migration: Creating a Table
\n\nIn sqlx, migrations are separate SQL files. Create a migrations folder and a file named
Blogs
Book Recommendations
Read also
Updating GUI from Another Thread in C#: Complete Guide with Examples
How to Write a REST API in C++ in 30 Minutes: A Practical Guide
Files in Java: From Beginner to Pro in 20 Minutes
Determining debug/release builds in Rust via cfg: a complete guide
How to Write a REST API in JavaScript in 30 Minutes: A Practical Guide