Hacker News new | past | comments | ask | show | jobs | submit login
20 months, 2K hours, 200K € lost. A story about resilience and sunk cost fallacy (dsebastien.medium.com)
333 points by dSebastien 4 months ago | hide | past | favorite | 235 comments



Great read. Thanks for sharing!

I too think your definition of MVP needs to be adjusted. It sounds to me like an excited user came up with the MVP feature list, not an experienced developer, like "it's gotta have rich text editing capability and pdf export and offline support and nice ui!" because how can you not highlight important notes in bold and download your notes later, right? And it's got to be pretty to look at, and obviously needs to work offline when the wi-fi is down, right?

No, wrong. Everybody I know gets dreamy at first. It's your job to bring people down to earth. Simple text editing at best, and I do mean 'at best'. Basic UI, online only, unsexy solution. If you can't sell that, then you are either not solving the right problem, or it's just not that big of a problem to begin with.

Kubernetes, and Docker and CI? Cool tech, I suppose, but time wasters. Your release process should be scp-ing and extracting a zip file on the prod machine, or git checkout the files.

The one thing that went right was sticking with Couchbase imo. The world is filled with people who regret rewriting the persistence layer for an MVP under pressure. I am one of them. Several times over. Do not doubt the decision. It was the right choice.

Finally, schools and restaurants don't have money for software. I know folks who wrote school software. It was a travesty - the government gets involved at a certain point and wastes your time, the school budgets are razor thin and will not throw money at you. Restaurants are usually low tech as well. Most pay only for basic websites. Find markets with deeper pockets.


For the record, I've used CouchDB multiple times and it was a mistake every one of them. Moving to Postgres never takes as much time as you'd think, and having a database which is rock solid, understood, and performant is a great idea. Choose a DB which you will be happy with when there's an issue at 4AM, not the one fun to use at 4PM.


The problem with specialized databases is that people use them as a starting point at the beginning instead of realizing that that is a premature optimization which they will likely come to regret later on. Initially you are much better off by choosing a standard relational database (Postgres,MySQL,MSSQL, pick your favorite flavor) and then, when you really have to you may have to add something that is specialized. So unless there are hard technical constraints right off the bat (which is almost never the case) stick to simple.


Relational databases are an extremely specialized kind of datastore that people only treat as "standard" because they've been around a long time. They're not better than the alternatives, and in many ways they're worse: by picking a relational database you're committing to difficulty deploying schema changes, difficulty sharding, an awkward square-table model and a terrible query language, and if you make the mistake of trying to use the transactional functionality that's the one actual selling point of those datastores then you're practically guaranteed to deadlock yourself in production at some point during your growth process.


You do know that relational databases were predated by other kinds of databases and were far from standard for a long time, right?

They won their way to becoming a standard, for good reason.


Kinda with you until "terrible query language" as, in my mind, it's the best query language.

You can also opt our of rigid schema by using JSON columns. Which I generally promote as a new best practice when the database is being uses as a dumb store for a smart application. It comes down to who should be the source of truth for the schema.


> Kinda with you until "terrible query language" as, in my mind, it's the best query language.

It's a decent language for ad-hoc querying by humans; the problem is it's the only interface to the database that you get. It was never designed for machine use; in a modern RDBMS, 3/4 of the time to execute a pkey lookup is spent parsing the SQL string. Yes, prepared statements can help in some cases, but they come with their own overheads that make them difficult to use safely in a large system.

> You can also opt our of rigid schema by using JSON columns.

You can, but usually in a database-specific way, and support for that in drivers and especially at the ORM level is pretty spotty.


All the databases seem to have database-specific ways. SQL is the least vulnerable to this. Obviously if you leave SQL for e.g. Mongo, then you could not have picked a more bespoke and unique interface. Notionally SQL is standardized, but who migrates databases anyway.

Network latency is the real performance drag, not string parsing.

I think JSON support will improve, but SQLAlchemy for example is ok with a common JSON interface over mySQL and Postgres. I am sure this will resolve itself in time, its just a bit new for SQL.


> Obviously if you leave SQL for e.g. Mongo, then you could not have picked a more bespoke and unique interface.

In principle yes; in practice you can expect to find full-featured drivers in all major languages, and anything higher-level that claims support for Mongo will also have support. Certainly even the most basic Mongo drivers will let you have things like collection columns.

> Network latency is the real performance drag, not string parsing.

Depends what kind of network, if any, is between the two endpoints. But the performance aspect is just illustrative of what a poor format for expressing machine-level queries it is.


> I think JSON support will improve, but SQLAlchemy for example is ok with a common JSON interface over mySQL and Postgres.

This works extremely well with Postgres. The MySQL one is I think just saving it as a text string, which may become a killer.


> In a modern RDBMS, 3/4 of the time to execute a pkey lookup is spent parsing the SQL string

These times are on the order of sub-milliseconds; about 0.1ms with PostgreSQL on my modest laptop with ~30 million row table.

You make it sound like it's some sort of horrible performance hog, but 0.1ms for parsing a dynamic language really isn't that bad. Actually fetching the row takes about 1ms (without anything cached, faster otherwise), so that's hardly "3/4th" either. With cache it's about 0.1ms, which is about half.

But in reality most queries are more complex, and the parsing time becomes negligible; even for a fairly complex query it's about 0.6ms, which is hardly worth thinking about if you consider that the query execution takes about 60ms.


> But in reality most queries are more complex, and the parsing time becomes negligible

Depends on your usage pattern. If you're actually doing a bunch of different ad-hoc aggregations (which is what SQL was designed for) then yes, query parse time is irrelevant. If you're using an RDBMS as a glorified key-value store (which is what most web applications tend to do) then it's very possible for pkey lookups to be the majority of your queries. (My point isn't really about performance, it's about SQL not being designed for that use style in general).


I have never seen SQL being used as a key-value store. That most web apps use it like that is an incredible claim to me. Do you have any source for that?


I've seen database profiling numbers from some of my clients, but obviously I can't publish those. To be clear all I'm claiming is that for most webapps the overwhelming majority of database queries are simple indexed column lookups, not that most webapps are putting document blobs in the database or using EAV style or anything like that.


Claiming that most queries are simple indexed columns lookups is a far cry from claiming most SQL databases are used as simple key-value stores.


Well, "key-value store" means different things to different people. If most queries are simple indexed column lookups then that carries my original point: query parse time is actually a significant proportion of overall datastore request processing time.


You're whinging about performance and then desire for a full featured ORM. Choose one.


The performance aspect is just illustrating of what a poor representation SQL is for machine-level use. And I'm by no means demanding a "full-fledged" ORM; even basic querying requires a layer or two above SQL to do cleanly.


All of which is still much better than rebuilding that stuff in your application layer, which is what you'll inevitably end up doing otherwise. Besides the fact that you'll likely do so in an incomplete and buggy way.


It's what you end up doing even with a relational database, because the database's built-in implementations aren't controllable enough. There's definitely space for a library that offers standard implementations of these things rather than everyone implementing it themselves from scratch, but applications need a lot more control over them than a traditional database gives them.


You end up rebuilding transactions, foreign keys, MVCC and similar features on relational db's? If so you're probably doing way to much work.


> You end up rebuilding transactions, foreign keys, MVCC and similar features on relational db's?

Yes, because the database-level builtins are too restricted; pretty much the only behaviour you can get out of them is "reject the change and throw away the data" which is almost never what you want, and requires you to keep the data around on the client side and hope that all clients implement recovery consistently. Think about the user-facing behaviour that you want when e.g. one user tries to join a group at the same time as another user deletes the group. It ends up being easier to implement the right thing without using database-level transactions and foreign keys.


> Think about the user-facing behaviour that you want when e.g. one user tries to join a group at the same time as another user deletes the group.

You join first and the group gets deleted or the group gets deleted and you can't join. I don't see the issue.


The audacity to say that when your very own blog includes an article titled "People who disagree with you aren't trying to make things complex. Maybe you're wrong."

There is a reason relational databases are the standard. It's one of the rare things in computer science actually based on mathematics.


> The audacity to say that when your very own blog includes an article titled "People who disagree with you aren't trying to make things complex. Maybe you're wrong."

What point are you trying to make? The point of that article was that the rhetoric about "simplicity" is unproductive, no-one makes a deliberate choice to use something they think is complex. But I didn't make that kind of argument.

> There is a reason relational databases are the standard. It's one of the rare things in computer science actually based on mathematics.

Relational databases are a very finely engineered hammer. But not everything is a nail.


If you don't like relational databases what would you use instead? (And why?)


