Home
Rust/Actix-web 4 implementation for the Rinha de Backend 2024/Q1 challenge. Manages a fictional bank API with transaction processing and balance statements under strict resource constraints (1.5 CPU, 550MB RAM total across all containers).
Wiki Pages
| Page | Description |
|---|---|
| Challenge | What is Rinha de Backend 2024/Q1 |
| Architecture | Stack, services, resource constraints |
| Getting Started | Prerequisites and how to run |
| Performance | Results, benchmarks, resource usage |
| CI/CD Pipeline | GitHub Actions workflows |
Key Features
- Minimal single-file API implementation (~140 lines of Rust)
- Actix-web 4 with Tokio async runtime and SQLx 0.8
- PostgreSQL stored procedures for server-side business logic
- All requests under 800ms at 250MB RAM usage
Architecture
Overview
The system follows a shared architecture across all Rinha de Backend implementations: two API instances behind an Nginx reverse proxy, with a single PostgreSQL database and an observability stack.
Services
| Service | Role | CPU | RAM |
|---|---|---|---|
| webapi1 | Rust/Actix-web 4 API instance (SQLx 0.8 + Tokio) | 0.4 | 100MB |
| webapi2 | Rust/Actix-web 4 API instance (SQLx 0.8 + Tokio) | 0.4 | 100MB |
| nginx | Reverse proxy / load balancer (least-conn) | 0.2 | 20MB |
| postgresql | Database with stored procedures | 0.5 | 330MB |
| k6 | Load testing | (not counted) | (not counted) |
| grafana + influxdb | Observability dashboards | (not counted) | (not counted) |
Load Balancing
Nginx uses least_conn strategy to distribute requests across the two API instances.
Database
Business logic is implemented in PostgreSQL stored procedures. The database is tuned for maximum write performance:
synchronous_commit=0— no wait for WAL flushfsync=0— skip fsync on writesfull_page_writes=0— skip full page writes
Implementation Details
- Minimal single-file Rust API (~140 lines)
- Actix-web 4 HTTP framework with Tokio async runtime
- SQLx 0.8 async PostgreSQL driver
- Multi-stage Docker build for minimal container image size
Challenge
Rinha de Backend 2024/Q1
The Rinha de Backend is a Brazilian backend programming challenge. The 2024/Q1 edition simulates a fictional bank called "Rinha Financeira" that manages up to 5 named clients, each seeded at startup with a credit limit and initial balance.
Endpoints
Two API endpoints are required:
| Endpoint | Method | Description |
|---|---|---|
/clientes/{id}/transacoes |
POST | Submit a debit or credit transaction for a client (IDs 1-5) |
/clientes/{id}/extrato |
GET | Get a client's current balance, credit limit, and recent transactions |
Constraints
The challenge imposes strict resource limits across all containers combined:
- 1.5 CPU total shared across all services
- 550MB RAM total shared across all services
- The system is stress tested using Grafana k6 with concurrent users submitting transactions and querying statements
Source
Full specification: github.com/zanfranceschi/rinha-de-backend-2024-q1
CI/CD Pipeline
Workflows
This repository uses four GitHub Actions workflows:
build-check.yml
- Trigger: Pull requests to main
- Steps: Builds the Rust release binary, then runs Docker Compose and validates the healthcheck endpoint
- Purpose: Catch build failures and regressions before merging
main-release.yml
- Trigger: Push to main branch
- Steps: Builds the release binary, builds and pushes a multi-platform Docker image (amd64/arm64) to GHCR, runs container healthcheck, then runs k6 load tests and uploads the stress test report as an artifact
- Purpose: Automated release of production-ready container images with load test validation
codeql.yml
- Trigger: Push to main, pull requests to main, weekly schedule (Mondays)
- Steps: Runs CodeQL static analysis for Rust with security-and-quality queries
- Purpose: Continuous security and code quality analysis
deploy.yml
- Trigger: Push to main branch
- Steps: Deploys the
docs/directory to GitHub Pages using the actions/deploy-pages workflow - Purpose: Publish project documentation and stress test reports to GitHub Pages
Getting Started
Prerequisites
- Docker with Docker Compose
Clone and Run
git clone https://github.com/jonathanperis/rinha2-back-end-rust.git
cd rinha2-back-end-rust
docker compose up nginx -d --build
Access
The API is available at http://localhost:9999
Endpoints
| Endpoint | Method | Description |
|---|---|---|
/clientes/{id}/transacoes |
POST | Submit debit or credit transaction |
/clientes/{id}/extrato |
GET | Get account balance statement |
Example Requests
Create Transaction
curl -X POST http://localhost:9999/clientes/1/transacoes \
-H "Content-Type: application/json" \
-d '{"valor": 1000, "tipo": "c", "descricao": "deposito"}'
Get Statement
curl http://localhost:9999/clientes/1/extrato
Performance
Resource Constraints
The challenge allows a total of 1.5 CPU and 550MB RAM across all containers.
Actual Usage
| Metric | Limit | Actual | Margin |
|---|---|---|---|
| RAM | 550MB | ~250MB | 60% below limit |
| Response time | - | < 800ms | All requests |
Results
- All requests completed under 800ms
- Total RAM usage of approximately 250MB, which is 60% below the 550MB limit
- Built for learning purposes
Stress Testing
Load tests are run using the shared rinha2-back-end-k6 test suite, which simulates concurrent users performing debits, credits, validations, and statement queries.