Status: Accepted · Date: 2025-Q1 · Deciders: Aarokya Engineering

Context

We needed a backend that could:
  • Handle concurrent payment webhook processing without data races
  • Be deployed on constrained infrastructure (cost matters for a gig-worker product)
  • Integrate with an existing Rust/Smithy expertise within the team
  • Give us compile-time guarantees on SQL queries and API contract shapes

Language Decision: Rust

Node is the natural choice given the TypeScript frontend. However:
  • Payment processing logic benefits from strong type safety and no null/undefined surprises
  • The GIL-equivalent in Node’s event loop limits true CPU parallelism for compute-heavy operations
  • Memory safety guarantees matter when handling financial data
  • Team had deeper Rust expertise for this domain
Verdict: Not chosen for backend core (TypeScript used for generated client SDK only).
Go is a strong contender with excellent concurrency primitives, fast compile times, and a mature ecosystem.
  • Go would have been a reasonable choice
  • Rust was preferred for the compile-time safety guarantees on DB queries (Diesel) and API contracts (smithy-rs)
  • The team’s existing Rust proficiency tipped the decision
Verdict: Not chosen, but acknowledged as a valid alternative.

Rust

  • Memory safety without GC — no runtime crashes from null dereferences or data races
  • Smithy-rs generates production-quality code (it’s what AWS uses internally)
  • Diesel provides compile-time verified SQL queries
  • Excellent async story via Tokio (used by both Actix-web and our async worker)
  • Small binary, low memory footprint — cost-efficient deployment
Verdict: Chosen.

Framework Decision: Actix-web

Axum is an equally valid choice — both Actix-web and Axum are production-ready. We chose Actix-web due to team familiarity and the utoipa integration (OpenAPI generation for Swagger UI) being more mature at the time.

ORM Decision: Diesel

Why Diesel over SQLx:
  • Diesel’s query builder is checked at compile time — a wrong column name or type mismatch is a compiler error, not a runtime panic
  • For financial data (PBA account balances, funding orders, mandate executions), this level of safety is worth the synchronous API trade-off
  • SQLx’s async advantage is partially mitigated by using async-bb8-diesel for the connection pool

Architecture: How the Crates Fit Together


Consequences

Gained

  • Compile-time SQL safety (Diesel)
  • Compile-time API contract safety (smithy-rs)
  • Memory-safe concurrent payment processing
  • Low-memory production footprint
  • Strong ecosystem for background job patterns (Tokio tasks)

Trade-offs accepted

  • Diesel is synchronous — mitigated with async-bb8-diesel pool
  • Rust compile times are longer than Go/Node
  • Steeper onboarding curve for new engineers
  • Schema migrations require Diesel CLI (diesel migration run)