rinha4.lb

Home

The promoted default is the x86-64 assembly load balancer. It is the shared YOLO-mode transport layer for Jonathan Peris’ Rinha de Backend 2026 entries, with a C baseline kept in the same repo for controlled C-vs-ASM comparisons.

Downstream stacks

  • rinha4-back-end-dotnet: .NET 10 NativeAOT backend using raw HTTP over Unix sockets behind proxy mode.
  • rinha4-back-end-c: C fraud-scoring backend, usually benchmarked behind either the C baseline LB or the promoted ASM LB.
  • rinha4-yolo-mode: pure x86-64 assembly backend, used as the assembly lane for proving the shared ASM LB.
  • FD-passing backend lanes: APIs that receive accepted client FDs through Unix control sockets.

Image contract

ghcr.io/jonathanperis/rinha4-lb-yolo-mode:latest        # promoted ASM LB
ghcr.io/jonathanperis/rinha4-lb-yolo-mode:vX.Y.Z        # release tag, promoted ASM LB
ghcr.io/jonathanperis/rinha4-lb-yolo-mode:asm-ci-<sha>  # commit-specific ASM LB
ghcr.io/jonathanperis/rinha4-lb-yolo-mode:c-ci-<sha>    # commit-specific C baseline LB
ghcr.io/jonathanperis/rinha4-lb-yolo-mode:c-latest      # moving C baseline pointer

latest and release tags mean ASM. Use immutable asm-ci-<sha> or c-ci-<sha> tags for comparison runs so CI-vs-CI evidence does not mix moving pointers.

The comparison lane still matters. Future default changes should keep C-vs-ASM runs clean, repeated, and separated from official runner evidence.

Challenge

Rinha de Backend rewards correctness first and latency second. A faster LB is only useful if it preserves the official contract under repeated, official-like runs.

The shared YOLO load balancer now defaults to the x86-64 assembly implementation. Can it stay the default across the downstream stacks without correctness or p99 regressions?

The comparison harness exists to answer that by testing:

  • the promoted ASM image under pinned tags;
  • proxy mode for raw Unix-socket HTTP APIs;
  • fdpass mode for accepted-socket APIs;
  • repeated runs to smooth noisy GitHub-hosted runners;
  • official-vs-official results separately from CI-vs-CI runs.

Correctness failures close the result immediately. p99 only matters after false positives, false negatives, HTTP errors, and readiness checks are clean.

Architecture

The repository builds two load-balancer implementations from one source tree. The default runtime image is ASM; the C binary is retained as a baseline and troubleshooting fallback.

Implementation Build target Published image role Purpose
ASM make all or make asm latest, release tags, asm-ci-<sha>, sha-<short-sha> Promoted default path for Rinha4 stacks.
C make c or docker build --build-arg LB_IMPL=c c-ci-<sha>, c-latest Baseline for C-vs-ASM comparison lanes and fallback experiments.

Both binaries expose the same two external runtime shapes.

Proxy mode

k6 / judge
    |
    v
rinha4-lb-yolo-mode :9999
    |  TCP acceptor to Unix stream proxy
    +-- unix:/sockets/api1.sock -> raw HTTP API
    +-- unix:/sockets/api2.sock -> raw HTTP API

Use this for raw HTTP backends such as the .NET implementation. The promoted ASM proxy path accepts TCP clients, connects to one configured Unix stream upstream, forwards request/response bytes without parsing the fraud payload, and closes the client after the exchange.

FD-passing mode

k6 / judge
    |
    v
rinha4-lb-yolo-mode :9999
    |  SCM_RIGHTS accepted-fd handoff
    +-- unix:/run/rinha/api1.sock -> API receives accepted client fd
    +-- unix:/run/rinha/api2.sock -> API receives accepted client fd

Use this for APIs built around inherited accepted sockets.

