All Articles

I'll be honest up front: writing about my own work is uncomfortable. I'd rather show you the code than tell you it's good. So this post is a build log, not a pitch. If you take one thing from it, I hope it's not "use my app." I hope it's "you might not need that subscription."

I build Pheidi alone. It's an adaptive running training app: you tell it your race, your schedule, your history, and it builds and rebuilds a plan around your actual life. One founder, no employees, no contractors. That constraint shapes every technical decision I make, and the biggest one is this:

When I need a capability, my default is to build it into the app, not subscribe to it.

That used to be bad advice. "Don't build your own X" was right for most of my career, because developer time was the scarcest thing a small company had. But the math changed. With AI coding assistants, a focused feature that used to take a week takes an afternoon. Code got cheap. Subscriptions didn't.

Here are three things people usually rent that I built instead, with real numbers from the codebase.

1. The feedback system

The standard advice for collecting user feedback is to embed a tool like Canny, UserVoice, or Intercom. They're good products. They also start around $79 a month, ask my users to load a third-party widget, and put my most valuable data, what runners actually want, inside someone else's database.

Here's what I built instead:

  • A feedback form that slides out from the navbar. Bug or feature request, title, description. It captures the current page automatically so I know where the user was.
  • A small endpoint that saves the submission to my own database.
  • An email to me, fired in the background after the save, with the type, title, description, page, and the user's email.

That was the whole first version. Small enough to read in one sitting.

The first version stopped at the inbox. I didn't build a page for it. Every piece of feedback landed in my email, where I already live. Archive for triage, a star for priority, reply for follow-up. That cost nothing extra.

I built the page once "I'll remember what I decided" stopped being true. The admin app has a Feedback page. Each row is the report, who sent it, and the page they were on. I set a status, attach a GitHub issue number the reporter never sees, and write a resolution note. They read that note in their history. When I mark a report fixed, I can tick a box, and the next hourly pass emails them the same note. A new report still hits my inbox first. The page is the record of what I did about it.

The one design choice I'd point at: the save happens first, the email happens second. If the notification ever fails, the feedback is already safe in the database. Boring, but it means I can't lose a user's words to a hiccup in sending mail.

2. The email autoresponder

This is the one where people spend real money. Mailchimp, ConvertKit, Customer.io: the moment you want a welcome email, a drip sequence, and behavioral triggers, you're into tens or hundreds of dollars a month, and the price climbs with your list.

Signup still gets one welcome email, sent right after the account exists, with links to setup and the docs people need on day one. Reply-To is my personal inbox, so answering it starts a real conversation with me, not a ticket queue. That note sits outside the switches. The training mail is six categories, and each one has its own switch.

  • Morning workout reminder. The runner picks the hour, in their own timezone. New accounts start at 8:00 AM. The picker runs from 5:00 AM to 11:00 AM. The email includes today's workout, the pace target, and a heat adjustment note pulled from the live weather forecast. A background service sweeps every 10 minutes and sends each user at most one per day, and only on days a run is scheduled.
  • Phase updates. One email when a plan crosses into build, peak, or taper. At most three per plan. An hourly scan, with per-plan deduplication, so each phase fires once.
  • Weekly summary. Monday morning: how many of last week's runs got logged, the distance, and one line about what's coming. A quiet week gets nothing.
  • Achievements. The first logged run, workout-count milestones (10, 25, 50, 100), a streak record, a new longest run. At most one every three days.
  • Race countdown. A note in race week, a short one the night before, and a check-in a few days after. Three per training plan.
  • Check-ins and tips. The day-3 check-in asks a different question depending on whether you built a plan yet. The day-14 nudge goes out only if you made a plan but haven't logged a workout. The same category also covers a feature you haven't found, or a note when training goes quiet. Those go out at most once every seven days.

The whole thing, schedulers, templates, the rules for who's eligible and when, is a modest amount of code. The templates are plain HTML. The deduplication is handled in the database, so nobody ever gets the same email twice, even if the app is running on more than one server. Unsubscribe is one click and works with Gmail's native unsubscribe button; I didn't want to build email people resent.

I'm not pretending delivery is free. Azure Communication Services actually sends the mail, and I pay per message: fractions of a cent. That's the line I draw, and I think it's the useful general rule: rent infrastructure, build the workflow. Delivery, DNS, hosting? Rent it; that's commodity plumbing with real economies of scale. But the logic of who gets which email and when? That's product. That's the part the subscription products charge you hundreds for, and it's the part that was never hard. It was just tedious, and tedious is exactly what AI-assisted coding removed.

