← Back to Writing

January 19, 2026

Nine Lessons from a $3 Million Mistake

Kortex didn't fail all at once. There wasn't a dramatic day when the money ran out, everyone quit, and the servers went dark. It happened much more slowly than that.

We started building Kortex in July 2023. It was an AI notetaking app for content creators, or a "second brain," which was the language everyone used at the time. Two years later, we had spent roughly $3 million on salaries, infrastructure, and operating costs. We had a dozen employees and had reached $60K MRR. We were bootstrapped, and my cofounder Dan Koe had kept the company alive through sheer will.

Still, we had built ourselves into a corner. Adding something as basic as Google sign-in felt like it might take six months.

In May 2025, my cofounder Ari and I went to Japan and secretly rebuilt the product from scratch. That rebuild eventually gave us the confidence to let Kortex go and start Eden.

I've spent a lot of time since then trying to understand how we got there. It would be easy to turn the whole experience into a neat story with obvious lessons, but it didn't feel neat while we were living it. Most of our decisions made sense to us at the time. That's probably the part I find most uncomfortable.

These are the things I think we got wrong. They come from one company and one very specific set of circumstances, so I don't expect all of them to apply to everyone.

1. We had an engineering problem, but the bigger problem was the product

For most of Kortex, I thought better execution would solve whatever was wrong.

The idea seemed differentiated enough. We weren't building another generic notetaking app. We were building specifically for content creators, around the way people like Dan's audience researched ideas and turned them into content. Notion was for everyone. Kortex would be for a particular kind of person.

What we didn't do was test that assumption deeply enough.

We spent two years building without talking to users nearly as much as we should have. We never really sat with the question: what would make someone leave Notion for this?

I think we avoided it partly because the answer might have been uncomfortable. Most of the people we wanted to serve already had a workflow. It wasn't perfect, but it worked. Asking them to switch meant asking them to move years of notes and relearn how they worked. Our product had to be much better to justify that, not just a little more tailored to them.

The warning signs were there. $60K MRR is meaningful, but our growth was flat and churn was high. We interpreted both as engineering problems. The app was slow. We didn't ship often enough. If we fixed those things, we thought growth would return.

Some of that was true. The app did need to be faster. But I don't think speed was the main reason people left. They just didn't have a strong enough reason to stay.

Our own team struggled to explain what we were building. "Notion but with AI" became the easiest answer. We had marketed Kortex as something new, but in practice we were rebuilding parts of Obsidian for the web and adding chat. Features came from different ideas about what Kortex should be, so they never quite fit together.

I put that on leadership, including myself. The team couldn't build toward a clear product because we hadn't given them one.

If I were doing it again, I would spend much more time understanding why someone would switch before trying to build the thing they'd switch to. I used to think the answer would become clear as we shipped. Sometimes it does. For us, it didn't.

2. We prepared for demand before we had it

Infrastructure work felt productive because the results were visible. We could point to a billing system, a deployment setup, or a new piece of architecture and say we had made progress.

We built custom usage-based billing before we had enough users to need it. We wrote Terraform scripts and hosted on EC2 when a managed platform probably would have served us for years. We divided the engineering team into frontend, backend, and infrastructure roles as if we were already a much larger company.

None of these choices were obviously ridiculous. Each had a reasonable explanation. We wanted control. We didn't want to migrate later. We wanted to build things properly from the beginning.

The problem was that we were preparing for a future version of Kortex before we knew whether that version would exist. Meanwhile, the present version still hadn't given enough people a reason to keep using it.

I don't think custom infrastructure is always a mistake. I do think it was a way for us to work on problems we understood instead of confronting the product questions we didn't.

3. We rebuilt things that already worked

Authentication, sync, billing, hosting. There were existing products for all of them, and we found reasons not to use those products.

We worried about losing control. We worried they wouldn't scale. Sometimes using another company's service felt like taking a shortcut, and at the time I thought shortcuts were something serious engineering teams avoided.

Our self-hosted authentication system, Keycloak, ended up costing us hundreds of thousands of dollars in engineering time. We configured it, maintained it, debugged it, and rebuilt parts of it when it broke.

When Ari and I rebuilt the app, we used third-party auth. It took about a week to configure across our platforms and social logins. Then we mostly stopped thinking about it.

That experience changed how I see build-versus-buy decisions. Vercel uses Orb for billing. OpenAI uses third-party authentication. These are much larger companies than ours, and they are comfortable handing off work that isn't central to their product.