The fdpass control socket type is explicit:

  • LB_FDPASS_SOCKET_TYPE=seqpacket for datagram-preserving control sockets;
  • LB_FDPASS_SOCKET_TYPE=stream for stream control sockets.

The ASM implementation accepts client sockets in blocking mode for fdpass so simple backend read() paths do not immediately see EAGAIN. Proxy mode uses a compact blocking syscall loop in ASM; the C baseline uses epoll/nonblocking forwarding.

Design constraints

The default ASM LB is intentionally narrow:

  • exactly two upstream workers, matching the Rinha4 topology and enforced by the ASM validation path;
  • static/no-libc runtime with direct Linux syscalls and linux/amd64 container publishing;
  • no fraud payload parsing;
  • no request-level logging;
  • fixed minimal syscall path;
  • environment parsing only for the contract knobs needed by the stacks.

The C baseline supports up to 16 upstream paths and broader mode aliases, but it is not the promoted image.

Contracts

Environment

Variable Default Description
LB_MODE proxy proxy or fdpass; promoted ASM aliases are fd, fd-pass, and scm_rights.
PORT 9999 TCP listen port. Invalid numeric values fall back to 9999 in the integration-tested paths.
UPSTREAMS mode-specific Comma-separated Unix socket paths. Proxy default is /sockets/api1.sock,/sockets/api2.sock; fdpass default is /run/rinha/api1.sock,/run/rinha/api2.sock.
BACKLOG 65535 TCP listen backlog. Invalid numeric values fall back to 65535 in the integration-tested paths.
LB_FDPASS_SOCKET_TYPE seqpacket FD-passing control socket type. Use seqpacket or stream to match the backend control socket.

Compatibility notes:

  • The promoted ASM binary reads LB_MODE, PORT, BACKLOG, UPSTREAMS, and LB_FDPASS_SOCKET_TYPE directly from its environment.
  • The ASM binary is static/no-libc and ignores unrelated environment variables injected by Docker or GitHub Actions.
  • The C baseline accepts MODE as a fallback when LB_MODE is unset, and also accepts uds-proxy/unix-proxy for proxy mode.
  • The ASM binary intentionally requires exactly two non-empty upstream paths shorter than the Linux sun_path limit. The C baseline supports up to 16 upstreams.
  • ASM PORT and BACKLOG parsing accepts positive decimal values up to 65535; invalid values fall back to 9999 and 65535 respectively.
  • Published containers target linux/amd64 and run as the unprivileged rinha user.

Image contract

Tag family Implementation Use
latest ASM Default stack image.
vX.Y.Z ASM Release image for a promoted main commit.
asm-ci-<sha> ASM Immutable ASM comparison and rollout image.
sha-<short-sha> ASM Docker metadata short-SHA alias for the same ASM manifest as asm-ci-<sha>.
c-ci-<sha> C Immutable C baseline image published by the build workflow.
c-latest C Moving C baseline pointer; avoid for repeatable benchmarks.

Proxy-mode contract

  • Listen on TCP PORT.
  • Connect each accepted client to one configured Unix stream upstream.
  • Forward bytes without parsing fraud payloads.
  • Avoid per-request logging in the hot path.
  • Keep the runtime compatible with raw HTTP backends.

FD-passing contract

  • Maintain persistent Unix control sockets to API workers.
  • Accept TCP clients on PORT.
  • Send accepted client FDs with SCM_RIGHTS.
  • Close the LB copy after handoff.
  • Do not inspect or mutate request payloads.
  • Match the worker socket type with LB_FDPASS_SOCKET_TYPE.

Stack-specific socket type

Stack Mode Socket type
Raw HTTP backend proxy Unix stream HTTP upstreams.
FD-passing backend fdpass Usually LB_FDPASS_SOCKET_TYPE=seqpacket.
Assembly backend fdpass lane fdpass Usually LB_FDPASS_SOCKET_TYPE=stream. Verify the active compose before benchmarking.

Correctness comes before p99. If any participant reports false positives, false negatives, HTTP errors, or readiness failures, reject that comparison result before reading latency.

