Home
Go 1.25 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). Written in ~221 lines of pure Go.
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
- Go 1.25 with minimal standard library usage (~221 lines)
- chi/v5 router for high-performance HTTP routing
- pgx/v5 with pgxpool for efficient PostgreSQL connection pooling
- PostgreSQL stored procedures for server-side business logic
- Extreme throughput under strict resource constraints
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 | Go 1.25 API instance | 0.4 | 100MB |
| webapi2 | Go 1.25 API instance | 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
- chi/v5 for lightweight, idiomatic HTTP routing with minimal overhead
- pgx/v5 with pgxpool for connection pooling and efficient concurrent database access
- PostgreSQL stored procedures handle all transaction logic atomically
- Multi-stage Docker build for minimal container image size (amd64, arm64/v8)
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, push to main
- Steps: Builds the Go API and runs a Docker health check to verify the service starts correctly
- Purpose: Catch build failures and regressions before merging
main-release.yml
- Trigger: Push to main branch
- Steps: Builds a multi-platform Docker image (amd64, arm64/v8), pushes it to GitHub Container Registry (GHCR), and runs k6 load tests
- Purpose: Automated release of production-ready container images with stress test validation
codeql.yml
- Trigger: Pull requests to main, push to main, weekly schedule
- Steps: Runs GitHub CodeQL security analysis for Go
- Purpose: Automated security vulnerability detection
deploy.yml
- Trigger: Push to main branch
- Steps: Installs dependencies, builds the Astro site in
docs/, and deploys the output to GitHub Pages - Purpose: Publish project documentation and stress test reports to GitHub Pages
Docker Image
Published to ghcr.io/jonathanperis/rinha2-back-end-go:latest (amd64, arm64/v8)
Getting Started
Prerequisites
- Docker with Docker Compose
Clone and Run
git clone https://github.com/jonathanperis/rinha2-back-end-go.git
cd rinha2-back-end-go
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 | ~200MB | 63% below limit |
| Response time | — | < 50ms P95 | All requests |
Results
- Extremely low P95 latency under concurrent load
- Minimal memory footprint thanks to Go's efficient runtime
- High throughput enabled by pgxpool's concurrent connection management
- Flat, minimal codebase (~221 lines) reduces attack surface and maintenance overhead
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.