Jacob’s Tech Tavern

Jacob’s Tech Tavern

The Terrible Technical Architecture of my First Startup

A system that could only be built with the confidence of a 25-year-old Deloitte graduate with an AWS certification

Jacob Bartlett's avatar
Jacob Bartlett
Sep 22, 2025

Carbn defined my career.

For 2 years, I was the tech team of a tiny climate-action startup. I built a mobile app, and multiple backend architectures, from scratch, with close to zero experience.

When I started out my career at Deloitte, I was the classic case of the temporarily embarrassed young billionaire. Body buzzing with energy and undiagnosed ADHD, mind buzzing with dreams of greatness, yearning to someday do a startup. But, unlike my corporate colleagues, I had something my consulting companions didn’t have: I kept not getting promoted*.

*I was basically much too annoying to put in front of clients.

After the annual consulting tradition of “I’m leaving, for real-sies this time”, and some performative job applications to Revolut and Monzo, a recruiter got me in touch with something they thought would be right up my alley.

A commercial strategy consultant, with some cash, validated market research, and a dream, was searching for somebody with energy and a strong technical background to build an app in a potentially huge new market: Carbn.

Carbn was a gamified app that simplified climate action. Calculate your footprint, adapt your lifestyle, and pay for carbon offsets. It was peak late-2010s-ZIRP-era stuff. You honestly could not build this in 2025. But at the arse-end of the COVID lockdowns, the idea was catnip.

It was exactly what I’d daydreamed of for 4 years.

The founder and I immediately agreed to work together and became fast friends. I was the technical co-founding Camilla to a bootstrapping King Charles. I was offered generous double-digit equity, alongside a salary only slightly below what Deloitte paid their mid-level devs / janitors.

Today, I’m telling the story of the systems I created. The decisions I made as the tech cofounder to carry an app business, from scratch. We’ll look at:

  • The initial, rudimentary, backend architecture our MVP shipped with.

  • The “scalable” monstrosity I designed once we landed £200k in funding.

  • What I should have done all along.

At no point did I know for sure what I was doing. But that’s part of the fun.

Subscribe to Jacob’s Tech Tavern for free to get ludicrously in-depth articles on iOS, Swift, tech, & indie projects in your inbox every week.

I’ve recently created a new category of article to write about my rollercoaster of experience in and around startups: war stories. Contact me if you have a wild tech war story you’d love to share with the world!

This email can be too long for many email clients, so please read on my website for the best experience.

Read on my website


As well as from my memories of 2020-2022, this article was reconstructed in large part from old Apple notes I took at the time, as well as floating bits of documentation and code that remain on my old laptop.

Era I: Bootstrapping

Daydreams

While running down the clock on my notice period, I was jogging through the park and imagining the perfect technical architecture. I’d recently completed the second-easiest AWS exam, Solutions Architect Associate, so knew all about how to structure a big system. Vaguely.

I am a fraud: I still carry this certification on my LinkedIn despite it “expiring” in 2022.

I closed my eyes among the trees at Avery Hill and pictured a serverless wonderland, with SQL queries skipping among the Lambda functions. Serverless was the future, I think. I even went full MBA with my consulting training:

  • What are some KPIs and OKRs for Carbn?

  • Do we have a balanced business scorecard?

  • Will we need a data lake, or perhaps a dashboard?

Outside the glaring blind spots in my architectural knowledge, I had a reasonable understanding of my own strengths and weaknesses as an engineer. I was quite good at building quickly. I was relatively slow at picking up new tools. I could usually work things out. I knew a decent bit of SwiftUI*.

I was between iPhones after leaving cosy corporate life, so actually, the first couple of features were UIKit, since I was lent my mum’s old iPhone 6+ which only went up to iOS 12. I was frankly pretty okay at mobile apps, so this piece is more focused on pointing & laughing at my backend setup.

AWS Amplify

We had a tight 2-month timeline to ship our initial MVP, and I was self-aware enough to know I couldn’t learn how to whip up a backend in that time.

There's a known solution for mobile devs with limited backend capacity: Firebase.

Been there, done that, met Peter Friese, got the tee shirt.

The best I could do after several minutes of various shoulder angles and flexing

As an instinctive contrarian, I needed a way to use Firebase without feeling like I was using Firebase. In 2020, options were limited, primarily because I’d never heard of the nascent Supabase.

Enter AWS Amplify: Amazon's answer to Firebase. This was a competing platform-as-a-service (PaaS) that directly mapped core functionality to corresponding AWS services, offering a tempting conversion route directly to running our own cloud infra.

This held the solution to one non-negotiable technical requirement from my cofounder: working offline. For the climate-conscious yuppie on the go. Amplify was batteries-included with a sync engine, making it an obvious go-to.

As I began work, I meticulously crafted an architecture diagram in the hope that this serious piece of engineering planning would pay dividends.

I think these days you’d call it “cargo-culting”

The tech stack utilised the full Amplify toolkit:

  • AppSync and GraphQL for networking

  • DynamoDB for data storage

  • Cognito for email address & social authentication

  • S3 for profile pic file storage

  • Lambda serverless functions to run our Stripe integration and sell offsets.

