rinha2-back-end-rust

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

GitHub · Jonathan Peris

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 flush
  • fsync=0 — skip fsync on writes
  • full_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.