Rust/Actix-web 4 implementation for the Rinha de Backend 2024/Q1 challenge with SQLx async driver and PostgreSQL stored procedures
A Rust implementation of the Brazilian backend challenge Rinha de Backend 2024/Q1, where a fictional bank API must handle concurrent transactions under strict resource constraints (1.5 CPU, 550MB RAM total). The current API is a single src/WebApi/main.rs entrypoint (173 total lines at this revision) using Actix-web 4 with the Tokio runtime and SQLx 0.8 for PostgreSQL access.
| Technology | Version / Source | Purpose |
|---|---|---|
| Rust | edition 2024; Docker builder rust:1.95; CI uses dtolnay/rust-toolchain@stable |
API implementation |
| Actix-web | 4 | Async HTTP framework |
| SQLx | 0.8 | PostgreSQL driver with offline query metadata (.sqlx/) |
| Tokio | 1 (full) |
Async runtime |
| PostgreSQL | 16.7 Alpine | Database with stored procedures |
| NGINX | 1.27 Alpine | Reverse proxy and load balancer (least_conn) |
| Docker | Compose + Buildx | Multi-stage image build and orchestration |
| k6 | ghcr.io/jonathanperis/rinha2-back-end-k6:latest |
Stress testing |
NGINX (:9999, least_conn)
├── webapi1-rust (:8080, 0.4 CPU, 100MB; host :6968 in dev)
├── webapi2-rust (:8080, 0.4 CPU, 100MB; host :6969 in dev)
└── PostgreSQL (0.5 CPU, 330MB)
├── InsertTransacao() — atomic balance update + validation
└── GetSaldoClienteById() — statement with JSONB aggregation
| Service | CPU | RAM |
|---|---|---|
| webapi1/2 | 0.4 each | 100MB each |
| PostgreSQL | 0.5 | 330MB |
| NGINX | 0.2 | 20MB |
| Total | 1.5 | 550MB |
- Single Rust API entrypoint (
src/WebApi/main.rs, 173 total lines at this revision) - Actix-web route handlers for transactions, statements, and
/healthz - SQLx compile-time query validation with offline cache (
src/WebApi/.sqlx/) - PostgreSQL stored procedures for server-side balance updates and statement aggregation
- UNLOGGED
ClientesandTransacoestables for challenge-oriented write throughput - Lazy static
HashMapfor the five seeded client limits (no DB round-trip for client existence checks) - PostgreSQL tuned for benchmark throughput:
synchronous_commit=0,fsync=0,full_page_writes=0 - Multi-platform GHCR release flow:
latestis assembled as a multi-arch manifest from amd64 and arm64 builds;latest-arm64is also pushed during the arm64 leg - Development observability stack with Prometheus, Grafana, InfluxDB, and postgres-exporter
- Committed stress-test report artifacts under
docs/public/reports/; treat generated reports, not hard-coded README numbers, as the performance source of truth
- Docker with Docker Compose
git clone https://github.com/jonathanperis/rinha2-back-end-rust.git
cd rinha2-back-end-rust
docker compose up nginx -d --buildAPI available at http://localhost:9999.
The dev compose file also exposes the API instances directly on localhost:6968 and localhost:6969; use the NGINX port (9999) for challenge-compatible requests.
| Method | Path | Status Codes | Description |
|---|---|---|---|
| POST | /clientes/{id}/transacoes |
200, 404, 422 | Submit debit or credit transaction for client IDs 1-5 |
| GET | /clientes/{id}/extrato |
200, 404 | Get account balance statement with the 10 most recent transactions |
| GET | /healthz |
200 | Health check returning Healthy |
Transaction payload validation is handled in Rust before the stored procedure call: tipo must be c or d, descricao must be non-empty and at most 10 characters, and valor must be positive.
docker compose up k6 --build --force-recreateThe dev compose path runs k6 in MODE=dev with InfluxDB/Grafana export. The production compose file used by the release workflow runs k6 in MODE=prod and exports an HTML report artifact.
rinha2-back-end-rust/
├── src/WebApi/
│ ├── main.rs # Complete API entrypoint (173 total lines at this revision)
│ ├── Cargo.toml # Rust 2024 package and dependencies
│ ├── Dockerfile # Multi-stage: rust:1.95 → debian:bookworm-slim
│ └── .sqlx/ # SQLx offline query cache
├── docker-entrypoint-initdb.d/
│ └── rinha.dump.sql # UNLOGGED schema + stored procedures + seed data
├── docker-compose.yml # Dev stack: APIs, PostgreSQL, NGINX, observability, k6
├── prod/docker-compose.yml # Release/load-test stack using GHCR images and prod k6 mode
├── nginx.conf # Load balancer config
├── docs/ # Astro/Bun GitHub Pages site and wiki markdown
├── scripts/check_docs_drift.py # Source-backed README/wiki drift guard
└── .github/workflows/ # build-check, main-release, deploy, codeql
| Workflow | Trigger | Description |
|---|---|---|
| Build Check | Pull requests to main; manual dispatch |
Rust release build, docs drift guard, and Docker Compose /healthz test |
| Main Release | Push to main; manual dispatch |
Rust release build, amd64 + arm64 GHCR image pushes, multi-arch manifest merge, production compose healthcheck, k6 report artifact upload |
| CodeQL | Push to main, pull requests to main, Monday weekly schedule |
Rust CodeQL analysis with security-and-quality queries |
| Deploy to GitHub Pages | Push to main; manual dispatch |
Reusable shared workflow that builds docs/ with Bun and deploys GitHub Pages |
Docker image: ghcr.io/jonathanperis/rinha2-back-end-rust:latest
README and wiki facts that mirror code, Docker, Compose, or workflow state are checked by:
python3 scripts/check_docs_drift.pyThe guard verifies high-value source-backed facts such as API line count, Docker builder version, Rust edition, endpoint coverage, workflow triggers, wiki navigation coverage, and known-stale phrases.
MIT — see LICENSE