Without knowing the details of your use case, Cassandra. (Well, in reality Kafka, but that's a bigger leap). Consistent driver availability, easy horizontal scaling (not for performance to start with but for reliability), basic things like collection-valued columns can just work in a common-sense way, harder to shoot yourself in the foot with the consistency model, separate interfaces for fast key lookups and slow table scans so you don't mix them up.


This makes me think about how other people here feel about the arguments presented in this post. Personally, i actually agree with some of these points!

> difficulty deploying schema changes

Definitely agreed, even with tools like Flyway, Liquibase, dbmate or most of the framework provided options (such as Active Record Migrations for Rails and Doctrine for Symfony), most migrations still end up feeling brittle, because you oftentimes do things like renaming a column, or processing some data into a new format, or cleaning up old data etc. Well, you want to do that anyways, but then you realize that instead of simply renaming a column, you'll probably do a rolling migration for the apps that use the DB, therefore you need to create a new column that the app will write data into, then migrate all of the app instances to the new version and then clean up the old column, god forbid validations use the wrong column while this is going on. I don't think it's possible to work around problems like this with technologies like MongoDB either, since then dealing with missing data in an "old" version of a document would still be annoying. I don't know of any good solutions to address how data evolves over time, regardless of technology.

> difficulty sharding

Definitely agreed, in general it seems like most DBMS mostly scale vertically better than they do horizontally. For example, master-slave replication seems doable, but once you want to do master-master replication, you run into problems with latency and data consistency. There are some solutions like TiDB which attempt to give you a distributed database in a transparent way, without making you worry about its inner workings, but that only works until suddenly it doesn't. It seems like this problem affects most distributed systems and i'm not sure how to address it, short of making each new data entry reference the previous state, like CouchDB does with revisions ( https://docs.couchdb.org/en/stable/intro/api.html#revisions ) and even that won't always help.

> an awkward square-table model and a terrible query language

Partially agreed, SQL is pretty reasonable for what it does, despite its dialects being somewhat inconsistent, many of the procedural extensions being clunky and most of the in-database processing heavy systems that i've encountered being a nightmare from a debugging and logging perspective, though i guess that's mostly the fault of the tooling surrounding them. Discoverability can be a big problem if OTLT and EAV are heavily used ( https://tonyandrews.blogspot.com/2004/10/otlt-and-eav-two-bi... ) and foreign keys are not used. Window functions, analytical functions, partitioning and other functionality feels like it's implemented in unintuitive ways in some systems, but that could also be a question of familiarity and a steep learning curve.

> if you make the mistake of trying to use the transactional functionality that's the one actual selling point of those datastores then you're practically guaranteed to deadlock yourself in production at some point during your growth process

Partially agreed, it can definitely happen, but being able to revert bad changes to the data and even test them in the first place sometimes feels like a godsend. Well, there should always be a local instance that's safe to break, but in practice that doesn't really come true often.


>Definitely agreed, in general it seems like most DBMS mostly scale vertically better than they do horizontally.

NoSQL databases do nothing special to achieve horizontal scaling. They simply don't support transactions or atomic operations across documents. If that's what you want you can just choose an RDBMS with that behavior.


Sounds like vaporware to me. If there are any RDBMSes that support practical autoscaling, they're certainly less mature/established than e.g. Cassandra.


> Well, you want to do that anyways, but then you realize that instead of simply renaming a column, you'll probably do a rolling migration for the apps that use the DB, therefore you need to create a new column that the app will write data into, then migrate all of the app instances to the new version and then clean up the old column, god forbid validations use the wrong column while this is going on. I don't think it's possible to work around problems like this with technologies like MongoDB either, since then dealing with missing data in an "old" version of a document would still be annoying. I don't know of any good solutions to address how data evolves over time, regardless of technology.

IME the best way to do it is to build your system on stream transformation (i.e. Kafka) and then you can just produce the new representation in parallel, wait for it to catch up, migrate the readers over gradually and then eventually stop producing the old representation. That tends to be what you end up doing with a traditional RDBMS too, but if you're using something like Kafka then the pieces that you use are more normal parts of your workflow so it's less error-prone.

> It seems like this problem affects most distributed systems and i'm not sure how to address it, short of making each new data entry reference the previous state, like CouchDB does with revisions ( https://docs.couchdb.org/en/stable/intro/api.html#revisions ) and even that won't always help.

There are two approaches that I've known to work: 1. actual multiple concurrent versions as you say, with vector clocks or equivalent, forcing the clients to resolve conflicts if you're not using CRDTs - Riak was the best version of this approach, 2. having a clear shard key and allowing each partition to have its own "owner", making it clear what you do and don't guarantee across partitions - e.g. Kafka.

> Partially agreed, SQL is pretty reasonable for what it does, despite its dialects being somewhat inconsistent, many of the procedural extensions being clunky and most of the in-database processing heavy systems that i've encountered being a nightmare from a debugging and logging perspective, though i guess that's mostly the fault of the tooling surrounding them.

I wasn't talking about the fancy analytics so much as just the basic data model - e.g. having a collection-valued column is just way harder than it should be. Everything being nullable everywhere is also a significant pain.


One interesting heuristic for promoting engineers or making "more-senior" hires for me has been:

1. Curiosity and interest in new tech, so they are keeping abreast of developments and can think of modern best practices where useful.

2. Ability to ignore the new/sexy bits when it comes to implementation decisions, because the trade-off for stability/speed to implement is necessary in a growing company.


I think that it depends on the data model / use cases. When I joined the project, I didn't understand it enough to feel how relational the model really was. It only became apparent to me later on. And by then, it was much harder to replace it.

CouchDB is really nice and has cool features, but for people used to SQL, its a very different beast. Querying is surprising in many ways (less so if you're used to MongoDB I guess).

As you can guess, joins across documents and the like are not really great... and often necessary for relational data.

The correct approach, assuming that we'd want to continue with it would be to denormalize the data much further (which we did not do so far), and perform data reconciliation...

The offline-first case did sound convincing enough to me in the beginning, because we were targeting high level executives, which probably travel a lot more often than others, and still want to be able to work.

But the world ain't static.. It's a different story in post-covid world :p


All data is relational. If you think some data model is not relational then you haven't thought about the problem space enough :p

The only valid reasons to choose non-relational databases are scalability and performance.


>> The only valid reasons to choose non-relational databases are scalability and performance.

Agree 200%. And people seem to get a wrong idea of where this argument starts making sense. With the right indexes, I can easily handle 200req/s on my last SaaS running on a $50/m PostgeSQL.

It's also significantly easier to move from a standardized relational model to a document DB than the opposite.


CouchDB is often just used for simple cloud sync in combination with PouchDB. It's like having a Google Drive integrated into your application. If you do any complicated online querying it's simply not meant for that.


The other reason I'd choose Postgres is because if it turns out you really want something more of a NoSQL style database, Postgres is still very competent.


Of you didn't knew this and doing c#

Checkout the DocumentStore library: MartenDb

It's documentation makes it pretty clear what postgress can do concerning this and event sourcing


There is no small amount of time wasted taking data from non relational dbs and making it relational.

If you prefer nosql, consider something like Hasura which reveals a graph on top of a Postgres dB. I’m not affiliated with either but it’s important to not make tech decisions based on what a developer hears others like to use.


Hasura is a game changing server technology. It handles postgres PostGIS and Json types really well.


It’s certainly one thing that made me wonder why I went in the direction of MySQL all those years ago.. from a modernization perspective it would be a bolt on for any existing Postgres db as well.


Hasura supports or will support MySQL soon (but is not 1 for 1 with PG in terms of features).


To me, it looks as if he wasn't obsessed with the problem.

He did everything except work on the product, from what I can tell, and my guess is that he either wasn't interested in the problem, and not disciplined enough to work on it anyway, or perhaps he suffers from impostor syndrome and don't want to work on the actual product because he thinks he'll fail.

(of course, not bothering about the product leads to bigger failure eventually)


I was probably not obsessed enough with it. It's hard to say, really. I tried hard to create a sound data model and technical solution to support the development, but often felt like we needed this and that refactoring to be able to move forward.

Impostor syndrome is indeed strong... ;-)


Reading your essay it feels like you were obsessed with the product's artefacts, the methodology, the tech stack, the hosting, the scalability, the suportabiliry..., far more than wth the solution and getting the first sale.

All of these are good qualities, but if you then do not have a product owner to push back and force you to deliver fast and cut every corner imaginable, you can indeed find yourself in endless development rewrites and optimisations.

I have seen quite a few startups up close in Belgium, and I'm fairly confident that you would be horrified by the code base and operations of the ones that are succeeding.

P.S. Smartschool seems to be triving in the Belgian school system.


What the comment you're replying to is saying, is that if you were deeply obsessed with the problem, you wouldn't have to think twice to make trade-offs. If the problem you're solving really needs solving right now, you will always make the trade-off that gets your solution into the world faster. You're not obsessed with the fact that teams all over the world could have less sucky meetings if they had an even incomplete version of your product in hand right now.


Others have said already but switching cloud providers, kubernetes, ci/CD, couch... it seems more like you were more interested in playing with tech than building a company


Thanks.

I think that you're spot on. I've probably been more obsessed about "the way it should be" rather than "what's the shortest path to get our first clients using it". I suppose that it's a newbie mistake; out of fear.

Part of me couldn't accept the idea of delivering something that would explode and that I wouldn't be able to support in production. It's still something I fear, especially when I look at our code coverage, even though I do care about the quality of what I create..

As you say, switching from CouchDB to PGSQL wouldn't be easy at all.

And yep, agreed about schools and restaurants, you're probably right.


It sounds like you might not have the right mindset for being a technical startup founder.

Unit tests and code coverage is anticorrelated with success. With a startup, your goal is to iterate the fastest. You cannot afford to be spending more than 1 day of time on your continuous deploy system before you have your first paying client.

Given the size to your team, you should also have been spending near zero time on documentation. Documentation should be in the form of sticky notes and Slack messages.

I think you’re very talented technically, but you should not work on startups until you are able to emulate more of the successful technical cofounder patterns.

If your code and processes can scale to 100x of your time expected volume, this is almost universally a sign that you have failed to optimise for what matters.

This also goes even if you’re building something like AWS. AWS engineers do not build over-engineered systems that can handle 100d of its expected volume.


I find this weird. Automated testing has saved me so much time.

If I don't have tests and make a change, I have to manually go through a whole set of checks to make sure I didn't break anything. If I have a test suite, it will tell me in 2 minutes if I broke anything.

The thing I'm working on at the moment has tests on the backend but not on the UI. I can definitely say the UI work is slower because of the lack of tests.


You're essentially in prototyping phase. Inevitably you'll have to discard whole chunks of code, because your understanding of requirements/concept space changes. Then you have to discard both your code and your fine tests, wasting ~2x more time.


Yes, but writing tests isn't a huge cost if you're used to it. And once I've discarded that huge chunk of code, I immediately know what else I broke, rather than having to find it by testing manually.

If I have to write 100 lines of code to implement a feature, it really doesn't take me twice as long to write another 100 to test it. In most cases, writing the test alongside (or even before) the code helps with writing the code. I'd say writing a test adds maybe 25% to the time.

Knowing a year later than that code is still good, because that test still runs successfully, is easily worth that 25%

Of course I'm not saying 100% code coverage is worth it. Just the critical bits.


Thoughts of "a year later" and MVP mostly don't mix.

Agreed about coverage.


Test suite is not free to create or maintain. To your example, for a product that isn't mature, a UI test suite is a waste of time and greatly increases the cost of UI changes.


This is what I don't get - a test suite saves me time. So, yes, it is free to create and maintain. Because it's much quicker to find regression bugs with automated testing than with manual testing. And this is massively more valuable when things are changing rapidly.


I think the core of what they're trying to get at is: let the users find those bugs. The business isn't large enough to focus on details, yet. In the future, when fixing bugs takes more time than making features, you should have the money to hire more hands and focus more on testing. If you don't, then you built too much product for too little clients which is a problem in and of itself ;-)

The cost/benefit isn't there in the beginning. All the bugs are either obvious, easy to find, or quickly discovered without a test suite. So save the time writing tests to stamp out more features the customer wants!


Adding features adds complexity. Features interact with each other in complex ways. If you add a feature and don't know quickly if it broke another feature, that costs time.

Letting the users find the bugs costs time - you have to talk to the user, replicate the bug report, find the failure, fix it, and then release. Finding that same bug 2 minutes after you wrote it (and before it got released) is massively quicker.

This feels like one of those "write code 16 hours a day to make more progress!" things that experience has taught me just doesn't work in practice. I feel like I'm making a lot of progress, but after about 10 hours most of the code I write is pure shite and needs to be rewritten the next day. I've found that it's actually way faster to quit coding after 8-10 hours rather than spend 2 hours the next day rewriting everything I wrote in the last 6 hours the day before.


> finding that same bug 2 minutes after you wrote it (and before it got released) is massively quicker.

That's not realistic.

Your last paragraph about overwork seems unrelated to TDD dogma.


That's because I was relating my personal experience building MVPs rather than spouting TDD dogma.


Tests cost money up front. Can you pay for those tests? You said you will pay for it in decreased costs once the business is running well.

Ok but how confident are you that your business will work out?

1%? you just increased your project costs 100 fold by doing tests.

50%? you just doubled your project costs by doing tests.

100%? Ok you are saving money, but if you are that confident then why haven't you gotten investors aboard that are convinced that doing it well from the start is a business edge?


The mindset and goals are much different. At the extreme, a showstopper bug in an MVP is not a big deal - you have few (if any) customers and a glitch here and there won't make any difference in the long run.

Early stage tech founder should be either a cowboy programmer or a business-minded project manager, the type who ruthlessly kills projects and blows things up on a whim.


That's completely dependent on what kind of software you are writing. (And yeah, if you caught yourself automating UI tests, you are probably way too far.)

The best phrasing is the OP's in that "automated tests are anticorrelated to success" (so is posting on HN, by the way). That doesn't mean that for your exact case they are not essential, just that there is an statistic relation.


Indeed. The required mental shift became much more apparent to me in the recent months. I guess I'm slow :)


I don’t think that you are slow or not a good developer is the right conclusion. I think you focused on the wrong things. Like code coverage, CI, etc.

You mentioned of being afraid of your codebase exploding in other comment. You know code don’t really explode, right? The worst case is you will need some refactor down the road. Nothing worse than that.


You might be surprised about how much code underpinning our society has no tests at all, how many huge companies place no value on test coverage.

And it all mostly works just fine. It might be even the right decision some times to not spend time in tests!


Don't be too hard on yourself or you'll start doubting your own decisions too much. Everyone screws up some things, and nails some other ones.

Here's something that helps me with development. First, decide if it's a personal project for learning/fun, or if it's a commercial solution you are developing for someone else.

Personal projects get the cleanest code. I obsess with perfection. Max optimizations. Sexy tech. I'm Michelangelo and this us my Sisteen Chapel. John Carmack himself should take notes from that code. You get the idea. This project never ships though. 9/10 times I learn what I need and then it's just about grinding, I get bored and move on.

Commercial products or projects I really need to ship get a clean design, but thats all. I spend some time to design the foundation correctly, and from there, its an ugly, duct taped, unoptimized piece of crap that I can iterate quickly on.

Also, make sure the power dynamics in your team are correct. Dont get hired to write the code. Get hired to develop the technical solution. This way you can say "no" to things.

A pattern I've noticed much later in my early endeavors: if the business people (those writing the check) are also the product managers, the project is likely doomed. You know the type of person. They will insist on which features need to be there because having money automatically makes you an expert. They typically think of the end product as the MVP.

One last thing, internalize the following:

"Make it work. Make it right. Make it fast." <- in that order.

I say this, because you mentioned code coverage, and I would like to say that my opinion is one doesn't need unit tests for the first step.

Basically, screw the tests. I know, I know, how can anyone take me seriously when I say that. But, why do you need unit tests? To catch bugs in an MVP? Who expects rock solid, bug free MVPs? Maybe its to sleep better at night because code coverage is representative of code quality? We know it's not, so why bother?

Your MVP should be small enough that it's entire functionality is critical paths through the code. This means that every time you click through your product you are testing your code and you should be able to exercise most of it quickly and often. Unit tests are basically code that you have to maintain when something changes and it decreases your velocity. You don't want that, you just want to "make it work".

Will you eventually pay the price for not having unit tests initially? Yes, of course, but, if you designed your MVP correctly, this will either be never, because the product doesn't have market fit, or right at the time when you are getting product-market fit and are growing your team. At this time you will have a great idea of what functionality to add tests for. You won't even give a damn about the code coverage, because now is when you "make it right".

Either way, exclusions apply because software is hard. Good luck with your endeavors and keep coding ;)


I agree with your point, but when it comes to tech choices I would say it depends on the experience, the point is that for an MVP you should go with things you know well and are efficient with.

One can setup a Gitlab pipeline with Docker and docker-compose and continuous deployment in something like 7 hours, when pretty used to it.

In this case, automating migrations can be done by running the migration script in Docker image command, and then you can have a proper RDMS that you have to add to docker-compose, if you've gone for a development framework that supports migration of course, which I believe you should in general.

For example, I made electeez.com which is now the less insecure online voting solution that I know of, thanks to homomorphic encryption library microsoft/electionguard and Django, in 3 weeks, add another week for a proper TDD rewrite that accounts for security of the endpoints, at the pace of 3 work days per week. Of course, mvp.css helped a lot too!

If I were to implement a better webdesign, my next step would be to use the Material Components Web Components served by Skypack and just follow the Material Design Guidelines so in another iteration of 3 days have something that's a bit more beautiful ... but for sure, beauty doesn't matter for an MVP, only usability does.


I agree with the main point but:

>Kubernetes, and Docker and CI? Cool tech, I suppose, but time wasters. Your release process should be scp-ing and extracting a zip file on the prod machine, or git checkout the files.

Ok, let's accept that K8s is overkill most of the times. But containerization and CI/CD? If you've some experience with it you know it's something that takes little time and money to set up (e.g. GitLab CI) and you get tons of benefits - you don't need to get super fancy either.

To me it sounds like the time waster would be doing what you describe, specially because it's so easy to mess it up after you do it a bunch of times on a single day. I used to do that when I started with PHP several years ago (replace scp-ing with FTP and git with cvs or svn) but IMHO it's not worth it once you deploy your product live.


> But containerization and CI/CD?

It is. For a very small startup, with not outside funding, everything that is not DIRECTLY related with A) Getting a paying customer. B) Launching, is a complete waste of time.