Back in the day, none of the big open source PaaS toolkits supported SQL databases, so SQL vs NoSQL wasn’t even a consideration (yet). We were locked-in. All our data was stored as a big JSON tree, one per user:

Very early data model structure; from the archives

Fighting the Framework

Anyone who’s built a complex system on early PaaS tools will run into limitations, hard. AWS Amplify is magic when shipping an MVP, but it has myriad invisible guardrails that twat you in the face as soon as reach out for flexibility.

Our data lived in DynamoDB and that was that. Our users were effectively sovereign islands, isolated by the limitations of NoSQL. I couldn’t find any obvious built-in way to create many-to-many relationships between users for our upcoming social features. It goes without saying that they were trapped in Cognito’s auth directory. AWS and their damn free startup credits does a fantastic job of locking you into their ecosystem.

The bane of my existence, though, was the mandatory GraphQL.

Never trust an API so complex your networking code needs to be auto-generated. Or one that you have to re-learn every time you want a new ‘endpoint’. It was just a lot of ceremony, man.

Part of the GraphQL schema (the bit I actually had to write)

Amplify’s DataStore, their persistence-framework-slash-GraphQL-sync-engine, might have been worse. Array data types didn’t really behave like you expected, often overwriting themselves due to confusing conflict resolution rules. I was in a hurry, so instead of learning the idiomatic approach to implementing one-to-many NoSQL, I picked the option labelled “optimistic concurrency” to unblock myself and moved on.

The Results

You wouldn't believe how long it used to take to ship apps before Claude Code. But with some smart scope cutting, we released after about 3 months of work, complete with:

  • The world’s most accurate™ Carbon footprint calculator

  • Smart suggestions to improve your footprint over 6 weeks

  • Carbon offset subscriptions via Stripe payments

The product was just about good enough to persuade an angel investor to take a bet on our founding team.


Era II: Angel Round

Increasing Headcount

Fresh off a funding round, we had a cool £200k in the bank. I took a cheeky 3-week break to hang out with my new baby, because it’s not like we were going to get any more time together for the next 12 months.

We wanted to run cool, so just had 2 key hires in mind: a designer and another engineer. This was my first run-in with the difficulties of hiring. We interviewed some characters:

  • One candidate was 2 hours late (because he said he had to shower), and, when we took him for lunch, loudly made fun of the current COVID mask mandates, to our masked faces.

  • A middle-aged, very experienced, dev willing to work for sub-£50k, who completely ignored everything I asked him to do in the technical test. His email name was Big Chungus. Somehow in my naïvety I was still on the fence. He would have made me his bitch.

  • Someone claimed to have done portfolio work for Peanut, a startup that later moved in next door(!), whose founder laughed and clarified that it was a complete lie.

  • I very nearly hired a friend who, I realised mid-interview, had been stuck doing mindless grunt work for the last year and a half.

  • We spoke to someone who was briefly accepted into a startup accelerator where he tried to design the Uber for Ice Cream.

*I won’t name any names, but three of these bullet points were the same person.

There’s a lesson I can give to scrappy startups looking to keep burn-rate low: Don’t look for someone with any experience. Seriously. You want someone bright, hungry, and energetic; unjaded by the astronomical unlikelihood of their equity being worth anything. This is why the meta is to hire grads straight out of uni.

We landed a UI designer we held onto until the end, a smart graduate dev who job-hopped after a 3-month death march, and an overseas contractor we broke up with after an argument over raising the day-rate. Yes, I really truly suck at management. For the most part, I was on my own.

The Tilt 2 B2B

The biggest strategic failure of our startup was around our target market. In that, we never settled on one.

  • The B2C proposition promised limitless growth from a groundswell of climate activists.

  • The B2B path promised revenue via climate-conscious corporates wanting to achieve net-zero.

Our angel, like all self-respecting Europeans, was nudging us towards B2B because that led to cold, hard cash. B2B focused us on “Scope 3” emissions, a category which included all the emissions produced by employees on-the-job. For many Western services businesses, this is by far their biggest block of CO₂.

But business clients require a rethink of our data architecture. They love a good report, thrive on aggregation, and get a little tight at the trousers for dashboards. NoSQL just isn’t a good fit for this use case. We wanted organisation-level data that piped directly into ESG reports: Employee carbon footprints, summaries across departments, and internal leaderboards that can spark friendly competition between teams.

The basic day-to-day usage of the product also transformed: we wanted to track employee daily habits as they became greener, and gave them Greenmiles every day (I coined the term, like corporate air-miles but for the planet). We fudged the numbers until 1 Greenmile = ~1 mile of driving.

To implement this, we needed relationships between users and their organisations, to-many tables which grew indefinitely for logging, and complex queries for environmental reporting. We needed something relational.

AWS Amplify was no longer suitable for our needs.

Subscribe for free to continue reading

Enter your email and get every post from Jacob’s Tech Tavern.
Already have an account? Sign in
© 2026 Jacob Bartlett · Privacy ∙ Terms ∙ Collection notice
Start your SubstackGet the app
Substack is the home for great culture