Rust Deep Dive

Joseph Swager

Elixir/OTP backend · 25+ yrs security engineering · ex-Instacart, ex-Marqeta

“The goal was a real backend system, not a demo. We shipped a multi-tenant CMS with failure handling built in.”

Joseph came into the engagement an experienced backend engineer looking to specialize in Rust. Rather than working through toy exercises, we scoped a real product from day one: a CMS platform for nonprofit organizations, built on Axum, ractor, Askama, and htmx, with Postgres behind it. The goal was a production codebase he could defend in a system design interview, not a tutorial repo.

Over five weeks and 78 commits, the project went through two full architecture pivots, first to a static-publish, CDN-backed model, then to a multi-tenant SaaS with row-level security. Both times the work was rebuilt rather than patched, which is where most of the real Rust learning happened: the borrow checker doesn't let you fake your way through a redesign.

25+ yrs
Software, cloud, and security engineering
Staff/Principal
Level roles at Instacart, Marqeta, and more
Co-Founder
Now building an AI startup on Elixir/OTP
First
Production Rust project
The challenge

Actor-based async, without the escape hatches

Joseph's prior experience was in languages where a supervisor restarting a crashed process is nearly free. In Rust with ractor, a WebSocket's write half can't be cloned or rebuilt, so “restart the actor” stops making sense once it owns a live socket. That forces a real design decision instead of a default.

The same pattern showed up again in the supervisor: re-spawning a crashed child needs either a boxed async factory closure with exact Send + Sync + 'static bounds, or an explicit enum of known child types. Neither has a clean universal answer, both require committing to an architecture up front.

  • •Non-cloneable ws_tx forcing an explicit restart policy
  • •Type erasure for heterogeneous actor broadcast (PubSub)
  • •Two full architecture pivots mid-build, not just feature adds
The outcome

A shipped platform, not a tutorial

By the end of the engagement Joseph had a working multi-tenant CMS: actor-supervised backend, live htmx updates over WebSocket, and a CDN publish pipeline that renders tenants in parallel and tracks assets with a content-hashed manifest. Every one of those pieces survived a real code review, not just a compiler pass.

He's now taking that project, and the ability to defend its architecture decisions in detail, into interviews for senior Rust engineering roles.

  • ✓Multi-tenant SaaS architecture with row-level security
  • ✓Parallel CDN publish pipeline (JoinSet + semaphore)
  • ✓A codebase he can defend line by line in interviews
Foundations

Axum, auth, and the actor mental model

Joseph came in a strong backend engineer, but Rust's ownership rules combined with an actor-based architecture (ractor) meant relearning patterns he already knew in other languages. We started with Axum routing and admin auth middleware before touching anything concurrent.

  • ✓Axum extractors and async middleware (FromRequestParts, request extensions)
  • ✓First domain actors: Settings, Content, Contact
  • ✓Session auth with sliding-window expiry inside actor state
System shape

One request, one supervised path

Browser request

HTTP + Askama HTML

Axum + auth

routes, extractors, middleware

RootSupervisor

ractor · OneForOne

supervised

Auth

sessions

Content

pages

PubSub

fanout

typed boundariesfailure policy explicitno hidden global state
Deep dive

The WebSocket spike nobody skips

The LiveSession actor was the hardest single piece of the build. A WebSocket's write half (SplitSink) can't be cloned or reconstructed, so it can only live in one place, and ractor's default “restart the actor” story breaks down when the thing you're restarting owns a socket that no longer exists. We had to design restart policy around that constraint instead of fighting it.

  • ✓Non-cloneable ws_tx inside actor state, explicit Transient restart policy
  • ✓Type-erased PubSub (ActorCell) to broadcast domain events to heterogeneous actors
  • ✓Askama fragment templates matched to htmx hx-swap-oob targets by hand
Hardest spike

The socket belongs to the session actor

Browser

persistent WebSocket

LiveSession

owns frame_tx

PubSub

domain events

SplitSink

Non-cloneable write half stays inside actor state.

Heartbeat

Dead socket detected through failed frame send.

eventrender Askama fragmenthtmx swap
Capstone

Two pivots, one shipped platform

Mid-build, the requirements changed twice: first to a static-publish model (render, upload to object storage, purge CDN), then to a full multi-tenant SaaS with row-level security. Rather than patch around it, we rebuilt the publish pipeline to render tenants in parallel and track assets with a content-hashed manifest.

  • ✓Row-level security and a TenantActor for multi-tenant lifecycle
  • ✓Parallel render pipeline with JoinSet and a bounded semaphore
  • ✓Content-hashed asset manifest so CDN purges stay correct
Production pivot

From one tenant to a publish pipeline

Tenant context

TenantId newtype

Postgres RLS

set_config inside tx

Parallel publish jobJoinSet + semaphore
1Render

tenant HTML

2Upload

object storage

3Manifest

hashed assets

tenant isolatedCDN purge correctrebuildable

The journey

One clear path through the build

Drag to explore · Select a milestone to read the full story

Max Wells

Mentor perspective

Joseph Swager brought senior security instincts, but needed a project that forced those instincts into unfamiliar Rust and product constraints. He applied the review habits, modeling discipline, and failure-first thinking we worked on, then carried them through Axum, auth, WebSockets, and a multi-tenant platform that could survive real user input.

Max Wells

Rustify mentor

Want a story like Joseph's?

Max WellsAvailable for calls

Max Wells

Founder · Rustify

Book your Rust career diagnostic

30 minutes, 1:1 with Max. An honest read on where you are and whether Bootcamp or Mentorship fits, before you apply.

Only a few diagnostic slots left this week.

Applications are reviewed carefully.

← Back to case studies

More client journeys

See another path into Rust

Ready to Land a $80k+ Rust Job in the US or Europe?