Please note this is not the only game in town (if you are Boston Dynamics by all means take all the time in the world to make those robots awesome) but if you are Yet Another Small Saas company for the love of god, launch, launch, launch.This is the game you chose to play.I dont care if your control version system are different folders and your backup are floppy disks, just launch and see if you can get people giving money to you for your product.


I have a tiny application. Yet it involves 5 containers. Some of the applications are a pain to install unless you go with a specific linux distribution and use their existing package. I don't have the time to manage all that crap through a labor intensive method or manage 5 separate servers when I can do it on one with containers. When I have to do things quick and dirty I just use a shell script with docker run and that's fine for 90% of projects because they don't pan out anyway. I can trivially switch to docker compose and then if I need scaling go to Kubernetes. It's a 100% solution. For the smallest prototype to large scale solutions. If you manage your servers manually you will either have to learn ansible which is just plain awful and difficult to use or you spend a lot of time doing everything yourself. Both cost time at the start of a project and many people don't have that time to waste on useless purism.


No way, maybe if you're working alone, but if there's even just two of us 'collaborating' via 'different folders and floppy disks' is going to slow me down, not speed me up.


It was hyperbole ffs, today it is more difficult to use floppy disks than Github. The point is that you dont need all the fancy stuff that more established companies with 10X-1000x more employees than you use.


Appreciate that re floppy disks specifically, I believe I did take it as intended, I was reacting to just sharing dumb directories - however they're pushed about - more than anything. I use git for things I work on alone, I find the ability to branch and stash etc. a net productivity improvement, not something that hampers me; add in collaborating with even one other person and I wouldn't even consider not using it, I'd honestly decline a job offer (well, everything has its price I suppose..!) over it, there's no way that's not a nightmare.


> But containerization and CI/CD? If you've some experience with it you know it's something that takes little time and money to set up (e.g. GitLab CI) and you get tons of benefits - you don't need to get super fancy either

This - CI/CD during development pays off so fast it's not worth skipping.


I don't regret setting up CI; it has saved us quite some time already with broken PRs (haven't tried CD, and I won't before we sell this thing :p).


How did you go from "manual upload to file server" to Docker+Gitlab?

We've been shipping MVPs long before those were a thing.

./deploy.sh runs the commands you used to run manually.

What problem are you solving now with containers?

Listen to what you are saying: "It will take little time" and "it will be worth it down the line". These are bets. People get this wrong all the time.

Don't take the bet. That's happy path thinking. Take the shell script and 0 dependencies on external services and complex software.


Dockerfiles are just a few lines of shell script and a single shell command away from a fully reproducible image that can be run anywhere. They are also reusable across projects. This is a point where you can easily carry over your productivity if you are constantly starting new projects. Your latest project will be much further ahead on day 1 than your first project. Compare that to manually typing in commands on a server to set your production environment up. You'll forget things (massive drop in productivity) or have to write them down (massive drop in productivity). You'll redo the same stuff over and over (massive drop in productivity). For what gain? Just to stay purist?

You are taking the advice way too far. The advice is do things that increase your productivity and many things that increase productivity are also easy to setup once you know them. I'm not saying that you should learn containers for the sake of your startup. I am saying that tools you already know well often require very little effort to setup and pay dividends immediately.


> How did you go from "manual upload to file server" to Docker+Gitlab?

When I learned what I said: it takes little time to set it up and you reap the benefits. If you don’t know how to use it then it’ll take some time to learn, in such case I see value going with whatever you know.

>We've been shipping MVPs long before those were a thing.

That reasoning can be used with almost any technology and doesn’t tell anything.

>./deploy.sh runs the commands you used to run manually.

You went from “manually copying” to having a script with reproducible steps. You’re closer to CD than what you were thinking.

I think the rest of the comment doesn't need to be addressed.


Disclaimer: I am building a product to address the same need for getting started with SaaS products as a kit, including Docker, Kubernetes, CI/CD and more: https://saasstarterkit.app/

I strongly agree with this. Investing into a quick setup for CI/CD in the beginning of a project pays of really quickly. Every time someone comes up with a "simpler" suggestion to deploy things, I find it always tricky and not-so-simple because of the following questions: - which machine do I deploy my code to? should I use an existing VM or should I get a new one? - what dependencies do I need to have on the machine? do I install them manually for each project? - how do I deploy multiple projects on this machine? what if the dependencies conflict? - how do I get the code to the instance? Should I use SCP, or Git, or some other method? - once the code is in the machine, how do I start it? how do I ensure it is running? - how do I securely expose it to the internet? - how do I serve multiple projects from the same instance?

Obviously, each of these questions have answers and they can be solved, potentially "simply" for some; but for myself, I found these to be way harder to deal with then a few lines of Kubernetes configuration. I use Docker for packaging the application, I build everything on GitLab CI, and just deploy to the same Kubernetes cluster for all of my projects. With this setup, I still use a single instance and have very low stable costs, and I can deploy 10+ projects on the same cluster since they have small load for now. Everything is standardized, and I can get to live in minutes even for a new project.

I believe the idea that these tools overcomplicate things need to ba taken on a case-by-case basis. For some, it works; for others, it won't, just like any other custom script or "simple" solution.


> The world is filled with people who regret rewriting the persistence layer for an MVP under pressure.

I think this may be true for people that switch from noSQL to NoSQL or from RDB to NoSQL, but very few that switch from NoSQL to RDB.


>"If you can't sell that, then you are either not solving the right problem"

Interesting. When I act as a client and looking to buy me some software the first things I am looking for:

  1) Does it have perpetual license for at least the version I am about to buy.

  2) Can it work offline?
Answer either of 2 no and I am not buying it. Well this of course excludes things like Netflix. The product I make offers either either perpetual license or subscriptions so the customer gets to choose. So far perpetual license revenue exceeds that of subscriptions.


Why would you care about having unlimited access to an app that doesn't necessarily do what you need it to do? That's what we're talking about here - all the MVP should do is the absolute minimum to solve the problem it sets out to solve, and as a customer you don't know if it actually does that until either you've tried it, or you have validation from other people who've tried it.

No one should be worried about perpetual licenses or offline support for an app that hasn't proven it even solves the problem in a viable way yet. If those things are key to your purchasing decision then you probably ought to be buying from established businesses with proven products and good support, and that is definitely not any startup I know.

I suspect your comment betrays the fact that you think the first version of a startup's software is the first finished and stable version. That's the main problem here. Startups need to be selling long before they're at that stage.


>"Why would you care about having unlimited access to an app that doesn't necessarily do what you need it to do?"

This is completely empty and made up argument. For every piece of software with perpetual license you can normally get evaluation version. Download and evaluate to your heart's content. Normally it is 30 days but I have not had one case in my live when vendor refused to extend eval period when asked.


Counterpoint: that guy right there is your user. He's the guy you're selling to.

If he doesn't think you're worth the money... You can say gravity is wrong all you want, you're still hitting the floor.


He's the guy you're selling to.

He wants a different product with features that aren't in the MVP. He absolutely is not the person I'd be selling to. If it turns out that I can't find customers selling what I think is the right product for the market then I might have to pivot to build what he wants, but until then he's just someone who isn't my potential market right now.

Startup sales is about getting the customer to buy in before the product is exactly right for them. Changing your product to suit whatever the person in front of you wants is massively distracting, often bad for the product, and doesn't guarantee a sale anyway.

If he doesn't think you're worth the money..

The product not being what someone wants only means it's not worth the money for them. That doesn't mean the product isn't worth it for anyone. You need to find the person who wants what you have right now despite it not being perfect, and who is willing to pay for what you have on the basis that it'll become what they need in the future.


It's rather unlikely that an anon on social media (HN) is "the guy you're selling to." Possible, but there are so many other motivations for a critical comment. "The guy you're selling to" is tangible and clearly has money to spend to solve a real problem.


If there is anything I've learned on social media, is that when you pitch an idea on Internet you can have hundreds of people swearing they'll buy your product day 1 if it has x, y or z. When the time comes to pull out the credit card however, suddenly everyone is gone.


Typical hacker news answer, There's always someone to come along and have the exact opposite opinion. :) But seriously, I can understand the preference for offline, non-subscription software, it's often cheaper and it's often faster. Non subscription doesn't provide for a steady revenue stream for the developer, however.


>"Non subscription doesn't provide for a steady revenue stream for the developer, however."

Developer is not entitled to that "steady revenue stream". Keep working and releasing new products / features that customers are willing to pay for and you'll be fine.


>Answer either of 2 no and I am not buying it.

Well, this makes you irrelevant as a target customer in this heavy subscription/SaaS 2020 market.

There are others like you. But not many enough to make it worth focusing on them, plus they'd be more picky and have all kinds of other demands too that regular users don't have.


>"Well, this makes you irrelevant as a target customer in this heavy subscription/SaaS 2020 market."

My personal opinion is that this business model is simply not sustainable long term except for cases where the subscription model is a natural choice (Netflix for example). If I had to pay subscription for every piece of software I own I'd be ruined. With perpetual licenses however I only update / upgrade when I feel there is a benefit in it for me. Otherwise that old copy keeps working. I suspect I am not alone here.

