Technical Leadership
Solo Full-Stack in 10 Months: The Brutal Truth About Building Everything Yourself

Solo Full-Stack in 10 Months: The Brutal Truth About Building Everything Yourself
The Decision to Go Solo
In February 2024, I made a decision that would define the next year of my life: I was going to build a multi-sided hemp delivery marketplace entirely by myself. No co-founder. No funding. No employees. Just me, a laptop, and an unreasonable timeline.
I wasn't naive about the scale. I'd spent years at Google building machine learning systems with teams of engineers. I knew what "well-architected" looked like—microservices, comprehensive testing, gradual rollouts. But I also knew something else: every additional person on a team adds coordination costs. In those first brutal months when you're trying to find product-market fit, coordination overhead can kill you faster than technical debt.
As a solo full-stack developer with no funding or employees
Ten months later, I had shipped five production applications: a vendor portal, courier portal, customer app, ops dashboard, and a backend API designed to scale to hundreds of vendors and thousands of customers.
The system handled Auth0 authentication, a multi-provider, cannabis-compliant payment stack (Hypur for checkout, Sezzle for BNPL, Plaid + Dwolla for vendor payouts), Shippo shipping, Algolia search, and AWS Personalize recommendations.
The infrastructure was ready.
I was completely exhausted.
This is the story of what I built, how I built it, and what I got wrong.
This lands hard without overselling. The short lines give it weight.
The 10-Month Sprint: A Timeline Breakdown
Months 1-2 (February-March 2024): Backend Foundation
I started with the backend API because everything else depended on it.
I used Python + FastAPI for the API layer, PostgreSQL for persistence, Redis for caching, and Celery for async work. The first two months were spent almost entirely on core domain modeling: vendors, products, orders, couriers, and customers.
I made one decision early that shaped the entire build: I would not build commodity infrastructure.
Authentication went to Auth0. Payments went to a cannabis-compliant stack, Hypur for checkout, Sezzle for BNPL, Plaid for bank verification, Dwolla for ACH payouts. Shipping calculations went to Shippo.
Every integration increased surface area and failure modes, but dramatically reduced time to market.
By the end of March, I had a working API with ~40 endpoints. No frontend. No users. But the foundation was solid.
Months 3-4 (April-May 2024): Vendor Portal
The vendor portal came first. Without vendors, there is no marketplace.
I built it with Next.js 15 (App Router), TypeScript, and Tailwind CSS, tools I knew well and could move quickly with. Server Components handled data fetching; Client Components handled interactivity.
The portal supported vendor onboarding, product management, order fulfillment, and payout tracking. I shipped the first usable version in six weeks.
It wasn’t beautiful. But vendors could list products and fulfill orders. That was enough.
Months 5-6 (June-July 2024): Customer App + Courier Portal
I built the customer app and courier portal in parallel, a decision I later regretted.
The customer app covered browsing, cart management, checkout, and order tracking. The courier portal handled route management, delivery status, and earnings.
Both apps shared roughly 60% of the same structure: identical Next.js setups, the same design system, and the same authentication flow.
I extracted common components into a shared directory that I copied between repos. Not elegant. Not scalable. But highly effective for a solo developer under time pressure.
Months 7-8 (August-September 2024): Ops Dashboard + Integration Hell
The ops dashboard was for me.
I needed full-system visibility: order state, vendor performance, courier metrics, and customer support workflows. I built it in four weeks using the same Next.js stack.
Then came integration hell.
Individually, none of the integrations were especially complex. Collectively, they were brutal. The hard problems were in the interactions:
- What happens when a Hypur webhook fails after an order is fulfilled?
- How do you reconcile a successful database write with a failed Algolia index update?
- What do you do when Plaid verification succeeds but Dwolla funding source creation fails?
Getting Auth0, Hypur, Sezzle, Plaid, Dwolla, Shippo, Algolia, and AWS Personalize to work together reliably took six weeks.
Months 9-10 (October-November 2024): Polish, Testing, Launch
The final two months were spent on polish and correctness.
I wrote integration tests for critical paths: checkout, fulfillment, and payouts. I added observability, Prometheus metrics, Grafana dashboards, and Sentry for error tracking. I worked through the most dangerous items in the backlog.
By November 2024, the platform was ready to launch in the Dallas–Fort Worth metro area.
Technical Decisions That Enabled Speed
Looking back, three architectural decisions made the 10-month timeline possible:
1. Monorepo Structure (Sort Of)
This meant I could context-switch between apps without mental overhead. The vendor portal's product listing component looked almost identical to the customer app's product browsing component. I could copy-paste between repos and make minimal adjustments. Purists will hate this, but it worked.
2. PostgreSQL Read Replicas From Day One
I set up read replicas in month two, long before I needed them. This was over-engineering, but it was _strategic_ over-engineering. When order volume scales, I won't have to scramble to scale the database, I can just point read-heavy queries at the replicas.
The setup took an extra three days in month two. It will save weeks of panic when we hit scale.
3. Server Components + Client Components Separation
Next.js 15's App Router with React Server Components was a game-changer for solo development. I could fetch data server-side (no loading states, no client-side fetch logic) and only use client components for interactivity.
Here's a real example from the vendor portal:
// app/products/page.tsx (Server Component)
import { getVendorProducts } from '@/lib/api'
import { ProductList } from '@/components/ProductList'
export default async function ProductsPage() {
const products = await getVendorProducts() // Server-side fetch
return <ProductList products={products} />
}
// components/ProductList.tsx (Client Component)
'use client'
import { useState } from 'react'
export function ProductList({ products }) {
const [filter, setFilter] = useState('')
// Client-side interactivity only
return (...)
}This pattern let me move fast without drowning in state management complexity. No Redux. No React Query (initially). Just server components for data, client components for UI.
4. Celery for Everything Async
Every operation that didn't need to happen synchronously went into a Celery task: sending emails, updating Algolia indexes, generating analytics reports, processing webhooks. This kept API response times under 200ms even as complexity grew.
I configured Celery with Redis as the broker and PostgreSQL as the result backend. Not the most performant setup (RabbitMQ would've been faster), but it meant one less service to manage. For a solo founder, operational simplicity beats raw performance.
What Almost Broke Me
Let me be brutally honest: there were three moments when I almost quit.
The Multi-Provider Payment Stack (Month 6)
Estimated 2 weeks, took 3x longer due to multi-provider complexity
Building a cannabis/hemp-compliant payment system isn't like integrating Stripe. Most mainstream processors won't touch the industry. I ended up with a four-provider stack: Hypur for cannabis-compliant checkout processing, Sezzle for BNPL, Plaid for bank account verification, and Dwolla for ACH payouts to vendors and drivers. Each provider had its own API, its own webhooks, its own edge cases.
The complexity wasn't any single integration—it was orchestrating them together. What happens when Plaid verifies a vendor's bank account, but Dwolla fails to create a funding source? What if a customer's Sezzle BNPL session gets approved, but Hypur can't capture the initial payment? How do you reconcile four different transaction ledgers with your internal database?
I estimated two weeks. It took six. That gap nearly broke my timeline.
Building Three Frontends Simultaneously (Months 5-6)
I mentioned earlier that I built the customer app and courier portal in parallel. This was a mistake driven by impatience. I thought I could save time by reusing components. Instead, I created a context-switching nightmare.
I'd be debugging a checkout flow in the customer app, then switch to fixing a route optimization bug in the courier portal, then jump back to the customer app to implement a cart feature. Each context switch cost 15-20 minutes of mental reloading.
If I could redo this, I'd build each frontend sequentially. The component reuse wasn't worth the cognitive overhead.
The Loneliness of Solo Debugging (Every Month)
With a team, a code review would have caught it in minutes
Here’s what people don’t tell you about solo development: when you hit a wall, there’s no one to talk it through with. No pair programming. No rubber-duck debugging. No second set of eyes in code review. Just you, error logs, and Stack Overflow.
· In month seven, I spent four days debugging a race condition in the order-fulfillment flow. Orders would occasionally be marked fulfilled before courier assignment completed, creating orphaned deliveries.
· I added logging. I wrote tests. I stared at the code until my eyes burned.
· On the fourth night, around 11 p.m., I finally found it: a missing await in an async function.
· One keyword. Four days.
· With a team, someone would have caught it in review. Solo, there was no safety net.
When Solo Stops Working: Signs to Hire
By month ten, the solo-founder advantage had clearly decayed. Here’s how I knew it was time to build a team.
1. Feature Velocity Collapsed
In months one through four, I shipped major features weekly. By month nine, it took three weeks to ship a minor change. Maintaining five applications, managing integrations, fixing production issues, and handling customer support had inverted the ratio of new work to maintenance work.
Early on, roughly 80% of my time went to building and 20% to firefighting. By month ten, that split had flipped.
2. Strategic Work Was Crowded Out
I wasn’t thinking about product strategy or market expansion anymore, I was triaging bugs and scaling infrastructure.
3. Bus Factor = 1
Every system, integration, and architectural decision lived in my head. If I got sick for a week, the company stopped. That’s not a badge of honor, it’s a liability.
The First Hire (Month 11)
· I made my first hire in month eleven: a backend engineer.
· Within three months, we had doubled feature velocity and reduced my bug-triage time by 60%. Coordination costs appeared immediately, daily standups, code reviews, architectural debates, but the leverage was undeniable.
· Solo speed had carried me far. Team leverage carried me further.
Within 3 months of hiring a backend engineer, we doubled output
Retrospective: What I'd Change
What I Got Right:
Choosing boring technology
Python, PostgreSQL, React. No bleeding-edge frameworks. This let me move fast without fighting the tooling.
Building the backend first
Everything depended on a solid API. Starting here was the right call.
Paying for specialized providers
Auth0 for authentication. Hypur, Sezzle, Plaid, and Dwolla for payments. Building these myself would have added months to the timeline.
Setting up observability early
Prometheus, Grafana, and Sentry from month three meant production issues were diagnosable instead of mysterious.
What I Got Wrong:
No automated testing until month nine
I told myself I’d “add tests later.” By month nine, I had ~40,000 lines of untested code. Retrofitting tests took four painful weeks.
Start with tests, even as a solo founder.
Building three frontends in parallel
Sequential development would have been slower in the moment, but faster overall. Context switching was brutal.
Not hiring earlier
I should have hired in month eight, not eleven. The marginal productivity advantage of going solo lasted about six months, not ten.
Underestimating integration complexity
I budgeted two weeks for the payment stack. It took six. Nearly every third-party integration ran 2–3× over estimate.
Takeaways for Solo Technical Founders
1. Solo works for 6–12 months, no longer
The coordination-cost advantage is real, but it decays. Use the solo window to find product-market fit and validate core assumptions. Then hire.
2. Choose your stack for productivity, not signaling
I used Python/FastAPI and Next.js because I could move fast with them, not because they were trendy. Optimize for shipping, not résumé building.
3. Pay for infrastructure; build for differentiation
Auth0, Hypur, Sezzle, Plaid, Dwolla, Shippo, Algolia, I paid for all of them.
Vendor onboarding, delivery routing, and recommendations were the differentiators. That’s where my time went.
4. Set up observability on day one
You can’t fix what you can’t see. Metrics, logs, and error tracking aren’t optional for solo developers, they’re survival tools.
5. Test the money paths first
Checkout, payouts, refunds. Everything else can break temporarily, those cannot.
6. Accept that some things will be built twice
I rewrote order fulfillment three times. The first version worked. The second scaled. The third was maintainable. That’s normal.
Jonathan Sullivan is the founder and CEO of HempDash, a hemp delivery marketplace operating in Texas. He previously built machine learning systems at Google and holds degrees from the University of North Texas and six Udacity certifications in AI/ML. He writes about technical leadership, operations, and building in regulated industries at jonathansullivan.com.
_If you're building a regulated marketplace or scaling a multi-sided platform, I'd love to hear about your architecture challenges. Find me on LinkedIn or Twitter/X._