There's a quieter benefit too. Because the email logic lives next to the app code, my morning emails can do things a generic platform can't, like reuse the exact same weather-adjustment engine that the in-app plan uses. The email and the app never disagree, because they're the same code.

3. The agentic tools

This is the newest one, and the one I'd push hardest on if you're building right now.

People are buying "AI features" the way they bought analytics dashboards: as a bolt-on SaaS layer between them and their own data. I think for solo builders that's mostly backwards. You can spend a few dollars of API tokens and give an AI agent raw access to your actual database and your actual product. No middleware, no per-seat pricing.

Here's the part that still surprises me. The AI tools that let me build all of this, the coding assistant I write with and the tokens my agents burn, run me around $100 a month, all in. That single bill replaced a stack I'd otherwise be renting: a feedback tool, an email platform, an analytics dashboard, an AI-features add-on, and a couple more besides. Any one of those subscriptions, on its own, costs about what I now pay for the thing that builds and runs all of them. Half a dozen of them stacked together would be three or four times my whole AI spend, every month, forever.

Two things I built:

A way for AI assistants to talk to the app. Pheidi exposes a handful of actions an assistant can take on your behalf: get today's workout, list the upcoming week, record a run, report an injury, add a vacation, update your profile, submit feedback, fetch the active plan. An AI assistant like Claude can connect, and a runner can manage their training just by talking: "I felt a twinge in my left calf on today's run, log it and ease off this week." The assistant logs the injury and the run, and the plan adapts the same way it would if they'd tapped through the screens.

The actions themselves were the easy part. The hard part was letting an assistant connect to a user's account safely, without me handing out keys by hand. That took some careful work and a lot of reading the standards. But it was a one-time cost, and now any AI platform that speaks the same protocol works with Pheidi without me building a separate integration for each one.

The same trick, pointed at myself. The Feedback page is a queue for one report at a time. It doesn't group a month of requests by theme. When I want that, I don't open an analytics product. I point a coding agent at my own database and ask. "Summarize the feature requests from the last month and group them by theme" costs me a few cents of tokens against data I already own. Every SaaS dashboard is ultimately a fixed set of someone else's queries with a UI on top. An agent with raw access is every query, including the ones nobody pre-built.

What I'm not claiming

I want to be careful here, because "just build it yourself" is easy to say and easy to overdo.

This works for me because I'm one person at a manageable scale. If you have a team, a shared SaaS tool's permissions, audit trails, and onboarding might be worth every dollar. If you're sending a million emails a month, deliverability becomes a profession, not a feature. And there are things I would still never build: payments, raw email transport, hosting. The rule is rent infrastructure, build workflow, and infrastructure is bigger than it looks.

The maintenance is also mine forever. When the day-3 check-in email has a bug, there's no support ticket to file; there's just me. So far that trade has been fine. The Feedback page is one table and a form, and I keep the rest small on purpose.

The actual point

I didn't set out to avoid SaaS on principle. I set out to run a one-person company without drowning, and I noticed that every subscription is not just a bill; it's a dashboard to check, a login to manage, an integration to maintain, an export to worry about. Twenty tools is a part-time job in overhead before any of them do anything for you.

And the bills add up faster than anyone admits. Each tool feels reasonable on its own, $29 here, $79 there. Stack six of them and you're paying several hundred dollars a month, forever, for features that mostly don't talk to each other. I'm paying roughly $100 a month for the AI that builds and runs the lot, and that number buys me code I own instead of rent I'll never stop paying. The subscriptions only ever go up. The cost of building collapsed.

The reason this is newly possible is not that I'm a great programmer. It's that the cost of focused, boring, well-understood code collapsed. A feedback form, a drip campaign, an OAuth flow: these are solved problems, and AI assistants are extremely good at solved problems. The expensive part was always the typing, and the typing is cheap now.

So before you reach for the credit card, it's worth asking the question I now ask every time: is this product, or is it plumbing? If it's plumbing, rent it. If it's product, it might be an afternoon of work to own it outright, with your data in your database, doing exactly what your app needs and nothing else.

That's the whole lesson. The app, if you're curious what all this plumbing serves, is Pheidi, a training plan that adapts to your life. But honestly, build the feedback form first.