As for not being relevant: so far I do not feel any lack of software offerings with perpetual licenses so allow me to disagree. I maybe irrelevant to your strict business model but not to the overall market.


>If I had to pay subscription for every piece of software I own I'd be ruined.

That's a very good point.

But also neither here, nor there. That's here the market seems to go, and it seems to indeed want us all ruined.

Or, rather, living paycheck to paycheck to pay those things...


I have this what I consider healthy attitude: I do not really give a flying fuck about what market wants. It seems that the guys like myself are still served really well. As for what happens in the future we'll see. I am tired to count how many times said marked had to correct its wet dreams.


Before I riff on him a little, I'm very thankful the author shared his experience, that takes a lot of bravery. He's also not the only person to make this mistake, so many have. I learned a lot of these lessons from making a bunch of expensive bone headed decisions myself. I also am not implying that just because he fundamentally doesn't understand an MVP or how to build a lean startup that he isn't an awesome dev, I honestly bet he is a great dev who just learned a valuable lesson(3 times :| ) about what an MVP truly means. ( I haven't shared them because I'm awful writer, but I hope to one day )

But wow does this guy not understand an MVP or what matters for a startup.

> I became more and more “aggressive” about reducing the scope and focusing on the essentials

You should do this day one before you write a line of code. There should be nothing you can cut from your MVP. For the first two months of my last MVP to edit data you sent an e-mail to a dev who wrote a sql script that edited it for you. We still added 3k MRR each month. For every feature you should ask "What would happen if I cut this out?" if the answer is anything but "It literally wouldn't work for any individual who could conceivably use this product (with a broad definition of conceivable) then the answer is cut it. Is it a differentiator? cut it. Does your product suck without it? cut it.

You can always trade time for features, but you can never trade features for time.

> Maybe I obsess too much about code quality

The answer is YES YOU DO! Code quality doesn't matter. It really doesn't matter. What killed your first three startups? Was it code quality? Or was it was not getting out a product fast enough, not iterating quickly enough, and not finding product market fit fast enough. This experience is typical.

If the code quality on your MVP doesn't physically disgust you, you're probably focusing on code quality too much.


It's funny how different peoples' experiences can be. I personally witnessed one of the two startups I worked for fail as a result of code quality. Things ended up being too slow and error prone for some of our customers, and eventually they left us behind. We tried to attract new customers, we had amazing feature set after all, but the performance/stability hole ended up being too big to dig ourselves out of before we ran out of money.

I agree that the poster likely focused too much on it, but it's definitely not something you can ignore completely with the assumption you'll always have extra time later to go back and fix things.


To split this hair a bit, I think “code quality” has two definitions:

1. the degree to which the code can be trusted to operate correctly and in a fault-tolerant way (i.e. “yeah that API endpoint will give you a 5xx about 2% of the time, sorry about that, just retry!”)

2. the degree to which the code optimally models the problem it’s solving, as well as how flexible it is as priors/needs change in the future and whether optimal languages/frameworks/patterns are used to solve the problem expressively.

The former has obvious customer implications — if your webapp craps out every ~20min of usage, or your API silently drops data when it can’t persist something to a data store, that’s bad, you will lose customers (and you deserve to!). Conversely, lacking in the latter could slow you down as you iterate, but you’re just as likely to not need to touch that code for a while if you’re off building new views/features/what-have-you.

I think the “don’t worry about code quality” folks are generally trying to beat it into technical founders/builders’ heads that the thing they’re building is ultimately being judged as a product, not as an engineering project... but that doesn’t mean that reliability and performance aren’t part of what may make your product valuable.


To expand on something you hinted at. I think it's a very important insight to realize that your code base doesn't have to be homogenous, and you can make different trade offs in different parts of the app.

If you have an accounting app for instance, if it crashes every once in a while users will accept that. If it calculates your taxes incorrectly leading to an IRS audit, that is unacceptable and an existential threat to your company.

In that scenario UI could be messy but your tax crunching code has to be the cleanest and best tested code you can write.


Of course the latter can lead into the former, and now you have two problems!


What you seen to be ignoring is that the startups you worked for had the chance to fail due to bad code quality at all. And that was likely due to the fact they they shipped features without worrying about code quality so much.

It's counter intuitive that high code quality is appropriate once a startup has found some kind of product market fit, but is wholly inappropriate until then. It's a very jarring thing to tech people but to people who really understand business it's very obvious or natural.


Switching those cultures is a challenge. The sort of personality that got you your first ten sales doesn’t want to stop coding that way, and if someone doesn’t step in, then that precedent becomes your culture. They never grow up.

One place dealt with Rube Goldberg code forever because most of the people who thought it needed to be fixed left. People conflate “if the code didn’t start that way then we wouldn’t have a product and thus we wouldn’t be having this conversation” with “there’s a good reason for the code to continue being that way”


Is the suggestion that high quality code is slower to write / iterate on? Because that hasn't been my experience.


I think there are some code quality trade offs you get for free. You should always make those, like don't write shitty variable names.

But there are a lot code quality decisions where increasing quality costs more time. (at least in the short run)

Code consistency - When you write one module one way and a another dev writes it another. Do you rewrite one of the modules for consistency?

Doing the "Right" thing - When there is a better solution and a faster solution that is maybe less maintainable. Which solution do you pick?

Corrections - You wrote some code while learning a new library/technology/api and find that you used it poorly. Do you go back and clean this up?

Code Reviews - How nit picky are you? How good is good enough? If a dev writes out a large feature and you don't like the way he did it do you ask him to fix it?

Database Mistakes - as you learn about and build out your app you realize you made the wrong choice with some database modeling, do you fix it or write unnecessarily complex SQL to fix paper over it?

Analyze or fix CSS - A button looks weird, you're not sure why the css is causing it to render funny. Do you do a deep dive finding the root cause or do you just jam some inline css in there?


As you say, some tradeoffs are free, others aren't.

One mistake I made is introducing a complex state management solution early on (NGRX); it had many benefits for code quality and overall FE architecture, but it also introduced additional layers, which required more code here and there for all details.

Entities that we get back are stored separately, then put together through selectors when they're needed on a screen. And all that jazz does take time & energy.

The net result is data consistency across components/screens (which is great), separation of concerns and clean code (cool), but at the code of slower development.

Even though, as I'm writing this, I also think about the alternative. Not having it means having less structure, maybe more issues to fix everywhere due to the lack of consistency, etc. It's not a choice that I can weigh easily, even now. I knew the tech already, used it in production before, and it still wasn't easy after all. Details details ^^


First, great blog post.

> The net result is data consistency across components/screens (which is great)

You probably don't need to be told this, but... how badly was the data really going to drift during a session? If a user notices that part of the UI is stale, they just hit reload, not a big deal. This could be improved later.


Yep, good point. I do see it now. I absolutely didn't back when I started working on that.

I had just delivered & supported an enterprise front-end framework (https://stark.nbb.be/) for which we HAD to help fix issues with state management.

But of course, I just looked at it from the wrong point of view... The point of view of a technical guy, and not the one of a founder.

I'm learning.. ;-)


Back in the day a lot of OO startups burned precious time on taxonomy debates and UML diagrams. There are productive code quality discussions, and ones that don't ultimately matter.


I think one can make the argument that it’s cheaper (in the short term), but I agree that it’s not inherently faster to develop. But experienced devs who can build high quality well modeled software fast aren’t cheap, haha


That depends on the developer, some need to slow down, go back and rewrite, etc. Others write naturally good code without much extra effort. Maybe partly experience?


Well put. I do feel the counter intuitiveness at this point ;p But what you say sounds correct to me.


System guarantees should be a part of your mvp. Code quality may or may not help you get there.

Fwiw - I can relate to the authors mindset after having spent a lifetime working in "enterprise software". As a team lead / lead engineer you're often judged on code quality metrics (did you clear code scans, security scans, code coverage scans, etc.). I'd have gone down the exact same rabbit hole as him.


The constraints just weren't the same. I had a team of 10, could organize the projects however I wanted, and had huge budgets.

It does indeed create a very different way of approaching things. The pressure is simply not the same at all.

I guess that's one of the big lessons for me so far; experience in large enterprises is not comparable to working on a small startup project without funding.

May sound stupid, but it took me time to integrate the idea :)


Thank you for saying this.

So many people here are chiming in with this idea that any time not spent shitting out sales is time wasted for a startup company.

What?

Please don’t take advice like this as dogma and throw the baby out with the bath water. Yes, don’t waste time like OP did, but you’re allowed to use your judgement to at least lay down some of the train tracks before you slam the throttle on the fully loaded train to 100%.

And no, I don’t advocate bike shedding on “code quality” for months before touching anything that matters. I still very much value prototyping ideas to inform MVPs, it’s an amazing workflow when you cut out the friction to get to the meat of an idea! And then by all means, get to the path of least resistance where you can sell it ASAP. But along the way you’re going to encounter friction, and you’re going to see where process is actually needed. LISTEN to these “impulses”, just do it carefully and only when the need is VERY clear.

Do not consciously sabotage all engineering efforts because a large number of people on HN told you to otherwise your startup would fail. Turns out, like everything else in life, that there isn’t some magic formula to success here— that the day is only won by the ones who build high rises on landfill.


> It's funny how different peoples' experiences can be

Yeah it is. I've never seen any startup or project fail due to code quality.

Mind sharing your experience? How many dev months had you guys been writing code before code quality became an issue? And why was it so hard to fix?


I've seen it a number of times. The company would rush to build a prototype, the product would be broken but looked like it's almost ready. Then the cost of engineering would grow and it would become harder to hire people. In some cases, the company had existing customers who were promised new features, so there was no time to fix the underlying issues, and they had to be built on top of. This cycle would repeat.

One might look at these companies and say that they are "successful" because they employ people, and some might even sell in the 7-figure range. But looking closely, each of the employees at the company could be more successful working for another company, where they don't spend their time firefighting, and instead focus on up-leveling their experience.


Having a surfeit of customers clamoring to pay more money for stuff--this doesn't sound like a terrible problem to have as a startup. Sure, spend time to build a reliable core, but gold-plating everything suggests there's been time to burn.


Not quite what I meant. A lot of startups are trying to find market fit and selling customers on a vision that is not yet realized. They will pitch new features and say that they can deliver if there is a contract. However, these features take longer to develop then anticipated, and are rushed on top of bad tech.


This is practically every software business, and is absolutely an illustration of success.


Sounds like a Big ball of Mud. If it solves a real problem then it can be re-invented; by the same people or by someone else. Otherwise it will slowly come to a crawl and eventually be forgotten.


They didn’t fail though. All you’ve described is a standard software startup.

If devs are spending time “up-leveling their experience”, that just indicates that it’s a pretty slow-paced field where that time can be traded. It doesn’t mean anything about the business itself.


If you want an example of company that crumbles under its weight because of code quality, look at Frendster.

Maybe you never heard about it, but it was the leading social network before MySpace then Facebook.

It was unable to scale, and as a consequence suffered bad performances and downtime and eventually all the users moved to more recent SN.

MySpace also had similar problems, their main app was an crappy ColdFusion app that they struggled to update to add features or fix bugs.

Facebook on the other hand, was far better technically and it's probably why they won the social network war.


The version I heard was that Friendster failed to scale not because of low quality code but because the CEO refused to compromise on a feature that was inherently unscalable.

MySpace was sold to News Corporation for millions, it definitely didn't fail as a startup. There's a point where code quality becomes important, I don't think anyone's denying that, but it's after you've got traction and product-market fit.


Here’s a 2011 HN post describing that claim about an unscalable feature in more detail: https://news.ycombinator.com/item?id=2370291

