How I made $11,673 in 5 days with an open-source project

Published in Programming on Jul 13, 2020

At the end of June, I launched a business-focused extension to my open-source project. The multi-tenant SaaS boilerplate for Laravel.

The sales completely exceeded my expectations.

$4,980 within the first 24 hours and $11,673 within the first 5 days.

🤯

Here’s the story leading to this.

Story of the project

Exactly 2 years ago (June 2018), I was 16 and I decided to start building my first SaaS application. It was meant to be an e-commerce platform focused on B2B sales.

After working on the project for 9 months, I needed to implement multi-tenancy. I looked at the existing solutions (Laravel packages) and they all felt extremely confusing and complex.

I decided to do the naive thing and write my own package. See, I wasn’t very experienced with Laravel at this point. I’ve only been using it since around July 2018. And this was at the beginning of 2019.

The main thing that I disliked about the existing solutions was that they pretty much required that you rebuild your entire application around their package.

That felt horrifying to me — again, I wasn’t a very experienced developer.

I felt like there should be a solution that just works with an existing application. The basic idea of multi-tenancy is letting customers have separate databases. Why would I have to rewrite my entire application for this? Why can’t I just tell the app to use database X after identifying the customer?

Version 1

I released v1 of the package in February. It was limited in features, but it fulfilled my needs. I didn’t have to rewrite my app anymore.

The package didn’t get much traction at this point.

The star count for version 1

On February 17, it got the first star on GitHub. 3 months later, it only had 60 stars.

And my SaaS wasn’t succeeding either. I decided to abandon the project basically immediately after I wrote the multi-tenancy package. I realized how bad the code was. The product market fit was there, but I didn’t want to work on this codebase anymore.

I started some other projects instead. They of course got abandoned too, after a few months. Such is the life of SaaS.

Version 2

In July, I decided to double down on the package. I started working on version 2. It added a lot more features and made it less proof-of-concept-y and more production ready. Fulfilled more business needs.

In August, I created a landing page for the project. I started treating it more as a product.

The first landing page
The first landing page.

By the end of August, the project had some 216 stars.

I doubled down on the marketing side of things, got some articles written and by the end of October, the project was at 476 stars.

Burnout

At this point, I took a hiatus from the project. I was juggling multiple projects at once and was starting to get severely burnt out.

For the following two months, I got basically zero work done. On any projects. This was the darkest time for me, work and focus-wise.

There’s a positive side to it, though. Experiencing a strong burnout for a manageable period of time is good — if you analyze it well. Teaches you what not to do and how much it sucks to be burnt out. After an experience like that, you’ll focus very hard on not getting burnt out.

The second landing page
I finished this period of focusing on the package with a second, better-designed landing page.

The lockdown

The coronavirus pandemic was a blessing in disguise when it comes to side projects.

Instead of school, I got to stay at home.

In the past few months I didn’t do much work. So working now was actually refreshing!

The timing really couldn’t have been any better. School got closed first week of March. About 2 weeks after I could (and did) legally get my sole proprietor license.

I took on a bit of client work, started making a bit of $ from that, but mostly I again focused on the package.

There were some quirks I didn’t like about the architecture of the code. I also didn’t like that the package was making an impression of being too opinionated and not enterprise™ enough.

So I focused on fixing exactly that.

I contacted a person who was interested in me adding some more enterprise-y features back in October. I explained that I’m focusing on the package again and that I’d like to add a lot of things to it.

He was very glad to hear this. We talked for a while and he offered sponsoring me to add specific features to the open-source package:

Let me know if €5,000 is a good price for you.

This was huge.

See, the project was released in February 2019. And there were no donations whatsoever until October.

Donations between launch (February 2019 and March 2020)

And even until March, the donations totaled $111.

5,000 EUR felt massive.

This was at the end of April.

I accepted the offer, expressed great gratitude and got to work.

I decided to focus FULLY on the package.

I was writing code and documentation all days nights long. Quarantine did its thing on my sleep schedule, but I was happy. Got a ton of work done.

Woke up at 16:00, went to bed at 8:00. Every day.

On May 13th (about 2-3 weeks after the donation) I announced a closed beta.

Why closed? Continue reading.

Competition

Like I said, there were other packages.

The project that made me create my own package also had a sister package. It was in development for seemingly forever.

However, in May, Spatie — a web development agency that’s very famous in the Laravel world for their open-source work — started writing their own multi-tenancy package.

