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.
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
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
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
One request, one supervised path
Browser request
HTTP + Askama HTML
Axum + auth
routes, extractors, middleware
RootSupervisor
ractor · OneForOne
Auth
sessions
Content
pages
PubSub
fanout
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
The socket belongs to the session actor
Browser
persistent WebSocket
LiveSession
owns frame_tx
PubSub
domain events
Non-cloneable write half stays inside actor state.
Dead socket detected through failed frame send.
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
From one tenant to a publish pipeline
Tenant context
TenantId newtype
Postgres RLS
set_config inside tx
tenant HTML
object storage
hashed assets
The journey
One clear path through the build
Week 1
Admin auth and htmx scaffolding, first Axum routes live.
Week 2-3
Domain actors (Settings, Content, Contact) built on ractor's supervision model.
Week 4
WebSocket LiveSession actor, the hardest spike: live page updates pushed over a socket owned by actor state.
Week 5
CSRF hardening, then a full pivot to a static-publish, CDN-backed architecture.
Launch
Second pivot to multi-tenant SaaS: row-level security, tenant lifecycle, parallel CDN publish pipeline.
Drag to explore · Select a milestone to read the full story

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 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.
More client journeys
See another path into Rust

Sekou Diarra
13 yrs · Java/Go backend
Senior backend experience translated into explicit Rust domain boundaries

Marko Sabec
18+ yrs · TypeScript/Rust protocol engineering
Long senior engineering track turned into production-grade Rust systems proof