(That was linked from http://highscalability.com/blog/2007/11/13/friendster-lost-l... but I had to fix the link, since it went to apps.ycombinator.com which must have been the HN URL at the time. Maybe dang can update DNS to make those old links redirect? Everything after the host was still correct.)


Code quality has little to do with performance.

Code quality here is more messy code, code that work now but doesn't abstract, ugly variables names like x..

Things that may even make your performance better now but harder/impossible to scale later.


In my experience code quality has a LOT to do with performance. Code changes over time, and bad code generally requires a lot more compromises when those changes happen.


This is a tough balance. I agree that code quality has much less importance when it comes to MVP and startups. The key point differentiator for a good engineer/lead is to be acutely aware of all the compromises and techdebt that being piled upon the product. Understand the effects of each and add them to the backlog so that as soon as an issue crops up from them these tasks from backlog are prioritized. Another important aspect is to continually architect a solution that involves components that can be broken off once we want to improve them or no longer use them.


So, you had customers. Which you eventually lost, but you had them. These guys don’t even have a first customer yet. For them, code quality can wait. For you, you just waited too long to address it.


Yes and no. That we waited 'too long' is only easy to see in hindsight. When growing a company quickly, you generally don't know where the system is going to get stressed until it is already stressed. Then whether or not it is too late has a lot less to do with time (things need to be fixed yesterday) and a lot more to do with the code (how long will it take to fix). You may get lucky and have your weak link be a portion of your system with few dependencies that's easily changed. Then again you might get boned and have the problem be some core system that has dependencies snaking through half your code base (which was the case in my aforementioned startup).


Code quality and performance/correctness are not at all correlated. One could argue an obsession towards code quality can even be detrimental towards true system optimizations.


I suppose that like many things, it's a question of balance. Mine was probably erred to far on the quality side.


I get your points. We did finally get there with the MVP; the initial roadmap was full of envy, and I set the bar way too high regarding build, tooling, ci/cd & testing.

I thought that those would help us further down the road, and I was right, but the issue was more about the time/effort it took me to get there, eventually.

I wouldn't say that code quality doesn't matter, but I certainly should've made more tradeoffs on that front. It was just really hard to judge.

With my background (enterprise frameworks, mostly), quality almost always needed to be top notch, because our deliverables were the basis for many other developments. I guess this created a bias in my way of looking at code quality? :p


And to reply to your question, the first two projects mostly failed because my partners did not believe in the projects enough and weren't ready to invest the required time/energy; maybe it was more envy than profound motivation; idk, cannot speak for them. But I abandoned those too, so they're not the only ones to blame I guess ;-)


The lack of belief and investment is not the root cause but a symptom - you had a limited budget of motivation and belief, and you ran out of it before getting a MVP. If you had "spent" that very limited motivation-time-runway more sparingly on a more-minimal-MVP, perhaps it would have been sufficient.

I.e. I'd suggest looking at the constraints the entirely opposite way around than "weren't ready to invest the required time/energy" - in this equation, you can (and must) change the "requirements" for time/energy, as the time/energy available for the project is your core limitation that you should treat (in the short run) as out of your control, especially as it concerns the time/energy of others before funding. From the classic project management tradeoffs, this is a "limited budget - adjust scope to match" scenario, not "fixed scope - let's see what the budget will be" one.


My point is only that with those first two projects if you guys had stripped it down then you would have gotten feedback much faster.

And if that feedback was negative then you would have been able to move on to the next thing sooner.

And if that feedback had been positive it would have provided a lot of motivation for your co-founders.


> If the code quality on your MVP doesn't physically disgust you, you're probably focusing on code quality too much.

Maybe. But it helps if the person writing the code has a habit of Quality.

That takes many years. When that level is reached, the person basically can't write bad code.

Early on, code Quality takes extra time. Down the road, once it becomes habit, then it is just "how it goes." No extra effort at all.

But design Quality, in my experience, is even more important. This applies to both architecture and UX.

Again, programmers with a great deal of experience will deliver in this arena, as well.

"We are what we repeatedly do. Excellence, then, is not an act, but a habit."


I'm reviving an old abandoned project/product of mine which I failed to sell initially. This is pretty much how I justified rewriting it from scratch. It makes very little business sense, because I already had a finished product which I could try to sell right then and there, however, I just wanted to learn some proper software development. The project was a front-end app built in jQuery (I started it in 2015) and had terrible code quality in general. If I rebuild it, and fail to sell it, at least I will have some base knowledge on how to build a front-end app properly which I could re-use in a future product.


Thanks for sharing that. I can def relate.

I wrote the BAOBAB server[0] as a "dissertation." It was an exercise to "retrain" my ship software Discipline.

Now, two years later, I'm using it in a brand-new application project. It's working amazingly well.

[0] https://riftvalleysoftware.com/work/open-source-projects/#ba...


MVPs work for a subset of startups and it’s important to note that. Selling the mantra around MVP wins praise, but digesting it whole-heartedly is harmful to early founders and generally bad for the world.


Why do you think that is? What have been your experiences where release too early has been harmful to the startup?

I've seen products release to early, and it can sometimes be painful. But releasing too late can be an existential threat to your company.


In mature markets with many organized competitors MVP type products fare poorly and provide little useful information, perhaps even misleading information.

What you need to build is the minimum product that can steal sustainable amounts of market share from competitors, but that product itself won't be an MVP.


This still qualifies as an MVP and is where the confusion arises in my opinion.

The minimally viable solution will differ depending on the product and market.

If you're entering an entirely green market that is just dying for a solution, a ramshackle MVP held together by cardboard and string might be appropriate.

If you're entering a crowded market, you'll be competing on product or price and what's minimally viable will be somewhat different.

We only tend to hear about the former as that's generally where the biggest opportunities exist, so it's more exciting and makes better reading material. However, if you've 'outsourced' your product market fit to the competition and your aim isn't to be first, but the best, your MVP will necessarily be of higher quality.


At that point it’s so outside of what everyone uses MVP for, it’s likely best to just call it something else. Almost everyone who uses MVP uses it in context of lean, and it’s useful to do so.

Building a really refined product that outclasses on features or experience just isn’t the common usage of MVP. It requires dramatically different framing, strategy. Sloppy code and quick iteration don’t make sense.

In reality “viable” does all the work, it’s definition literally means whatever works best, so it’s almost just a poor term to use in the first place as it basically can stretch to mean anything.


I totally agree there exist certain product market fits where an MVP approach doesn't work, or the MVP is so large it probably shouldn't be called an MVP. But I think they are rare.

Also the risks aren't symmetrical. If you take an MVP approach and find out an MVP doesn't work you can always build a bigger badder product, you're out a little bit of time(relatively). If however you build out a big bad product and find out you don't have product market fit. You're much more screwed.

Another reason this advice is useful, is because new founders who are more likely to rely on advice and rules of thumb over their own experience are far less capable of solving an un-mvp-able ideas simply because they'll have far less access to the capital required to build a big bad product.


In this kind of talks we take for granted that the startup is trying to solve an "easy" problem. We don't talk here about the "hard" ones, the ones that aren't only a web UI. Hardware, medical, societal, etc... Ones that need years of research before you even know if it's feasible.

I use air quotes for easy and hard since obviously they are not the words I'm looking for, but I can't find better ones. All(?) problems are difficult to solve in some way.

Anyways, this is almost off-topic, not really fitted for a pragmatic thread such as this one :)


Yeah mvp only applies to startups where product market fit is the biggest risk.

If you have a known market like nuclear fusion and your biggest challenge is going to be how do I scale nuclear fusion, and how do I raise money from the DoD than mvp/lean startup and 99% of the advice on this site aren't applicable.


A huge chunk of startups covered on this site disrupted existing industries and as the web matures MVP becomes less and less useful. The original post here wasn’t a good fit for MVP, and yet we had to come and swat down the proselytizing as it’s so pervasive.

Tesla, Google, and just so many huge companies absolutely aren’t good fits for it. It’s a limiting framework at this point as people seem to have oversubscribed to the philosophy and turned it into religion.


"can steal sustainable amounts of market share from competitors" is one type of "viable"


There's a pretty good interview with the Dropbox CEO in the "How I built this" podcast that illustrates a good example of when taking the time to build a robust product is better than releasing early.

[1] https://www.npr.org/2020/11/06/932199300/dropbox-drew-housto...


In mature, competitive markets - like the ones OP was targeting (enterprise communication) - MVPs don't make sense.

MVPs are good if you're solving a niche problem in a niche industry. But if your competitors are Slack and Zoom, you're going to have a hard time launching with a barebones approach.


Would you consider something like @username mentions as excessive in scope for what would have been Slack's MVP?

(I know bits of their "origin story" but am in no way familiar with their early product or whether that feature was around from the beginning)


Mentions are definitely out of scope for a MVP. It's not really needed until you have a fairly sizable room.


Very interesting question, I have my own take on an answer.

I would say yes, @mentions make a chat product like slack minimally viable. It is a baseline expectation of a modern chat solution to be able to ping others by name.

However, the minimally viable form of the @mention feature is where you stop. Skip all things that are not “the @mentioned user received a notification when I send the message”

If you disagree with me, please explain why. I don’t at all believe that a Slack MVP that is nothing more than a WebRTC chat demo would be a sellable MVP in 2020. MVP and prototyping seems to be very conflated.


Thank so much for writing this. The detail, the hurt, pain, everything. It's super real and the experience is not for the feint of heart.

Please stop coding. Go find a paying customer. Whatever it takes.

Lots of the other comments echo this sentiment, and you already know this in your bones. The problem us engineers face is we tend to hate sales. Whether we're bad at it, hate the experience, or insert X reason... we avoid it like the plague. At least I do. And so we support the organization by being the best damn engineer we can. Features features features. But there are times when that isn't the answer. This is one of those.

It's Monday, the day you work on the SaaS - pick up the phone and make calls.

You're not an engineer - you're a founder.


I'd like to thank everyone who took time to comment and share thoughts/ideas.

All of this feedback is super valuable to me, for many reasons. The first of which being the push in the back to change my approach drastically and obsess on the product much more than on the technical beauty.

I'm not kidding, but this morning I went with an axe through the backlogs and have pushed back so many tasks that I was emotionally attached to. Now, the "MVP MUST" version is planned for the end of this month rather than March.

A change of mentality really makes you see things very differently.

Anyways, it was time for the madness to end.. right? ;-)

Thanks again!


Hi, long time tech startup CTO and CTO freelancer here.

First of all, thanks for sharing your story. I think the real lessons here is that:

- a founder CTO needs to be very strong on product: I never accept offline capabilities or even mobile compatibility for a MVP, this is simply never necessary to get the needed early feedback

- as a tech startup cofounder, your infra should be a docker-compose.yml and that's it, your CI should be a README "ssh, git pull, docker-compose stop, build, up" and it should take max 3-4 hours to set up

- caring about unit tests and the like is useless when you're still iterating fast, automated tests are good once the product is stabilized and you want to kinda "freeze" it or at least stabilize it and introduce some friction in the dev process to prevent regressions (you trade speed for quality)

Sounds to me you spent entire months working on things which did not provide any business value


Agree on all points made here, though I haven’t yet been in the founding position myself.. yet :)

Relevant side note: Docker compose is SUCH a nice tool for this type of work. It is very worth learning, but learning it takes time. Be careful not to confuse “we need to move fast” with “there is no time to learn how to properly use tools”. It’s worth understanding. You will have both initial nimbleness and something that isn’t far off from production ready. To be completely honest, I am still in the active learning phase with both Docker and Compose, but it’s helped keep me organized already.


'CTO freelancer'? How does that work?


Fractional CTO I think


You're right, thanks for the advice!


That was an amazing read! Thanks for sharing your experience.

The obvious feedback is to let go of perfectionism and ship a real mvp. If you're spending 2 years on it, it's not a mvp.

Before jumping on a new idea, I'd suggest to think how you're going to sell it and test the market by talking to people in it.

Getting better at finding cofounders (as in, cofounders who would think about these problems while you build the product) would be good as well. Personally, I gave up on that last one and I'll just fly solo and smaller, but you may be more optimistic.

Also I'd recommend you to pick something smaller and easier to sell. A generic B2B SaaS API to solve a small problem can help you build a passive revenue stream and free you from worrying about money and plan bigger, better, more interesting projects.

Funnily enough, during uni I made an app which was making a decent amount of money in advertising (netting everyday a daily rate of a mid developer contractor rate in London) but didn't have a future.

I decided to start a company doing something bigger and better and failed miserably.

Some contracting, some more working and a few kids later, I'm back at square one building more small passive revenue streams.