For Kortex, auth and sync were never what made the product special. They needed to work, but users were never going to choose us because of how we implemented them.

I first heard this put clearly by Vitalii Dodonov, cofounder and CTO of Stan. He invited us to their Toronto office in November 2024 and showed us how they had built a billion-dollar company with ten people. He told us that "all wheels have been invented."

That line stayed with me. By then, we had spent years making our own wheels.

4. The way we organized the team made everything slower

We split the team by technical specialty. We had a frontend lead, a backend lead, and an infrastructure lead. It felt like a mature way to run an engineering organization.

In practice, a small feature could require three people to coordinate. Someone would be blocked by frontend or waiting on infrastructure. Nobody owned the whole thing, so nobody had the context or authority to finish it alone.

Our stack made those boundaries even harder. We had React and TypeScript on the frontend, Django on the backend, plus self-hosted auth and EC2. Frontend engineers rarely touched Django. Backend engineers rarely touched React. People worked on several features at once but didn't fully own any of them.

I also noticed that narrow ownership changed how we thought about the work. When someone owned one part of the system, it made sense for them to optimize that part. They wanted clean architecture and abstractions that would hold up over time. Those are usually good instincts. They became a problem when we were polishing code for features we hadn't proven should exist.

At Eden, we work differently. Engineers are full-stack and usually own a feature from beginning to end. Our iteration cycle has gone from weeks to hours in some cases.

At Kortex, we generally deployed every two weeks. At our worst, a month went by without an update. At Eden, we ship to production most days.

I'm hesitant to claim that one team structure works for every startup. Ours simply didn't fit the stage we were at. We had organized around coordination before we had enough people or enough certainty to make that coordination worthwhile.

5. Commitment mattered more than hours

We hired more than a dozen people who are no longer with us. Some were interns. Some were contractors or had another job at the same time. Many of those arrangements didn't work out.

For a while, I blamed part-time work itself. I assumed we needed more hours from people. Looking back, hours weren't the best predictor of whether someone would work out. Commitment was.

The people who made the biggest difference felt responsible for the outcome, not just their part of the work. When that commitment wasn't there, deadlines slipped and decisions got passed around. A ticket blocked one person, then another, and eventually the whole team felt it.

Every departure also carried a cost we hadn't properly considered. Knowledge left with the person. Someone else had to be onboarded. Momentum disappeared. We hired quickly because we wanted to move faster, then waited too long when it became clear a relationship wasn't working. Both decisions were expensive.

Ari is the clearest counterexample to my old thinking. He joined in November 2023 as a part-time developer while holding a full-time job somewhere else. On paper, he had less availability than our full-time engineers. In reality, he put in more hours and carried more responsibility. He became CTO of Kortex and later cofounder and CTO of Eden.

Our design lead at Eden is also technically part-time because she's still in school. Her output is better than that of many full-time people I've worked with.

So I no longer put much weight on the label. Full-time can describe a contract without describing someone's relationship to the work. Commitment is harder to identify in an interview, but for a small team, it matters more than I understood at the time.

6. What we shipped slowly lowered our standards

We talked about quality a lot. We had style guides, code reviews, and QA. We also kept shipping buggy or unfinished features because we felt behind.

That contradiction wore people down.

Most people on the team had high personal standards. The environment made those standards difficult to maintain. Requirements changed constantly. Ownership was split between several people. We were trying to move many features forward at once, so each one received only part of our attention.

One of our best engineers left around the time of the pivot. In our final conversation, he talked about the unclear vision, missed timelines, unfinished features, and declining quality. None of it was new information, but hearing it all together was difficult. He had watched the distance between what we said and what we released grow for months.

I used to think speed and quality were opposing forces. Kortex made me question that. We often shipped slowly and still shipped work we weren't proud of. The problem wasn't that we moved too fast. We spread ourselves across too much work, and nobody had enough ownership to bring a small piece of it to completion.

Over time, each mediocre release made the next one easier to accept. That probably did more damage to morale than any single deadline or technical mistake.

7. We should have tested our assumptions sooner

In May 2025, Ari and I went to Japan for what was supposed to be a vacation. We were both exhausted. Development had stalled, and much of our time was going toward maintenance, bugs, and recovering from data loss rather than the things we had promised users.

I had been suggesting a rebuild for months. I believed we could rebuild Kortex in a fraction of the time with a different stack and fewer custom systems. The idea kept getting dismissed, which was understandable. Rewriting software is often a bad idea, and I was asking the team to reconsider years of work based mostly on my confidence.