Getting Started

Build and test locally

make clean test
make docs-drift

The test target builds the C and ASM load balancers, runs docs-drift, then runs local integration checks against dummy Unix-socket backends. docs-drift is the quick audit for README/wiki drift: it checks image tags, runtime knobs, workflow inputs, and sidebar coverage against source files.

make clean all            # default ASM binary: build/rinha4-lb-yolo-mode
make asm                  # build/rinha4-lb-yolo-mode-asm
make c                    # build/rinha4-lb-yolo-mode-c

Use the promoted ASM image

services:
  lb:
    image: ghcr.io/jonathanperis/rinha4-lb-yolo-mode:latest
    platform: linux/amd64
    environment:
      LB_MODE: proxy
      PORT: "9999"
      UPSTREAMS: /sockets/api1.sock,/sockets/api2.sock
    ports:
      - "9999:9999"

latest is ASM. For a pinned rollout, prefer asm-ci-<sha> or a release tag.

Use the C baseline image

services:
  lb:
    image: ghcr.io/jonathanperis/rinha4-lb-yolo-mode:c-ci-<sha>
    platform: linux/amd64
    environment:
      LB_MODE: proxy
      PORT: "9999"
      UPSTREAMS: /sockets/api1.sock,/sockets/api2.sock
    ports:
      - "9999:9999"

Use the C image only for comparison and fallback experiments. c-latest exists, but repeatable benchmark runs should pin c-ci-<sha>.

Use fdpass mode

services:
  lb:
    image: ghcr.io/jonathanperis/rinha4-lb-yolo-mode:latest
    platform: linux/amd64
    environment:
      LB_MODE: fdpass
      LB_FDPASS_SOCKET_TYPE: seqpacket
      PORT: "9999"
      UPSTREAMS: /run/rinha/api1.sock,/run/rinha/api2.sock
    ports:
      - "9999:9999"

For stream fdpass backends, switch only the socket contract:

environment:
  LB_MODE: fdpass
  LB_FDPASS_SOCKET_TYPE: stream
  UPSTREAMS: /run/rinha/api1.sock,/run/rinha/api2.sock

Build the image locally

docker build --build-arg LB_IMPL=asm -t rinha4-lb-yolo-mode:asm .
docker build --build-arg LB_IMPL=c   -t rinha4-lb-yolo-mode:c .

Docker access is required for image builds. The repository integration tests do not require Docker.

The Dockerfile publishes linux/amd64 images, builds the ASM implementation by default, strips the binary, exposes port 9999, and runs the runtime stage as the unprivileged rinha user. Override LB_IMPL=c only when building the C comparison image.

Before pushing

Use the full local gate for changes that touch runtime behavior, docs, workflows, or public contracts:

git diff --check
make clean test
cd docs
bun install --frozen-lockfile
NODE_ENV=production bun run build

After pushing to main, watch Build and publish LB images, Deploy GitHub Pages, and CodeQL for the pushed head, then smoke the live Pages routes listed in the operations runbook.

Performance Notes

The ASM LB is promoted because it should reduce transport overhead without changing the backend contract. The C implementation remains published so each claim can be checked against a pinned same-commit baseline.

Promotion gates

  1. zero correctness regressions and zero unexpected HTTP errors;
  2. equal or lower p99 latency across downstream stacks;
  3. stable behavior across repeated workflow runs;
  4. no hidden socket-contract changes in compose files;
  5. same-lane image tags: compare asm-ci-<sha> against c-ci-<sha> for the same commit whenever possible.

What to watch

  • LB_MODE=proxy should not parse payloads or add per-request logs.
  • LB_MODE=fdpass should close the LB-owned accepted FD after handoff.
  • LB_FDPASS_SOCKET_TYPE must match the backend control socket.
  • GitHub-hosted runners are noisy, so one lucky p99 should not decide a promotion.
  • latest, c-latest, and release tags are moving or semver pointers; pin immutable tags for evidence.