Look up Pieter Levels's presentation Bootstrapping Side Projects into Profitable Startups.


> the project needed to be (almost) re-created from scratch

> the build system, Docker/docker-compose, continuous integration, authentication, internationalization, etc

> created a wiki, migrated the code to a monorepo, created/cleaned up the backlog, etc.

> created a story map, devised a roadmap, and clarified the scope of the MVP

> replaced Angular Material by Tailwind, created our own theme, refactored the data model

This is why. A year went by and no product work was done, none of this was necessary. The very first thing that should have been built is a MVP, that main screen that was only tackled 9 months in. Strongly recommend studying “The Lean Startup” and learning how to be stoic about tech. That’s how people deliver working products in three months.


what does it mean to be stoic about tech?


Not jumping on bandwagons and exercising restraint - you don’t need all that shiny stuff to get the job done.


I personally have a very simple takeaway: Never half-ass two (or more) things. Always whole-ass one thing.

I think the OP was not prepared to completely dive in to his startup project which led to distractions, i.e. side business and writing, thus compromising dev time, mental recovery time, and eventually morale.


Bill Gates and Warren Buffet famously stated the key to their successes had been “focus”, i.e. going all-in on one thing.


"I became more and more “aggressive” about reducing the scope and focusing on the essentials; still, I didn’t want to forget about code quality."

After reading all of it, it seems to me that the problem is right there.

Security, maintainability, offline-first, horizontal scaling etc. Should have just thrown these out the door and put every client on their own VM, with local database and automate backups and updates.

You'd get something out the door and could make sales, then re-factor for the next iteration of the app.

You'd be hard-pressed to find any client that wouldn't be sufficiently sustained on their dedicated hardware (or VM).


VM for a mobile app?


Absolutely, highly scalable VMs are available for less than 2€/mo from providers like Hetzner and OVH (less at scale), with an included "global" redundant network.

Does it make sense if your business idea is having thousands of customers on a single VM by using containers?

No, of course not! But it does make sense if each customer is worth more than 2€ per month.


I think this is what's wrong with today's SaaS and web environment. People thing that by going with AWS, creating a complicated auto-scaling infrastructure that supports billions of user is the way to go and the most cost-effective way, but while doing so many forget that using the simpler solution that costs a bit more can actually save time and money.

What's the point of trying to save $1/month per user if you have no users yet and achieving this cost reduction takes one or two more years of development time.


The team i worked with hosted simple solutions on VMs at first. But after a few years, the client requirements and features grew until our biggest problem became maintenance and upgrades.

The sysop costs became higher than our earnings, so we weighted our options of re-building or partner with a larger API-first solution.

Eventually we choose to partner up and in the end, we cut costs to a fraction, while still keeping the customer base and increasing performance.

Which is another point I see constantly, founders desperately want to keep control by not outsourcing when it _should_ be, and by doing that, the costs continue to increase and the already over-worked team can no longer push features, competition gain even more ground, margins fall even more and eventually layoffs and inevitable shut-down.


Good points. It should still be mentioned that moving away from VMs to API-first solution or outsourcing maintenance only happened after the company grew and was successful, not before the MVP was ready.


AWS is rarely cheaper than competitors.

It just offers more for more.


I thought one of the main selling points was the on-demand computing power and per second billing. So instead of having a $5/mo VPS you only pay 30c or whatever your usage was for that month.

I do know that billing can get confusing and in some unfortunate cases people ended up paying 10x or 100x more than they expected.

Maybe my example was bad, but my point was that sometimes it's ok to not go on the most-efficient route and that for an MVP "good enough" is actually the best way to go.


The main reason people choose AWS is orchestration ability and scaling, the cost is usually hidden in "free" tiers until you start to scale and it becomes visible.

Bandwidth being one of the largest issues...

The second is cost complexity..

AWS pricing is also so complex that Amazon provides cost calculators to get an estimate, however, since most services intertwine, it's so easy to miss obvious cost points that business provide cost-savings service for AWS specifically.

The costs have become so complex, that AWS customers even use AWS own ML service to log and do cost analysis.

https://www.concurrencylabs.com/blog/aws-quicksight-cost-opt...


I totally agree with your premise, I just wanted to point out that AWS is rarely as cost effective as a VPS.

If you're spending 30c in lambda, you're probably cheaper than a 5$/mo VPS but I'd argue you'd be covered by heroku (or similar) free tier.

In theory, AWS gives you more tool so you don't have to build / manage software yourself.

In practice, the markup on the tools is significant and you usually pay a premium for devops who know AWS over those who don't.

If you're saving a lot of development time by using AWS tools, it could be worth it, but I haven't seen many companies where that is true.

Maybe it makes more sense in Silicon Valley where tech people are much more expensive.


How does a cloud VM for each user solve the problem of offline, local storage, or make anything simpler?


> ” Between July and September, I worked on different things: the build system, Docker/docker-compose, continuous integration, authentication, internationalization, etc.”

Authentication seems to be the only thing the author should be working on at all for a MVP. And even so, I would personally choose AWS Cognito or something like that.

From reading this, it seems to me that the issue is a mix of harmful obsession code quality and bad priorization of what to work on.

Probably some feature creep too, even with the author claiming they cut all to the basics.


Just finished a MVP idea I had and used Firebase for everything, including auth. Auth took a total of 15 minutes to work into my react SPA. Called it a day and moved on feeling very impressed with Firebase.


I'll reiterate what I said the last time it came up on HN - this is exactly why I use Firebase, and why OP probably should have done the same.

It's literally 15 minutes to configure/integrate, and you're done. You can then move on to building/iterating on actual features that matter to customers.

Until you've proved you're building something that people want to buy, your data layer only needs to do the absolute bare minimum (store some data). It doesn't matter if it's not scaleable, performant, extensible, etc. 99.9% of the risk is that you fail because you're not building the right thing, not that you fail because Firebase wasn't appropriate.

You have a limited number of hours in every day, and they are much better spent building features side-by-side with customers. You won't even know that Firebase is a bottleneck unless/until your platform is successful, and at that point you're in a good position to migrate/rewrite/whatever.

A couple of commenters smugly pointed out that they were contracted to fix Firebase issues later down the track, and that's why they would stay away from Firebase in the first instance.

First up, there's clear survivorship bias there - the fact is these businesses survived and were in a position to hire someone to upgrade their data layer. That's meaningful in and of itself.

Second, don't pay too much attention to people who have never bootstrapped anything from the ground-up. What works in a mature, stable, well-funded organization is not what works in a solo, early-stage startup that's strapped for cash, time and equipment.


Setting up postgres on heroku is similarly quick and straightforward, also comes with a free plan for when you're just starting out, and won't leave you with the headaches you'll almost certainly have later with firebase. Firebase is slower to iterate on, because you have to bake your query patterns into the schema (yes your data still has a schema even if you don't have to define it up front)

Using firebase for auth and/object storage makes sense. But I don't understand why anybody would choose to use the database(s) except for a few niches where realtime is critically important and query flexibility / data integrity aren't.


1) Firebase storage has the advantage of one-click integration with auth (Google Auth, Sign in with Apple, etc). Probably not difficult to achieve with Postgres on Heroku, but why waste a couple of hours on something when I don't need to?

2) My golden rule is to avoid anything that doesn't get you closer to a customer in the next 14-28 days. For some use cases, Postgres on Heroku might help you do that. For me (see next point), it's just adding another platform/service for no reason. That will only slow me down.

3) I disagree that "Firebase is slower to iterate because the schema is implicit" (at least, as a hard-and-fast rule). It depends on how complex the schema is. You iterate on implicit schemas by rewriting code, and you iterate on explicit schemas by rewriting code and the schema itself. This is faster for complex data models with strong integrity requirements, but for basic data models (think mobile game leaderboards, etc) it's just unnecessary.

That's not to say that any of this is a huge amount of extra work. I'm sure a lot of people are reading this and thinking "Postgres will just take an afternoon to hook up, why not?".

The reason is that spending that afternoon with a user is infinitely more valuable than spending it hooking up Postgres.

You have to be ruthlessly focused on what moves you forward, which at an early stage is simple - features, customers, users. On any given day, there are literally hundreds of things you could do that "will just take an afternoon". If you allow them to distract you, you'll probably end up like OP - 2 years in with a well-architected system that doesn't have any customers.


> You iterate on implicit schemas by rewriting code, and you iterate on explicit schemas by rewriting code and the schema itself.

You've missed a step: you also have to migrate the data. In my experience this is by far the slowest / most complex step. And it's much easier with SQL where you can `UPDATE WHERE` and `INSERT FROM SELECT`.

If you want a flexible schema then Postgres has JSONB which is just as flexible and usually performs better than firebase anyway. Plus you can use all the querying power of Postgres, JOINs, etc just like typed columns.

> For basic data models (think mobile game leaderboards, etc) it's just unnecessary.

If you're completely sure that you won't need powerful querying, joins, etc for any of the data you'll be storing then sure. Otherwise you lose all that time and more the first time you need a JOIN or a query that firebase can't do. And you pay that cost every time you need to implement such a feature (or you end up storing that data in Postgres or similar and you end up with two databases, which is much more painful than having two platforms).


> You've missed a step: you also have to migrate the data. In my experience this is by far the slowest / most complex step. And it's much easier with SQL where you can `UPDATE WHERE` and `INSERT FROM SELECT`.

I didn't miss a step, because until you have paying customers (or at least, some other indication that you have a product that people want), there's zero data to migrate. If someone isn't paying, just blow away their data. If they are paying? Congratulations! You have a product that might be worth migrating to Postgres.

> If you're completely sure that you won't need powerful querying, joins, etc for any of the data you'll be storing then sure. Otherwise you lose all that time and more the first time you need a JOIN or a query that firebase can't do. And you pay that cost every time you need to implement such a feature (or you end up storing that data in Postgres or similar and you end up with two databases, which is much more painful than having two platforms).

I think you're missing the central point, which is that until you have paying customers, you don't know whether you're even building the right thing. There's usually no way of saying "I'm sure we will need powerful querying" because you have zero clue whether there's any demand whatsoever for the idea you have in your head. In fact, 90%+ of the time, there isn't, which is why we fail so often at it (including OP).

Everything you do in the early stages must be geared towards proving whether or not you're actually building something people want, not getting sidetracked by non-core technical issues. That doesn't mean I think you should never use Postgres straight up. Sometimes an RDBMS is so integral to your idea that it's actually easier to use Postgres than a NoSQL DB (like a GIS application or some such). But more often than not, it's not, and you need to be ruthlessly honest with yourself about what you actually need to build to validate your concept.


Yes, its interesting from that list of things he did for 2 months one cannot discern what his project was!


Spending time reading horror stories on HN can lead to a form of paralysis.

While it’s true bad decisions can be made at any level and anytime early on it is much more important to get something (anything) up and running - even if you scrap it later.


First, thank you for writing this, It's really cool to see others entrepreneurs sharing their experience, I believe this post here will help you a lot, I agree with many opinions here, the main thing would be the MVP opinion, you are focusing too much on secondary features(like PDF export) and could not finish the primary feature I guess (if yes you should launch it).

I am a developer and entrepreneur, I have sold a SAAS product 3 years ago and will sold my other SAAS this year(much bigger), I built entirely my SAAS products.

As almost everybody here said you are being too perfectionist, I would suggest you focus on the main feature, the feature that was mentioned when you had the interest of that first customers, make sure this features works well and launch it, then improve it.

After you have your first 2 or 3 clients you will see your motivation go higher, all the team will be motivated, also, these customers will ask for critical things that you forgot, but when they suggest things you have to be critical and think if the feature will benefit multiple customers, not just the guy who asked, doing this in 3 months you gonna have a good product.

I really would suggest you stop writing tests in this moment, takes time and probably in the future the code will change, which will require 2x work, but if you think you are fast doing this is okay.

Another thing I would suggest is just comment features that are not finished and you think are not part of the primary feature, don't try to finish those things, just comment it out, if some customer asks for this in future you finish it.

My approach is a bit radical, but I learned this way, customers will ask for stuff that matters at some point, if they think the primary feature is good enough, and for you to know if is good enough, you need to launch it, just make sure it works ;).