This made the other project hurry development too. So in May, these packages were being released:

  • My package’s version 3
  • Spatie’s new package
  • tenancy.dev’s new package

This got stressful fast.

The Spatie package was built on the same principles as my package. Automatic, no changes needed. Except it was a lot simpler version.

That was no good!

Also remember when I said that I was trying to focus my package more on the enterprise-y needs, like flexibility? That’s what the tenancy.dev package is about, to a large degree.

Hence the closed beta. I ain’t showing no code to competition!

Comparison of GitHub stars between the packages
The evolution of GitHub stars — blue is my package, green is the older competing package, yellow is Spatie's new package.

The boilerplate

With the beta done, it was time to focus on the commercial product.

The idea was this: Even though the package does all the heavy lifting for you, you still need to implement it. And many apps will implement it in the same way.

So there was a place for another project. A boilerplate with all the stuff you’d be writing anyway. This means customer (tenant) onboarding flow, billing logic, an admin panel, domain management, customer HTTPS certificate management etc.

And it also fit perfectly into my beta. I had a beta that I wanted users to test. I also wanted to build an app that would use the package. This would make me see all the missing parts, from the perspective of a user of the package.

This took about a month of half-work to build.

Why half-work? Motivation was slowly disappearing, the beta & new marketing website was out, so competition was sort of taken care of. Also a bunch of personal stuff happening.

The launch

I was on a family vacation in Southern Europe. I originally wanted to finish all my work before going there, but you know how IT projects are.

I spent the first week doing fun stuff — working out, walking, reading, listening to audiobooks and podcasts.

But after a week of spending my time completely differently than I normally do, I decided to finish the work. So, I spent 3 days inside the apartment. There was no time to go outside, I had to finish this.

I was finishing the package’s features alongside the boilerplate.

The package was ready for release. And so was the boilerplate.

This was at 3 AM in the morning. I was severely overworked and it was time to write an announcement.

I didn’t have enough energy to send an email, do a Twitter thread, make a launch discount or any of the other stuff. Nor did I have the confidence in my abilities to do it well at 3 AM.

But I was glad I managed to get the marketing site done! In some form anyway.

So I went with a safer approach. I announced the release on my Discord server. This way only a small portion of my users saw it and if anything was wrong, I’d manage to extinguish the fire before it got too big.

So I made an announcement and went to bed. I didn’t expect much. I actually don’t know what I expected.

But I can say that waking up to $600 in sales surprised me.

I woke up, went to the bathroom, and went straight to the computer. Inviting people who bought the project to the private community (no automated process — gotta do that MVP!). Improving the marketing page.

Then I got to scheduling a Twitter thread on Hypefury and writing a marketing email on Mailchimp.

Then both went out.

And the sales started coming in.

A lot of them.

A LOT of them.

My inbox quickly got filled with tens of emails with the subject line of:

New sale of Multi-tenant SaaS boilerplate for Laravel - Standard version

https://i.imgur.com/SaBSah1.png

I was incredibly happy.

The first day concluded with a bit over $5000 in sales.

The selling process

The product was sold in two tiers. Standard and Enterprise.

The difference between the two versions was that the Enterprise version got priority support and could be used by companies with an annual revenue of $60k and higher. This is the same model Laravel Nova uses.

I launched the product with two launch discounts.

A “generic” one, that I haven’t yet decided when it will end.

And a better one, that only lasted the first 48 hours.

The prices were:

  • Standard: $299 -> $199 (generic) -> $149 (48 hour)
  • Enterprise: $499 -> $379 (generic) -> $349 (48 hour)

I think given the sales, I hit the nail on the head with the pricing.

It was pretty affordable for solo projects, while also being high enough for the enterprise version.

My project is in this strange space where there are one-man indie hacker projects on one side of the income spectrum, and huge enterprises on the other side of the spectrum. Very little in between.

I decided on the prices the night before, after thinking about them for a long time. The original price I had in mind was too high for one-man projects and too low for enterprises (they can pay more!). So I went with two tiers which solved the issue.

I was also offering discounts for people from lower-income countries. Sold plenty of copies at discounted prices.

A funny thing is that I thought of this project back in August 2019 and thought about pricing it at $49 or something. My rationale was that “Laravel Nova is $99 and it has like 849645745x more features, so my project must be cheaper”.