Tag discipline

latest and release tags are ASM. Benchmark runs that need repeatability should pin asm-ci-<sha> for the promoted implementation and c-ci-<sha> for the C baseline instead of relying on a moving pointer.

Comparison Lane

The active comparison branch is intentionally narrow: it benchmarks the promoted shared ASM LB against the C baseline for the standalone YOLO/assembly API lane. Older archived results may include .NET and C API lanes, but the current workflow keeps only the participants we are actively chasing.

Participant Purpose
yolo-c-lb YOLO/assembly API behind the C baseline LB.
yolo-standalone-asm-lb YOLO/assembly API behind the promoted standalone/shared ASM LB.

The comparison branch workflow writes participant artifacts and then summarizes them into comparison-results/latest.json. The Pages workflow copies that file into docs/public/comparison/latest.json when it exists so the site can render the latest table.

Branch shape

The comparison branch should stay a lean benchmark harness. It normally tracks only:

  • .github/workflows/benchmark.yml;
  • LICENSE;
  • competitor-compose/**;
  • comparison-results/**.

Do not merge main wholesale into comparison just to refresh the harness. Copy or cherry-pick only the workflow, compose files, and archived results that belong to the benchmark lane.

Evidence rules

  • Pin image tags for every participant.
  • Use asm-ci-<sha> for ASM lanes and c-ci-<sha> for C baseline lanes; prefer matching SHAs when the comparison is meant to isolate implementation differences.
  • Keep latest and c-latest out of comparisons unless the test is explicitly about the current moving pointer.
  • Record whether the fdpass socket contract is seqpacket or stream.
  • Keep CI-vs-CI and official-vs-official conclusions separate.
  • Reject correctness failures before evaluating p99.

Workflow dispatch inputs

Use the LB Comparison Benchmark workflow with ref=comparison for real runs. The workflow copy on main exists so Actions can discover and dispatch it.

Input Use
compose_file all-comparison for the active matrix, or a single competitor-compose/.../docker-compose.yml participant.
official_ref Ref of zanfranceschi/rinha-de-backend-2026 cloned by the runner.
k6_image Docker image used when benchmark_k6_mode=docker.
lb_c_image Optional C baseline override; pin c-ci-<sha> for repeatability.
lb_asm_image Optional ASM override; pin asm-ci-<sha> for repeatability.
lb_fdpass_sndbuf Compose-level fdpass send-buffer value for participants that honor it.
benchmark_repetitions Number of k6 repetitions. Increase when investigating noisy p99 deltas.
benchmark_k6_mode native for runner-installed k6, or docker for k6_image.
benchmark_runner matrix runs participants separately; sequential runs all participants on one runner and captures host metadata.

The summarize job writes comparison-results/latest.json and comparison-results/run-<run_number>.json on the comparison branch. Pages copies latest.json into docs/public/comparison/latest.json before building the reports route.

Operations Runbook

Use this page when changing the load balancer contract, publishing images, running comparisons, or validating the GitHub Pages docs.

Local release gate

Run from the repository root before pushing contract or docs changes:

git diff --check
make clean test
cd docs
bun install --frozen-lockfile
NODE_ENV=production bun run build

make clean test runs docs-drift, builds both implementations, then executes the C and ASM integration checks. The C path covers proxy and fdpass behavior. The ASM path additionally covers unsupported LB_MODE, invalid UPSTREAMS, decimal fallback parsing, and both seqpacket/stream fdpass control sockets.

Source-backed docs drift

make docs-drift

The drift checker compares public docs against source and workflow truth:

  • published image tag families from .github/workflows/build.yml;
  • runtime environment knobs from src/yolo_lb.c and src/yolo_lb_fdpass.S;
  • Makefile build/test targets;
  • active benchmark participants from .github/workflows/benchmark.yml;
  • Pages build knobs from .github/workflows/pages.yml;
  • every docs/wiki/*.md page listed in the sidebar.

When adding a new public runtime knob, image tag, benchmark participant, Pages build input, or wiki page, update both the docs and scripts/check_docs_drift.py in the same change.

Workflow map

Workflow Trigger What it verifies or publishes
Build and publish LB images push/PR to main, manual dispatch Runs make clean test, then builds linux/amd64 ASM and C images. Pushes latest, release tags, asm-ci-<sha>, Docker metadata sha-<short-sha>, c-ci-<sha>, and c-latest outside PRs.
Deploy GitHub Pages docs/comparison/main workflow changes, manual dispatch Installs docs dependencies with Bun, uses Node 22, builds with NODE_ENV=production and PUBLIC_GA_ID=G-VN29JG8MTG, uploads docs/out, and deploys GitHub Pages.
LB Comparison Benchmark push to comparison, manual dispatch Runs pinned comparison compose files, archives artifacts, and writes comparison-results/latest.json for Pages.
CodeQL default GitHub code scanning triggers Static analysis for the repository.

If actions/deploy-pages fails after artifact upload with a transient GitHub Pages deployment error, prefer a fresh manual dispatch for the same main head. Rerunning only the failed deploy job can leave multiple github-pages artifacts in the same run and make the rerun fail before deployment starts.

Benchmark dispatch checklist

Run real comparison benchmarks from the comparison branch. The copy of the workflow on main exists for Actions discovery and manual dispatch.

Important inputs:

  • compose_file: use all-comparison for the active matrix, or a single competitor-compose/.../docker-compose.yml participant.
  • official_ref: official Rinha repo ref cloned for the benchmark runner.
  • lb_c_image and lb_asm_image: optional image overrides; use c-ci-<sha> and asm-ci-<sha> for repeatable evidence.
  • lb_fdpass_sndbuf: compose-level fdpass socket buffer value used by comparison participants that honor it.
  • benchmark_repetitions: repeat count; use more than one when chasing noisy p99 deltas.
  • benchmark_k6_mode: native for runner-installed k6, docker for the configured k6 image.
  • benchmark_runner: matrix runs participants separately, sequential runs all participants on the same runner and captures runner metadata.

Reject benchmark results with false positives, false negatives, HTTP errors, or readiness failures before comparing p99.

Live smoke checklist

After a docs or workflow change reaches main:

  1. Watch Build and publish LB images, Deploy GitHub Pages, and CodeQL for the pushed head.
  2. Fetch key Pages routes and assert HTTP 200:
    • /rinha4-lb-yolo-mode/
    • /rinha4-lb-yolo-mode/docs/
    • /rinha4-lb-yolo-mode/docs/contracts/
    • /rinha4-lb-yolo-mode/docs/getting-started/
    • /rinha4-lb-yolo-mode/docs/operations/
    • /rinha4-lb-yolo-mode/reports/
  3. Check that newly documented markers are present in generated/live HTML.
  4. Confirm git status --short --branch is clean and HEAD...origin/main is 0 0.

Runtime troubleshooting quick reference

Symptom Likely check
Container exits with unsupported mode Confirm LB_MODE is proxy, fdpass, fd, fd-pass, or scm_rights. The C baseline also accepts MODE, uds-proxy, and unix-proxy; the ASM image does not use MODE.
ASM exits with invalid configuration Confirm UPSTREAMS has exactly two non-empty Unix socket paths, each shorter than the Linux sun_path limit.
fdpass backend receives no request Match LB_FDPASS_SOCKET_TYPE with the backend control socket type and make sure both control sockets exist before the LB starts.
fdpass backend sees immediate EOF/EAGAIN-like behavior The LB intentionally passes blocking accepted client FDs. Recheck backend socket handling before changing LB accept flags.
Proxy mode returns intermittently Confirm both Unix stream HTTP upstreams are mounted at the documented paths and can accept raw HTTP over UDS.