Dumb question: how does one sell a SaaS in practice?

Hypothetical scenario: solo engineer develops bitcoin trading platform. Wants to sell it. Then what? What steps does the engineer/founder take to sell this?


Sites like these: https://feinternational.com/, they guide you through the process, but you have to reach certain MRR(2k minimum I think), the price of the SAAS business is calculated using a multiple of the MRR(20x~48x).


While I enjoyed the read, I was perplexed by the author writing a long post about how busy and stressed he is and then casually mentioning that he also started a new book and inviting us to sign up for his newsletter right at the end.

Stop letting all your plan Bs distract from your plan A mate.


It's just the usual end of post that I use. I've been blogging for quite some time already; more as a relaxing activity than anything; I do like sharing what I learn about.

I do try to monetize what I write, but it won't make me rich anyways ^^.

The book doesn't distract me from the startup project; it's just another project, to which I dedicate two evenings a week and a few hours during the week-end.

It's important to me for other reasons; mostly the will to share what I do know about, and the need to think about something else.

I couldn't work on the startup project also during those evenings/week-ends. I don't want to be in burnout state just because I was able to pour in more hours each week.

Question of equilibrium. Maybe I would've done that ten years ago, but not today.


Regarding the stress, I manage to isolate things in my life well enough to keep going; otherwise I'd already be crawling in my bed crying ;-)

I'm still employed, have no worries about my capacity to find a new job should everything else fail, and my family hasn't been hurt too badly by Covid so far. So I can't complain.

I'm stressed about the project and where I'm going, but not about life in general. I still have tons of energy, motivation, will, and projects :)


I think the guy has just low technical skills. He writes that he managed a team (that means other had to work), that he prefers team work (usually it means that someone else has to do the work).

Then he started with the classic: previous code is bad so I rewrite it from scratch.

Then came to a conclusion that his own code is bad and shouls be rewritten.

And only then author had another conclusion: it was unlcear how the product should work. So they hired an UX person. Then we learned that moving buttons around requires back end changes (wtf?)...

And then we learned that the author still didnt know how to make the main feature of the product.

My guess: if they hired another programmer the other person would code it in few days.

Author looks like a manager / team player - someone who never did anything on their own.

Also I really loved the part about previous code being bad (classic) and rewriting everythig just to say that own code is bad too and didnt move the project at all. I wonder what part of the solution even works. Probably nothing apart from login window.

Also the part where the author wrote that after coming back to previous work they had to do lots of frantic work... sounds like normal work. But author wasnt a manager anymore so the work had to be made: hence it was so painful. No more possibility to delegate the problem and do nothing all day. And real deadlines.


Thanks for sharing!

I also wonder whether the OP should have made clear decision (and expectation) between bootstraping vs startup, because I think they require different mentality, operation style and even market. With startup he and his cofounders could focus on applying incubator and/or angel investors early on. They would get some feedback on their ideas. They could even get a little funding to hire a designer or contractor to help build the UI (which appears to be the big drag). In this case you are trading ownership to additional support systems. If you do bootstrapping, then you'd need to prepare for the longer timeframe, and financial burden. Maybe still keep the original full-time job and working par-time on the side project.


> I feel almost ashamed when I think about how little we have to show for it. Maybe it’s normal, maybe it isn’t.

I had the same feeling, and a very similar story, when I failed for the first time. The main problem here is the process (outcome of a 10yo developer mindset in an established company): too much focus on things that don't matter at that stage.

Launching a MVP, and more in general starting a startup, is all about risk mitigation and more importantly simplicity. I saw too much commitment in building and not enough on validating (especially for value that is the first big risk to mitigate).


This is a hard read for me, because I can sense the vision and determination behind the last two years, but there has been some really poor decision making as well.

Here are some things that come to mind reading this:

* Most people are not cut out for startups, and I would include some of the people you've recruited along the way, by your description. It's hard enough to get a startup off the ground without having semi-motivated partners. I think you do need a partner or two, but I wouldn't say you have been brutally honest about what exactly you need to be successful yet.

* This is partly a Europe / West coast US thing, but one thing Silicon Valley does well is create a solid revolving door for entrepreneur types -- in general, if you want to go try a startup, go for it -- even if you fail, ideally, you will learn some new skills not on the big company's dime, and come back more seasoned and ready for another round with the big co. I know this is harder to pull off culturally in Europe, but I think some of the paths toward successfully pulling this off involve selling your experience harder, (along with getting broader experience). If you're depressed with a year of failure, you will feel like you're slinking back. By comparison, I would hold out examples of one of the moviepass founders who bemusedly reports in interviews he's in demand for a follow-on startup, despite launching a massive massive crash and burn startup. And it's right that he's in demand; he got a startup launched with huge scale, brilliant free press and marketing, and briefly shook up an industry. I bet he'll be back. Which leads me to point three.

* You have picked terrible, terrible markets. Tiny markets. Markets which require public tenders. In tiny countries. Markets where purchase decisions are made nearly infinitely far from those who require the benefits of the purchases. Seriously, these were terrible decisions. You compounded them by not getting some initial sales done first. I imagine that as you read this, right now you have roughly ten reasons why your path made sense at the time. And, I bet it did make sense at the time. But it was the wrong path. If you want US west coast philosophy, I can say that some of the best incubators on the west coast consider maybe their number one core skill market testing -- they work very, very hard at testing out if a product will sell before they write a single line of code for it. To the point that places like Pioneer Square labs are actually turning their product-fit test facilities into SAAS model products in their own right. If you prefer value investing, Buffet's aphorism is helpful here: it's better to be mediocre at a great business than it is to be great at a mediocre business. You could be a brilliant, brilliant coder and a brilliant, brilliant product person, but it just won't matter if you are selling something nobody wants to people with no money.

At any rate, my personal advice to you is to listen to your urge to be an entrepreneur, and set your sights both much higher and also much more narrow. Pick a giant market that you care about, pick a niche you can do some damage in, get some test sales in the door, and I think you'll find you feel a lot more successful, and it will paradoxically be less emotional work. If you can get a little success that can help aim your company as you iterate.

Also, it's hard work to write your retrospective, thanks for doing it -- I hope you find some success, and can update so your readers get a feel for what to do on their own paths.

In summary, product-market fit is the only thing, and you should get it before you do anything else. If you sell crack cocaine, the world will beat a path to your door.

Crack cocaine I've seen this year come across my VC fund's desk:

* paramutual insurance (merchants want it, customers want it, it's cheap to provide).

* product authentication which works from factory to distribution to retail to end customer (manufacturers really really want and need this and can convince customers it's in their best interests)

* defi lending (people want to borrow on their crypto, and want 0 friction to do so)

* Instant vendor network credit scoring as the real value add for supply chain management - large cos want insight into their vendor world and early warning of problems, small vendors desperately want cheap financing

* high margin trading volatility of all sorts - people love to gamble

* home insurance bought by app -- nobody wants an insurance agent, or spammy calls.

Most of these could have their own niche spins, but the point I hope to make is that there is a wide world out there of problems, each of the above are giant markets, with plenty of room to be 'mediocre' and still have happy customers, and generate huge wealth.

Best of luck in 2021!


Thank you I needed to read this, very well put and wonderful advice!

Regarding your first point: I am still not sure if I'm cut out for startups / the hustle. But I've made some of these mistakes and I'm glad I did. Because that seems to be the only way I have gained some insight into what kind of a person I am.

Now I'm on the lookout for opportunities and people who compliment my strengths / weaknesses.


Incredibly insightful. Can you share some of the startups who are working on product authentication and instant vendor network credit scoring? I had somewhat adjacent ideas but haven't quite clicked with the market I am targeting.


Having gone through a startup accelerator and failed a startup after 2 year struggle i can only attest to these gems of wisdom. All true what you say.


I found this very insightful, thanks for sharing.


Do u do seed ?

We have something innovative which ticks these boxes

  - trading volatility  
  - really scalable   
  - instant craving for more


Always happy to hear a pitch :) My email is in my profile.


What I found curious is the equation

money not gained = money lost

To me that sounds like the perfect mentality for a burnout.

I would think that you used your time (i.e. opportunity) not for monetary but personal gains (i.e. experience).

Ideally you would have turned that experience into money again, but just because that didn't happen doesn't mean you didn't gain anything.


It's not all black and white though. I did learn a lot (especially about myself in recent months), but this all came with a very real cost.

If I did consultancy or went back working full time as an employee, I'd have a ton more money in the bank. It does impact my family. It is money lost, no matter how you decide to look at it :)

I'm not saying that I regret doing what I did. What I regret (but am not going to cry all day about) is the bad decisions that I've made during that part of the journey.


Time is money, no double counting: either you can say you lost the time, or you can say you lost the money. Claiming you lost both would not be true in this case.


Extrapolating a bit. What seems to be missing from this story are any significant milestones. Humans need miletones. Perhaps more than projects do.

Sure, you can psych yourself up every morning about how excited you are, about the greatness of the destination, and so on. But long timelines without significant feedback will catch up to you, your team, your investors, to everyone involved.

When things stagger on and on and on, you lose focus, you lose confidence, and in that context bad decisions increase; as does friction between the team.

Lean doesn't simply build products. Lean also addresses the human side.


That's very true. What also helps is not only to have milestones but also have people (preferably prospective customers, but friends are great as well) you can show your milestone results; this often serves as some kind of reality check.


How much of that 2000 hour was spent on the core experience, the meetings screen? How much of the work that wasn’t spent on the meetings screen had to be reworked due to changes with the meeting screen? How many times has the meetings screen been shown to prospective customers?


On my end, probably 50%. I've logged ~200 hours on that screen and the surrounding components.

But I get your point; that should've been almost the only focus. I did was time with tech, build, code quality, release automation, ci, code formatting, git workflows, project organization, lazy loading, and whatnot. It all adds up and eats time that I didn't realize I didn't have to spend in the first place.


Thanks for sharing - it takes a lot to share these sort of personal experiences. I've definitely been there, too.

Aside from all the good and valid comments about reducing scope and shipping an MVP, I'd like to raise another point which may be controversial (or even wrong), but still worth raising:

Would it have been different if you had used Rails? A few of the problems you mention (rich text editing, validation, and to some extend, pdf exports) are very easily solved in Rails. Take rich text editing: It's literally a couple minutes to use ActionText. Or validations / forms, there's really not much work to do. PDF exports are also not too hard via wicked_pdf [1] if you're okay with fixing some formatting quirks later on.

I've seen both worlds by writing tons of JS / React code myself, and at that time (2016-2018) those problems were almost an order of magnitude more time-costly to implement in SPAs. I remember react-router.. not great memories.

Of course, all the points reducing MVP scope still hold, but.. if you could have had all those features (nearly) for free, would you be at another stage now? Who knows.

[1] https://github.com/mileszs/wicked_pdf


Reading this I realized the same mistake that I made.

It's because we focus on a product that

1. need lot of front-end works

2. target a user-base that need a lot of onboarding

I have a side project that I worked on in 10 years and still doing nothing...Its scope is too big and because It requires some kind of front-end works, which isn't my strong suite, it becomes a constant battle to say what should I do, how should I make UI/UX intuitive.

Then after I sitting down after 10 years(and still have nothing to show), I leanrn about 1) and 2).

Then I think in order for me to move forward when I have a day job, I have to focus on something that require zero or very little front-end works and can easily self onboarding.

I did that idea. And something I think I can finished in 2 weeks ended up taking me 3 months and still not 100% polished but at least I have finally launch it and have my first paid customers

So my advice to anyone is to find something that requires minimal front-end works can can easily on-board new users.

---

the service is https://hanami.run an email forwarding service if you are curious


Heh, I totally did the restaurant platform and just like him it failed because all of the customers run razor margin business and some of them are still uncomfortable with the internet.

But unlike him, I noticed the downward trends and decided to cut the losses even though I had managed to hit the break even line.

I thought it was a pretty good decision on my part.


Given that one of your partners is a "Lean Coach" did you consider to first sell a no-code service. Perhaps one focused on helping/coaching/training companies manage remote meetings effectively.