Stupid thinking. Different audiences, higher price because less total units sold. More directly business-oriented niche. Charge more™ paid off.

I used Gumroad for the launch. I originally wanted to write a custom platform that uses Stripe because I have quite a few of Stripe credits. But in retrospect, that would have been a terrible idea.

Now I just pay $10/mo for Gumroad Premium and get charged similar fees to Stripe. Not to mention that the savings from Stripe credits wouldn’t have been more than $400.

Revenue

The vast majority of the sales took place within the first week. Now I get around 1 sale a day (at the time of writing).

I underestimated the power of the launch and overestimated the tail end, so this surprised me a bit. But looking back, it makes perfect sense. A lot of people were waiting for it and I made a good 48 hour only deal. Everyone who needed it got it and now it's a tiny bit of passive income.

Gumroad sales analytics

There was a bit of sales on Stripe and PayPal too (around $800 worth), so the statistics aren't 100% accurate, but they're accurate enough.

Receiving $10k into my PayPal account meant immediately withdrawing it. I've heard enough stories of people getting 5-figure balances frozen and that's not exactly what I'm wishing for!

Gumroad payout to PayPal

Lessons

Long term value

Long term value pays off. That's what I built with the package. I didn't focus on any monetization at the beginning. I just wanted to build something useful and only now I found a way to monetize it well.

Speaking of monetizing open-source, here's an amazing blog post by @calebporzio: I Just Hit $100k/yr On GitHub Sponsors! 🎉❤️ (How I Did It).

Ideally I'd like to move to some exclusive sponsors-only content too. This would bring less money right now but more predictable passive income. And focusing on this project sort-of full-time would be great. I'd get to work on my own project — something I enjoy — and people would benefit from the growing ecosystem.

I think rather than trying make a quick buck, you're better off building something with long-term value. Something that aligns with your values. If you manage to monetize it well, you can capitalize on the enormous value you created. You can't do that with get-rich-quick schemes. They don't scale.

Tiered pricing

Coming up with a price that would work for everyone and make me enough money was agonizing. After thinking about it for a few hours, I went to Tailwind UI, looked at their pricing components and thought: Fuck it, two tiers, one cheaper than I planned and one more expensive than I planned. Standard & Enterprise.

Revenue from each tier

Turns out that was the perfect solution. Everyone could afford it (see below) and the more enterprise-y clients paid more as they should.

I came up with the $60k threshold for Enterprise by thinking that it should seem attractive and communicate that it will save far more in developer salaries, but it also shouldn't be a bigger investment than 1% of their revenue. So 50-60k was ideal.

Discounts

Like I mentioned, I was offering PPP discounts. The way it worked was that people emailed me, told me where they're from and something about their company and I cut them a discount on an individual basis.

While the discounted price wasn't that small, I think everyone made a profit by buying it.

The idea is "save you X hours of development time for $Y". And as an extension "save more money than you pay".

There were many kind and respectful people asking for discounts. The typical exchange looked like this:
Polite man from India

But I also realized that asking for discounts is almost a scam industry. People coming up with lies after lies to get a low price.

For example: Guy says he's from a low-income country, if he can get a discount. I say sure, if $99 works for him I'll send him a discounted link.

He starts saying that it's for a school project. To which I reply:

My response to school SaaS entrepreneur

And his response:

I'll manage it for $99.

Okay I guess.

But nothing beats this email I received:

Guy asking for the enterprise license for 20 bucks

The entire point of the enterprise license is that you buy it if your annual revenue is over $60k and that you get priority support.

And it costs $499 in original price.

$20 🤔

Waiting list

As always, a waiting list paid off. The waiting list was the second best source of sales, after the Twitter thread.

I had about 400 contacts on my mailing list at the time of sending the email.

I sent another email ~48 hours later about the ending discount. I made sure to mention that it's the last email about the boilerplate — as the first thing in the email, so that people don't get the impression that I'll spam their inbox with this stuff forever.

The package

The open-source part of this project — the package — is growing well, has a healthy community and has recently reached 1000 stars on GitHub.

🙏

A complete history of the package's GitHub stars

And that's it for this post, I hope it was of value.

Thank you for reading to the end, or skipping to the end — whichever you did.

Newsletter

You will be notified whenever I publish an article about the topics you selected. Unsubscribe anytime.

Comments

Your comment will appear once it's approved (to fight spam).