Ari and I decided to test it without telling anyone.

We spent three weeks in Japan rebuilding the app instead of sightseeing. We used a stack with end-to-end type safety, third-party auth, a sync engine we didn't maintain, and one file for schema and permissions.

Three weeks later, the technical argument was mostly over. We had rebuilt the core of the product, and it worked better than the original.

But the code wasn't the most important part of that trip. Being away from the daily pressure of Kortex gave us enough distance to admit that the product itself also needed to change. I don't know why we couldn't see that as clearly from home. Maybe we were too close to it, or maybe leaving gave us permission to say something we already knew.

The rebuild started as an attempt to save Kortex. It ended up helping us accept that we needed to move on from it.

8. We should have let go sooner and handled it with more care

Sunk cost is usually explained as a financial mistake. For us, the emotional cost was much stronger.

People had spent years building Kortex. Scrapping it could easily feel like we were scrapping their contribution along with the product. Every time a rebuild came up, we heard some version of the same concerns:

"We've already invested so much."

"It would throw away months of work."

"Let's push through. We're almost there."

I felt all of that too. Each additional month made walking away harder because there was another month of work to justify. We kept believing we were close, although what "close" meant kept changing.

When Ari and I came back from Japan and showed everyone what we had built, some people were upset. Some eventually left. I understand why.

People had turned down other opportunities, relocated, and worked nights and weekends for Kortex. Users had paid us and built real workflows around the product. From our perspective, the rebuild proved there was a better path. From theirs, two founders had gone away and made a decision that affected years of their lives without including them.

We owed those people more than a surprise pivot. I still don't feel settled about how we handled that transition. I believe changing direction was necessary, but believing the decision was right doesn't mean we made it in the right way.

Two months later, we launched Eden. We made $250K over Black Friday weekend, four times what Kortex had made during the same period the year before.

That number needs context. Dan already had a large audience, and the launch benefited heavily from his platform. A successful launch is not the same thing as organic product-market fit. Eden still has to earn that.

Even with that caveat, the response gave us some evidence that leaving Kortex was the right decision. If I could go back, I think I would make that decision earlier. I would also try to involve people sooner and handle the human side with more care.

9. I was too certain about too many things

When I look back at our biggest mistakes, most of them started as confident decisions.

We were sure that organizing engineers by specialty was the professional way to run a team. We were sure a custom sync engine would become an advantage. We were sure that if we kept shipping features, product-market fit would eventually follow.

Those beliefs cost us months and hundreds of thousands of dollars. None of them felt reckless when we made them. That is what makes this difficult to learn from. Bad decisions don't always feel bad in the moment. Sometimes they feel responsible.

I still think conviction is necessary when you're building a company. There is too much uncertainty to wait until you know you're right. But I confused conviction with certainty, and certainty made contrary evidence easier to explain away.

I don't want the lesson to be that I should trust myself less. I think it's that I need to notice when confidence has stopped helping me move and started preventing me from listening.

Calling the $3 million "tuition" is tempting because it gives the loss a purpose. Maybe that's partly true. I learned a lot from it. But it was still $3 million, two years, and a painful experience for people who trusted us. I don't want the cleaner story to erase that.


What I would do differently now

In the first week, I would pick a specific kind of user and spend time watching how they work. I would ask what frustrates them without immediately pitching a solution. If I couldn't find a problem that felt specific and poorly served by existing tools, I would probably stop there.

If the problem held up, I would spend the next week building the smallest version I could. I would use third-party auth, third-party sync, and managed hosting. I would save custom engineering for the part users actually cared about.

Then I would put it in front of people and charge for it. Not because $10 proves there is a business, but because paying changes the conversation. People are generous with compliments about free products. Money reveals whether the problem matters enough to change their behavior.

I would keep the team small and give one person ownership of each feature. I would try to ship often, remove work that wasn't helping, and talk to users every week. None of that guarantees a good product. It would at least shorten the time between making an assumption and finding out whether it was wrong.

That's the part I keep coming back to. Early on, we knew very little, but we built as if we knew much more. Our architecture, hiring, and team structure all made changing our minds slower and more expensive.

I don't have a clean ending for this story. There wasn't one mistake, one lesson, and then a version where I got everything right. I changed my mind, moved on, and kept finding new things I didn't understand as well as I thought I did.

For now, these are the lessons I can see. They cost more than I wish they had, and I doubt they're the last ones I'll have to learn.