English static mirror for SEO/GEO · AI-assisted translation · Read Chinese original

Stripe-Style Billing Architecture: Why Rust (Axum + SQLx) Beats Go (sqlc) at High Concurrency

Forum topic · 小凯 · 2026-01-24

Summary

This post analyzes a billing-system architecture modeled on Stripe's scale, arguing that a Rust stack built on Axum and SQLx outperforms a Go stack using sqlc code generation. It describes the operational demands of a payments-grade billing API: over 10 million requests per second, sub-millisecond latency targets with strong consistency, retry-driven connection storms, and rapidly evolving schemas. The author contends that sqlc's compile-time code generation creates a painful loop for frequently changing schemas — every schema change requires regeneration, full rebuild, and redeployment — while SQLx's runtime approach with async prepared statements, cached query plans, and Postgres JSONB/generated columns enables zero-downtime schema evolution without codegen. Reported benchmarks at 10K concurrency show roughly 3x higher throughput for the Rust stack, P99 latency reduced by 68% (0.6ms vs 1.9ms), and memory reduced from 4.2GB to 1.6GB after migration, plus stable connection-pool behavior under simulated 50K req/s bursts where the Go setup thrashes. The article outlines a layered architecture (Axum routes, Tower middleware, SQLx, Postgres with PgBouncer and read replicas) and a 60-day migration roadmap. Note: this is a community analysis inspired by Stripe engineering, not an official Stripe disclosure.

Overview

This forum post (originally published as an interactive Chinese-language dashboard on zhichai.net) presents a deep-dive analysis of billing-system architecture at Stripe-like scale, comparing a Rust stack (Axum + SQLx) against a Go stack (sqlc). The central thesis: for high-concurrency billing APIs, Rust's runtime query approach avoids the operational costs of Go's code-generation model.

*Note: This is a community technical analysis inspired by Stripe engineering practices, not an official Stripe engineering disclosure.*

The Scale Problem

The post frames billing systems as far beyond toy CRUD workloads. The stated challenges:

  • 10M+ requests per second — unpredictable burst traffic and webhook floods
  • <1ms latency targets — with strong consistency requirements
  • Retry connection storms — failed retries can instantly overwhelm fragile connection pools
  • Constant schema churn — metadata, indexes, and fields change daily
  • The "Hidden Tax" of Go sqlc

    While sqlc's type safety is pleasant at small scale, the author argues it becomes an operational burden under frequent schema changes. The pain cycle:

    1. Schema change (add column / change index) 2. Run sqlc generate (code generation) 3. Full binary rebuild 4. Redeploy and restart (risk of service interruption)

    Additional consequences cited: high struct-mapping overhead at high concurrency, increased goroutine scheduling pressure, and connection pools prone to collapse.

    The Rust Alternative: Axum + SQLx

  • No codegen — schema changes don't require rebuilding binaries; bottlenecks are handled at runtime, not compile time
  • Async prepared statementspool.prepare_cached() automatically reuses query plans; SQL is validated at compile time with results extracted at runtime
  • JSONB + generated columns — leveraging Postgres features for zero-downtime schema evolution
  • Reported Benchmarks (Billing API CRUD, 10K concurrency)

    | Metric | Result | |---|---| | Throughput | ~3x higher for Rust vs Go | | P99 latency | -68% (0.6ms vs 1.9ms) | | Memory after migration | 4.2GB → 1.6GB | | Connection pool under 50K req/s bursts | Rust stack stays stable; Go setup exhibits thrashing | | Load testing tool | wrk2, up to 1M+ RPS |

    Production Architecture (Layered)

    1. Axum routes/invoices, /customers 2. Tower middleware — auth, rate limiting, tracing 3. SQLx (async) — prepared statements, connection pooling 4. Postgres + JSONB — read replicas, PgBouncer

    60-Day Migration Roadmap

  • Weeks 1–2: SQLx async fundamentals — async prepared statements, pooled transactions, understanding Postgres behavior
  • Weeks 3–4: Axum CRUD — build Invoices/Customers APIs, integrate Tower middleware (auth, rate limiting)
  • Weeks 5–6: Schema evolution strategy — JSONB metadata extensions, generated columns, zero-downtime migrations without regeneration
  • Weeks 7–8: Load testing and launch — wrk2 testing at 1M+ RPS, comparison against the legacy system (Fiber + sqlc), capstone: deploy a Stripe-style billing API on Fly.io
  • Conclusion

    The author argues that engineers proficient in this stack command high salaries not for syntax skills but for the ability to prevent real production incidents. Suggested résumé highlights from the migration:

  • Axum + SQLx billing API: 1.8M RPS, p99 < 1ms
  • sqlc → SQLx migration: memory 4.2GB → 1.6GB, 3x throughput
*Based on an original report by Dagger (2026).*

Tags

#stripe#rust#axum#sqlx#golang#sqlc#billing-systems#performance-benchmarks

This page is an English static mirror generated for search and AI citation. It may be a full translation or structured summary of the Chinese original. Canonical interactive discussion lives on the Chinese page: https://zhichai.net/topic/176922593