This service would be admittedly a tough sell, and hard to scale since it would depend on your partner attending many meetings and providing feedback for each one.

But even if you get a few customers, then you have some cashflow and provide a sales channel to slowly start onboarding them on full-code product as you build more features. It will also allow you to quickly identify the most useful features to prioritise, and some features you might have not even thought about.

Lastly, it would give you much more credibility when trying to raise seed funding if you are able to show you sold the no-code version of the service.


Yes, one option currently on the table is to bootstrap ourselves using a service model at first; either around the core business (probably better I imagine), or through IT services.

Another option would be to monetize the existing version that my partner created and is actually using with multiple clients already (made using FileMaker)

Another is to try and avoid funding for one more year, using more of our personal savings to continue moving forward (albeit with a different approach).

We still have to decide.. It's a pretty tough decision, and not straightforward at all :)


This doesn't help TFA, but building a successful business is usually really difficult (based on what has been seen and written about other successful businesses). Also, many entrepreneurs fail multiple times before succeeding at a business.

Indeed, sometimes luck is against you. COVID was probably not on most people's risk models, so who would know it was a bad time to start most businesses?

And while sunk cost fallacy is a real problem, I suspect that some terminations with that excuse might have been successes if pursued further. But having a family and children is a significant priority conflict with being an entrepreneur, so I certainly don't judge the TFA. But likewise I don't think I would use the sunk cost expression.


I second your opinion about having a family to support will conflict with being an entrepreneur.

It reminds me about the reason #9 not to start a company: http://www.paulgraham.com/notnot.html

> I wouldn't advise anyone with a family to start a startup. I'm not saying it's a bad idea, just that I don't want to take responsibility for advising it. I'm willing to take responsibility for telling 22 year olds to start startups. So what if they fail? They'll learn a lot, and that job at Microsoft will still be waiting for them if they need it. But I'm not prepared to cross moms.

> What you can do, if you have a family and want to start a startup, is start a consulting business you can then gradually turn into a product business. Empirically the chances of pulling that off seem very small. You're never going to produce Google this way. But at least you'll never be without an income.

> Another way to decrease the risk is to join an existing startup instead of starting your own. Being one of the first employees of a startup is a lot like being a founder, in both the good ways and the bad. You'll be roughly 1/n^2 founder, where n is your employee number.

> As with the question of cofounders, the real lesson here is to start startups when you're young.


Thank you so much for sharing this.

My first thoughts were that you dove into what you could control. Those aspects of the product related to non-functional requirements. However, it’s really the functional requirements that primarily count for a customer.

It’s a feature of our times that nearly all programmer attention is paid to technologies and plumbing. What’s left, how to determine “what” should be produced and how to model that into code, without regard to plumbing, persistence, user-interface/s or interaction with other systems, seems long forgotten.


I think the main lesson here is that an MVP has to be small enough to be completed in a reasonable time. Even if it means boiling the product down to one single thing. Everything else can wait.


Clearly! Haha ;-)


It's safer to use relational db for all business applications since transactions integrity is required most of the time. To reduce complexity, check out:

https://github.com/shujutech/StORMi http://shujutech.mywire.org/corporation?goto=ormj


> but the people we discussed with weren’t interested at the time; they were scared of traceability and preferred to be able to avoid taxes (no kidding :p).

I'm a project manager in construction, and I still have to make my quotes in excel or word because of this. Don't know if this is a typical belgian thing, but it's pretty ridiculous.


My only take-away from this article is also something I deeply believe in: Use boring technology(1) if you're doing it for business.

(1) http://boringtechnology.club/


I always find it amusing that PostgreSQL is classified as "boring tech".

I'm using it every day, and I'm always amazed by how wonderful this piece of software is. PgSQL help me doing thinks in seconds that would take days do to in Mongo.


When building an MVP stop flouncing around with your professional software development. Build the damn thing and get it launched. Every singe dollar you waste on CICD Docker and testing sends you closer to the clock running out and failure.


Indeed. But as a newbie, you first need to start feeling that the clock is really ticking. And fast.

I think that during the first year, I just had no pressure at all. I worked very seriously, but didn't feel external pressure. I had just put enough money aside, I was glad to finally work on my own terms, etc.

And thus I thought it was all okay, and that our pace was normal, given the time constraints that we had.

Now I see clearly how much of a fool I was.. ;-)


OP, thanks for sharing your article.

On the balance, you aren't doing anything wrong. The only real takeaway is entrepreneurship is hard. VERY HARD.

You will make plenty of mistakes. Technical mistakes. Business mistakes. Mistakes that cost years, maybe even decades. Mistakes that will cost you thousands (hopefully not millions).

Don't obsess about "we should have done this" or "I should have done that." You'll beat yourself up unnecessarily.

If you want to do entrepreneurship, keep at it. Find problems. And fix them fast.

If you don't have the bankroll to do it (or just fall out of love), then you can quit too. That's ok.


Thanks!

Right, it is hard. But I like challenges; so I'll keep trying =)

I don't like dwelling on the past too much, but I find it incredibly useful to look back every once in a while, and take a good hard look at what I accomplished.

There are different ways to look at things. I've quit a well paying job, but managed to keep the same quality of life (even improved in some aspects, independently of Covid-madness), I launched a company, had new and interesting experiences, met cool new people, published a book, etc.

We can tell as many stories as we like in life. Ain't that fun? :p


Medium hellscape. They now require an account to read.


Open a private window and read it in there.


My criticism is that we've gone from an open Internet to one where every silo wants us to log in.

I hate this system. Medium doesn't write any of these articles and they think their value add or marketplace or whatever it is that they've built is in exchanging content for personal information.

I'm sick of post-2006 Internet and I want things to go back as they were.


That’s a great story and I can really feel his pain.


It hits home with me, and the TL;DR is: Don't bother setting up "proper" DevOps (but you still need it, just to get going), Don't bother building for scale, Don't bother proper code lifecycle... Until you have some traction. Focus on your MVP. Your truly scrappy MVP.

Applicable most (only?) when there's only 1-2 tech guy. More than that, you need some structure (communication issues).

Technical debt? Yes. Server will crash with angry customers? Definitely. Will never experience those problems because you product will fail anyway? Most likely.

Also, refrain yourself from using that latest JS framework. Use what you know like the back of your hand.


Just to expand on this:

> Don't bother setting up "proper" DevOps (but you still need it, just to get going)

Correct, you can use a Makefile or make.sh for years, more to remind you of the build process rather than something that needs to be continuously run, in a startup. Time waiting for a build process is time not adding user features.

> Don't bother building for scale

Correct, since finding the true requirements for scale requires having many users, and the unicorns that you admire had multiple rounds of scale-out rewrites.

(You can add Google Analytics to your pages to see their usage. I've seen some companies do this as a lightweight interim APM before. Pages that nobody uses aren't a bottleneck.)

My current SaaS app has a built-in APM using pre-auth, post-auth and post-load hooks that I added after version 2.0. I learned the auth was slow, but the page generation was fine, so I fixed the auth routine.

> Don't bother proper code lifecycle

Correct, since you don't know what the final version will even look like. The exception is if you've done similar projects with a similar expected load, then you can skip a lot of the steps that didn't work before.

My goal is to write code to Open Source standards, but I realize that rework will be needed later for scale, etc.


If I may, it seems like you’re doing too many things at once, and yes the context switch is a killer.


Anyone can explain why using a NoSQL database was a limitation? He says that they had to switch to a RDBMS for offline usage, but why couldn't a NoSQL dataset be saved locally for offline usage?


We designed our documents just like separate tables and didn't want to denormalize the data model. This was a mistake and known anti-pattern for NoSQL, because we just can't easily join different documents together. It caused issues with updates (e.g., If I change the state of a meeting document that is linked to a number of other documents, then I need to fetch/update those separately) and all without a transaction, because CouchDB only ensures atomicity at the document level (& with bulk ops). It's far from intuitive, prone to error, and complex.

Certainly, having a classic RDBMS with an powerful ORM makes such operation much easier in practice, and safer as well.

I'm not bashing on NoSQL; we just use it badly and suffer from all the drawbacks while getting none of the benefits (since our schema is strict after all..).

CouchDB was appealing for offline-first because it exposes a RESTful API & means to replicate entire databases. So we had in mind to use PouchDB on the client-side; store a copy of the data locally while online, saving changes locally and synchronizing when going back online.

So it allows for a true offline-first approach, not a middle ground where you keep access to the subset of the data that you already got while browsing the app.

But it doesn't mean that it's easy, or that it ain't possible to do the same with a classic RDBMS, or a mix of tech...


Thanks for an honest, forthright chronicle. I wish you luck, going forward.

For myself, after leaving the corporation that I had been at for 27 years, I rapidly discovered that no one wants to work with older folks; regardless of our skill level, so I went on an odyssey of self-actualization that played out a lot like what the OP described.

I hadn’t sunk as much cost, and was realistic that I’d need to try out a lot of stuff before hitting my stride. I think that helps with the morale/motivation stuff.

I also consulted a couple of cranky old men, with cynical views, and quite a few scars.

It was humbling, but their clear-eyed judgment of my [scant] chances helped me to make some massive course changes, early on.

I spent about seven months, a couple of years ago, developing a powerful, high-quality backend server that was never really meant to be used[0]. It was more like a “dissertation.” I needed to develop a Discipline that could carry me forward.

In my experience, non-technical, “soft” skills, like Discipline, Integrity, Reliability, and Honesty have been important; Even if no one else appreciates them.

I need to keep a personal Discipline. For example, I get up every day, quite early, even though I don’t need to, and walk a couple of miles, first thing. It helps me to clear my head, and plan out the day’s work. I also never work in sweats (except if I need to do a bit of work, right after my walk). I think that I need the structure imposed by dressing for work.

I am now partnering with a couple of other folks, in a non-profit endeavor. It is working quite well, but we also have a very flexible plan. That’s mostly because of me. I insisted on a “pave the bare spots” approach[1]. Our project is morphing as we develop it, and I couldn’t be more thrilled. As an added bonus, it uses that backend that I developed a couple of years ago[0]. It has also allowed me to learn a great deal of stuff, and I love to learn.

> we went through the user stories, completed those, created a story map, devised a roadmap, and clarified the scope of the MVP.

I’ve become less-than-enamored of this approach. I know that makes me apostate, but I haven’t seen it bear fruit (besides a couple of withered crabapples), in my personal experience.

What has worked for me, is “paving the bare spots.”[1]. I start with a vague, general project concept, then work on creating usable, high-quality partial prototypes, quite quickly, with built-in flex points. It has worked a charm. It is especially valuable in getting useful stakeholder involvement. It helps them to feel good about the project, incubates their sense of “ownership” (and commitment), and we create stuff that is actually useful to the end user, as opposed to “meeting specification.”

Also, the very old practice of “constant beta” has paid dividends. This means no development or alpha release stages. The product is always in “beta-quality” stage, even if only partially done. The first release is “beta,” not “alpha.” I never say “I’ll fix that later.” If I encounter a bug while developing, I stop forward movement, until the bug is fixed. I may say “I’ll implement that later,” but I don’t leave known bugs behind me, and I’m constantly testing.

Ultra-high Quality is important to me. I write highly-structured, heavily-documented code, with thorough (seldom automated, at first) testing, and am very hard on myself.

A significant benefit of this approach, is that we have very solid product to show in that important “shopping around” phase of things, and that phase can start quite early. If we want a potential investor to look at the product, we simply loop them into the TestFlight group. No chaperone necessary, and no sacrifice to The Demo Gods. In fact, any feedback or bugs found are appreciated and integrated into the project (or we develop talking points to address the issue). An important part of this, is that the “prototype” code is actually ship code. It is the product, not a “sizzle reel,” so this means that actual project progress is demonstrated; not some vague, hand-wavy “this won’t take long to realize as ship code” promises.

The jury is still out on where this is all going, but I’m extremely happy with the integrity of my work.

[0] https://riftvalleysoftware.com/work/open-source-projects/#ba...

[1] https://littlegreenviper.com/miscellany/the-road-most-travel...




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: