rinha2-back-end-go

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

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