The One-Person Company: Building a Low-Cost Serverless Framework
The great way is simple, yet it unfolds into the intricate. — Laozi
Preface: This is the third essay in the “One-Person Tech Company” series. The concept of OPC (One Person Company) is all the rage right now, so I thought I’d dip a toe in and see what a single person, seriously committing weekends to work only a real tech company could pull off, can actually build. This does not mean I’m going all-in on a startup. I’ve always considered myself a founder perpetually on the road, and the nine-to-five has never been a cage for me. Through this process, I want to discover the boundaries of AI — and my own.
This series will chronicle the entire journey of building a complete technology stack from zero — from infrastructure, to networking and runtime, to the core framework, and finally to application services. This is not a tutorial; it is a field journal, complete with the thinking behind it.
In the previous two essays, we discussed building AWS access control and security architecture with IaC, and the trade-offs in service architecture. With the foundation laid, we must now answer a soul-searching question: With just you, how on earth does the backend actually run?
The answer is almost singular: Serverless.
But here’s the rub — serverless frameworks on the market chase generality to a fault, stuffed with abstractions you’ll never use and flexibility devoid of meaning. So I did something that looks absurd: I built a complete serverless framework in Rust myself, from runtime to CLI tooling, from auth system to infrastructure templates — the whole bundle in one go.
In this essay, I’ll take apart the pitfalls I hit, the trade-offs I made, and the lessons I learned along the way, and lay them all out for you.
I. Why a One-Person Company Must Embrace Serverless
Put yourself in your own shoes: you’re one person wearing six hats — product manager, architect, frontend, backend, ops, and customer support. There’s no on-call rotation; when the server blows up at three in the morning, you’re the one crawling out of bed to fight the fire. No ops team to patch, scale, or watch dashboards for you.
In that situation, do you really want to babysit EC2 instances? Fret over Kubernetes cluster upgrades? Deal with a node whose disk filled up in the middle of the night?
The core value of serverless architecture for a one-person company isn’t “saving money” (though it does save money) — it’s “saving your sanity.” It lifts the mental burden of operations off your shoulders so you can spend your limited energy where it truly belongs: on the product and the users.
Specifically, serverless brings a one-person company three irreplaceable advantages:
First, zero operational overhead. No patching, no OS upgrades, no capacity planning. A Lambda function finishes its job and walks away; you pay only for actual compute. For an early-stage product with wildly fluctuating traffic, this elasticity is a lifesaver.
Second, pay-as-you-go by nature. Your service might get called only a few hundred times a day, yet under a traditional architecture you’d still be keeping at least one instance idling 24/7. With serverless, no requests means no cost. At the stage of hunting for PMF (product-market fit), this means you can run several experimental services at once without wincing at the bill.
Third, a debug loop that is extraordinarily AI-friendly. This point is especially crucial. Serverless architecture naturally produces a wealth of structured logs, and those logs are precisely the information AI coding assistants digest best. When you drive development with AI, it can flip through CloudWatch logs directly, understand the error context, fix the bug, and redeploy — the whole loop closing in minutes. Traditional architectures struggle to be this smooth.
But serverless is no silver bullet. Cold-start latency, vendor lock-in, limited execution time — these are real constraints. The key insight is: for a one-person company’s scenarios, these constraints are almost always tolerable, while the benefits are decisive.
II. Why Build the Wheel Yourself
The market already has mature options like Serverless Framework, SST, and SAM. So why reinvent the wheel?
Good question. Let me break it down from first principles.
First, language choice. I chose Rust for the backend for a very plain reason: Lambda charges by execution time multiplied by memory. Rust compiles to small binaries that start fast, sip memory, and run hard — and that shows up directly as a lower Lambda bill. For an API with the same functionality, Rust’s running cost might be a fifth or even a tenth of Node.js’s. When you’re chasing extreme cost savings, language choice itself becomes an architectural decision.
But Rust’s ecosystem in the serverless space is nowhere near as rich as Node.js’s or Python’s. No framework offers you an end-to-end experience from routing to database operations to auth to deployment. You either cobble together a pile of libraries yourself, or…
Second, framework fit and infrastructure alignment. General-purpose frameworks, to remain compatible with all scenarios and providers, must stack abstraction upon abstraction. Yet serverless and infrastructure are inherently deeply coupled; excessive abstraction and generalization prevent a framework from wringing out the full potential of specific infrastructure. If I want to push AWS services like SSM / CloudFront / KVS / SQS / EventBridge to their limits, I still have to write a great deal of glue code myself, and the value of a general framework shrinks dramatically.
Finally, the AI buff — this is the true asymmetric advantage. The cost of building a framework in 2026 is nothing like it was two years ago. I use Claude Code as my core development tool: write a detailed design doc, then have it implement the thing right there in the terminal. The entire framework’s core code went from design to landing in half a day.
Here’s a point many haven’t realized: Rust + AI are a natural golden pair. Rust’s type system and compiler are like a stern master; as long as the AI’s code compiles, a quality floor is guaranteed. Switch to Python or JavaScript and AI-generated code may “look fine” at runtime while harboring all sorts of bugs — whereas Rust’s compiler blocks those pitfalls before the code ever lands. Types are documentation, compilation is testing, and this “a priori” quality assurance dramatically raises the trustworthiness of AI output.
When the cost of building the wheel is low enough, “building it yourself” is no longer a luxury — it’s the rational choice.
III. The Architectural Panorama: One Lambda to Rule Them All
First, let’s look at the overall architecture, then we’ll take apart each design decision.
The core design philosophy is one Lambda to rule them all. All HTTP routes go into the same Lambda function, with axum’s Router doing the dispatching internally. Does that sound counterintuitive? Shouldn’t it be one endpoint, one function?
No — quite the opposite.
The single-function model has three advantages: First, there’s only one “breed” of cold start. With ten endpoints across ten deployed functions, each function has its own cold-start probability. Merge them into one, and the heat concentrates, sending the cold-start frequency plummeting. Second, deployment is dead simple — one binary file, done. Third, all routes share resources like connection pools and configuration caches, wasting nothing.
The framework (I call it operon) is organized as a workspace, split by responsibility into multiple crates:
operon/
├── core/ # runtime, middleware, auth, error handling
├── dynamo/ # lean DynamoDB wrapper
├── s3/ # S3 operations + presigned URLs
├── webhook/ # webhook signature verification
├── facade/ # unified facade, import on demand
└── cli/ # scaffolding, build, and deploy tooling
The user-side code is remarkably concise: