<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/building-scalable-backend-services-with-rust-and-postgresql-tlwj69w1v" -->

---
title: Building scalable backend services with Rust and PostgreSQL
description: A practical walkthrough of building medium-sized backend services in Rust with PostgreSQL, covering the HTTP stack (tokio, rustls, hyper, axum, reqwest, tower,...
canonical: https://daily.dev/posts/building-scalable-backend-services-with-rust-and-postgresql-tlwj69w1v
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Building scalable backend services with Rust and PostgreSQL | daily.dev
og:description: A practical walkthrough of building medium-sized backend services in Rust with PostgreSQL, covering the HTTP stack (tokio, rustls, hyper, axum, reqwest, tower,...
og:url: https://daily.dev/posts/building-scalable-backend-services-with-rust-and-postgresql-tlwj69w1v
og:image: https://api.daily.dev/og/posts/tLWj69W1V.png
og:image:alt: Building scalable backend services with Rust and PostgreSQL
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Building scalable backend services with Rust and PostgreSQL

**[Sylvain Kerkour](https://daily.dev/sources/kerkour)** · 10 min read · 6 upvotes · 3 comments

## Summary

A practical walkthrough of building medium-sized backend services in Rust with PostgreSQL, covering the HTTP stack (tokio, rustls, hyper, axum, reqwest, tower, tracing), a layered code organization (HTTP/service/repository), background jobs and cron leader election with Postgres advisory locks, caching guidance with moka, and serving SPAs directly from the API server to avoid CORS overhead.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://kerkour.com/rust-scalable-backend-services>

## Questions this post answers

### Why should I use rustls instead of openssl for TLS in a Rust web server?

Rustls is recommended because it is a Rust-native TLS implementation that gets statically linked into the executable, avoiding runtime dependency issues like mismatched OpenSSL versions on deployment images and easing cross-compilation. Alternatives include boring and openssl, but rustls integrates via the tokio_rustls crate for wrapping tokio's TcpStream into a TlsStream.

_daily.dev surfaces practical Rust TLS tradeoffs for engineers choosing a crate before deployment._

### How do you prevent multiple replicas of a Rust service from running the same cron job simultaneously?

Use PostgreSQL advisory locks to elect a single leader among service replicas before running scheduled tasks. One instance attempts to acquire the lock via a function like try_to_become_leader; only the instance that succeeds runs the cron scheduler, preventing duplicate job execution across high-availability deployments.

_daily.dev helps backend engineers compare leader-election techniques before scaling cron jobs across replicas._

### How should database queries be organized in a layered Rust backend service?

Database queries should live exclusively in a dedicated repository layer, separate from HTTP handlers and business logic in the service layer, so queries tied to a table are grouped in one file for easier reuse and schema changes. The HTTP layer can only call the service layer, and the service layer can only call the repository layer, keeping caching and business rules out of repositories.

_daily.dev helps developers weigh layered architecture patterns before structuring a new Rust service._

## Community discussion

Top comments from developers on daily.dev.

**@agustinbarrientos** · 0 upvotes

> I'd serve the SPA from the API too and take one deployment over a separate CDN for a medium-sized service.

**@pdfopsdev** · 0 upvotes

> pg advisory locks for cron leader election is underrated, the big win over a redis TTL lease is they release automatically when the session dies so there's no orphaned lock to clean up after a crash. moka's a solid pick too if you're single-node, way less ops surface than a redis sidecar just for caching.

**@trevorsuna** · 0 upvotes

> Postgres advisory locks are a nicely pragmatic choice for cron leader election when the database is already in the stack. The layered HTTP/service/repository split also keeps the Rust pieces understandable. I’d be curious where the author draws the line before moving jobs to a dedicated queue.

## Similar posts on daily.dev

- [Backend Concepts In Rust: HTTP Server](https://daily.dev/posts/backend-concepts-in-rust-http-server-ynqw9gv7v) · Medium · 0 upvotes · 0 comments
- [Build a Rust AI Agent Gateway with Tokio and Axum](https://daily.dev/posts/build-a-rust-ai-agent-gateway-with-tokio-and-axum-4xfsvkj3f) · SitePoint · 2 upvotes · 0 comments
- [GitHub - malisper/pgrust: Postgres rewritten in Rust, now passing 100% of the Postgres regression tests](https://daily.dev/posts/github---malisper-pgrust-postgres-rewritten-in-rust-now-passing-100-of-the-postgres-regression-te-t4anp8pcl) · Hacker News · 4 upvotes · 0 comments

---

Tags: [#backend](https://daily.dev/tags/backend), [#rust](https://daily.dev/tags/rust), [#postgresql](https://daily.dev/tags/postgresql)

[View this post on daily.dev](https://daily.dev/posts/building-scalable-backend-services-with-rust-and-postgresql-tlwj69w1v)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Building scalable backend services with Rust and PostgreSQL","url":"https://daily.dev/posts/building-scalable-backend-services-with-rust-and-postgresql-tlwj69w1v","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/building-scalable-backend-services-with-rust-and-postgresql-tlwj69w1v"},"datePublished":"2026-08-12T16:00:30.916Z","dateModified":"2026-09-14T08:06:09.799Z","description":"A practical walkthrough of building medium-sized backend services in Rust with PostgreSQL, covering the HTTP stack (tokio, rustls, hyper, axum, reqwest, tower,...","image":"https://media.daily.dev/image/upload/s--1KxV4ohY--/f_auto/v1722860400/public/Placeholder%2007","thumbnailUrl":"https://media.daily.dev/image/upload/s--1KxV4ohY--/f_auto/v1722860400/public/Placeholder%2007","isAccessibleForFree":true,"articleSection":"Sylvain Kerkour","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Sylvain Kerkour","logo":"https://media.daily.dev/image/upload/s--3ngWt4Yp--/f_auto,q_auto/v1786438308/logos/kerkour?_a=BAMAMicg0","url":"https://daily.dev/sources/kerkour"},"commentCount":3,"discussionUrl":"https://daily.dev/posts/building-scalable-backend-services-with-rust-and-postgresql-tlwj69w1v","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":6},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":3}],"keywords":"backend,rust,postgresql","timeRequired":"PT10M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Sylvain Kerkour","item":"https://daily.dev/sources/kerkour"},{"@type":"ListItem","position":3,"name":"Building scalable backend services with Rust and PostgreSQL"}]}
{"@context":"https://schema.org","@type":"WebPage","@id":"https://daily.dev/posts/building-scalable-backend-services-with-rust-and-postgresql-tlwj69w1v","comment":[{"@type":"Comment","text":"I’d serve the SPA from the API too and take one deployment over a separate CDN for a medium-sized service.","datePublished":"2026-08-13T15:27:26.028Z","url":"https://daily.dev/posts/tLWj69W1V#c-YdDLqkeyS","author":{"@type":"Person","name":"Agustin Barrientos","url":"https://daily.dev/agustinbarrientos","image":"https://media.daily.dev/image/upload/s--5ayxQnqn--/f_auto/v1788281802/avatars/avatar_wQYYVe5Tbj0NJ7C7qPoa8?_a=BAMAMicg0"}},{"@type":"Comment","text":"pg advisory locks for cron leader election is underrated, the big win over a redis TTL lease is they release automatically when the session dies so there’s no orphaned lock to clean up after a crash. moka’s a solid pick too if you’re single-node, way less ops surface than a redis sidecar just for caching.","datePublished":"2026-08-12T18:03:02.518Z","url":"https://daily.dev/posts/tLWj69W1V#c-M2ibuctV2","author":{"@type":"Person","name":"PDFops","url":"https://daily.dev/pdfopsdev","image":"https://media.daily.dev/image/upload/s---8isRBKc--/f_auto/v1782922291/avatars/avatar_orjMeK8QKaaVZwGq7ScPz?_a=BAMAMicg0"}},{"@type":"Comment","text":"Postgres advisory locks are a nicely pragmatic choice for cron leader election when the database is already in the stack. The layered HTTP/service/repository split also keeps the Rust pieces understandable. I’d be curious where the author draws the line before moving jobs to a dedicated queue.","datePublished":"2026-08-13T02:44:24.170Z","url":"https://daily.dev/posts/tLWj69W1V#c-Vuf8uYtHj","author":{"@type":"Person","name":"Trevor Suna","url":"https://daily.dev/trevorsuna","image":"https://media.daily.dev/image/upload/s--dZ7gXxpp--/f_auto/v1784081551/avatars/avatar_EMoP47rpuw8DNjhp6R1b6?_a=BAMAMicg0"}}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/building-scalable-backend-services-with-rust-and-postgresql-tlwj69w1v#faq","mainEntity":[{"@type":"Question","name":"Why should I use rustls instead of openssl for TLS in a Rust web server?","acceptedAnswer":{"@type":"Answer","text":"Rustls is recommended because it is a Rust-native TLS implementation that gets statically linked into the executable, avoiding runtime dependency issues like mismatched OpenSSL versions on deployment images and easing cross-compilation. Alternatives include boring and openssl, but rustls integrates via the tokio_rustls crate for wrapping tokio's TcpStream into a TlsStream. daily.dev surfaces practical Rust TLS tradeoffs for engineers choosing a crate before deployment."}},{"@type":"Question","name":"How do you prevent multiple replicas of a Rust service from running the same cron job simultaneously?","acceptedAnswer":{"@type":"Answer","text":"Use PostgreSQL advisory locks to elect a single leader among service replicas before running scheduled tasks. One instance attempts to acquire the lock via a function like try_to_become_leader; only the instance that succeeds runs the cron scheduler, preventing duplicate job execution across high-availability deployments. daily.dev helps backend engineers compare leader-election techniques before scaling cron jobs across replicas."}},{"@type":"Question","name":"How should database queries be organized in a layered Rust backend service?","acceptedAnswer":{"@type":"Answer","text":"Database queries should live exclusively in a dedicated repository layer, separate from HTTP handlers and business logic in the service layer, so queries tied to a table are grouped in one file for easier reuse and schema changes. The HTTP layer can only call the service layer, and the service layer can only call the repository layer, keeping caching and business rules out of repositories. daily.dev helps developers weigh layered architecture patterns before structuring a new Rust service."}}]}
```

