
If it's a nice problem to have, don't solve it now - davnicwil
https://davnicwil.com/if-its-a-nice-problem-to-have-dont-solve-it-now
======
rigel_kentaurus
This can also be summarized as "Early on, don't be afraid of doing things that
don't scale".

In this particular example, my "reset password" functionality could be sending
me an email, and I have to reset the password manually and email you a
temporary one that you can use. Bad solution? Yes. Doesn't scale? Of course.
But if you have 5 customers it's not a big deal and you can use your time on
something else.

The key here is to have good people in the team. A decent Senior Engineer /
Architect would know that 'Reset password' will be needed. That is why a very
technically solid person is gold in the first round, because they can design
the signup in such a way that it's prepared for future requirements. They of
course would also know that you can't store in plain text, that it should be
hashed, that you might have to use a vault, that you need to randomize the
hash, and that in the future limit access to the "user" table and never ever
expose it through an endpoint where a user can reach it, as well as protecting
against XSS and SQL injections.

Which of the list above goes off the list? There is a balance there in getting
the right solution without scope creep, but also not implementing something so
silly that it's going to get you into trouble later. The genius of a competent
person is being able to tell what needs to be solved now vs. later

~~~
solatic
> That is why a very technically solid person is gold in the first round,
> because they can design the signup in such a way that it's prepared for
> future requirements. They of course would also know that you can't store in
> plain text, that it should be hashed, that you might have to use a vault,
> that you need to randomize the hash, and that in the future limit access to
> the "user" table and never ever expose it through an endpoint where a user
> can reach it, as well as protecting against XSS and SQL injections.

Wrong. The correct technical decision is to bundle in a library that solves
this for you - login with Google, or Facebook, or GitHub, or OIDC, pick one
according to the context. Get password reset, MFA, password security, etc. for
free.

Why reinvent the wheel, poorly?

~~~
MaysonL
Assuming that Google or Facebook or Github has implemented a library
correctly, and that it will remain available as long as you want your app to
function is dangerous.

~~~
Dudenoso
As opposed to assuming that you'll implement it correctly when Google or
Facebook or github haven't?

~~~
yjftsjthsd-h
Yes, because what's good for them is not necessarily what's good for you.

------
frandroid
The problem with issues like this is that this is patch development. If you
don't look a couple steps ahead and at least think through your "nice to have"
problems, you might end up getting the architecture wrong. The password reset
problem might drive you to find an authentication library instead of rolling
your own. Suddenly, your "nice to have" problem is fixed before you get to it,
because you decided to look at the larger picture instead of just rushing to
just rely on an email and password column in your MVP. That way when you demo
your app to an investor or early beta users, you won't be stuck saying "oh,
there's no password reset, just create another one".

~~~
dakiol
I'm curious, what's the right alternative to having an email and password
columns in a "customers" table?

~~~
twiss
In addition to the sibling answer of "use a framework"; if you simply stick
passwords in a database, and the database gets stolen, you've now leaked your
users' passwords. So you should hash the passwords, and they should be salted,
so now you need a `salt` column. Most people use too cheap a hash function, so
this is an additional argument for using a library / framework.

~~~
dakiol
Umm, but using bcrypt to hash the passwords is just a couple of lines of code
(at least in Go); I'm wondering if I'm doing things wrong by not using a
dedicated framework.

~~~
twiss
No, that's fine :) It wasn't clear to me from your original comment whether
you were hashing passwords, apologies.

------
superfamicom
As a person who has worked at many startup, I get it, "shipping" features is
important.

As an engineer working at many startups, this is a sad and painful reality of
working under product driven ideas and "first to market" type things-
basically anything that doesn't (usually) involve life or death, or federal
regulation is rushed out the door when it can be.

As a user, I absolutely 100% hate this mentality. You skip features you don't
consider necessary, do things in ways that make them difficult to return to
later and throw it in the "technical debt" pile.

~~~
ysavir
I think the "ship asap" is necessary for brand new startups. If you can't
generate the user growth necessary to secure the next round of funding you'll
be out of business, and that time spent writing the ideal code was not only a
waste of time, but also a potential cause to the slow user growth. In its
first year or so, until it receives enough funding to stabilize, it makes
sense for a startup to give more weight to the short term than the medium
term.

But once stabilized, and there's no immediate danger of running out of runway,
things shift, and the medium and long terms become much more significant. But
many startups fail to realize this; they've become too accustomed to the fast-
paced, ship-asap mentality. Breaking from it seems to them a decline in
productivity, where it's actually just a shift in priorities. There are a lot
of contributing factors to this oversights, and they can vary from company to
company, but it's continuing to prioritize the short-term is a dangerous act
that usually serves neither the end user nor the business.

~~~
afarrell
> ideal code

One problem in these discussions is that people quickly start using absolutist
language, which makes it hard to find _balance_.

~~~
ysavir
Balance also is not quite the correct thing to strive for.

The proper course of action is to work with the leadership to figure out when
the expected critical points are for the business. This includes fund raising,
IPOs, acquisition, or any other time when the company receives a valuation.
The goal, for both the business and the dev team, is to make sure that the
company has the best possible value at those exact points. You don't want to
peek too early or peek too late. The proper course of action then is to
prioritize things in accordance with how they impact those points in time. If
one's coming up soon, prioritize the short term almost exclusively. If it's
years out, plan ahead as a marathon, not a sprint.

~~~
afarrell
Know the enemy, but also know thyself.

For example, it would be a bad idea for me to say "I am not going to write any
automated tests" for a 3-week MVP. That decision would lead to me producing
nothing.

------
danShumway
Just to push back a tiny bit on this, sometimes nice problems can turn into
nasty problems very quickly.

"My customer data isn't backed up", is a nice problem to have when you're just
launching a new service and don't have any customers. But it's still a problem
you'd probably like to solve relatively early. There won't be a moment where
missing backups are an immediate problem but also still easily solvable;
they're either a future problem or you're unavoidably about to lose a large
number of your customers.

As a less on-the-nose example, sometimes when I'm building software, I can
anticipate that something will be a problem two or three months from now. In
those cases, I have a decision to make. If the code is disposable, I can
ignore the problem and solve it later. But if I'm working on core
architecture, spending an extra 2-3 days to solve the problem now can save me
3 weeks of refactoring in the future.

Many businesses start agile and become slow and cumbersome over time precisely
because of this reason. They can't keep up the pace they started at because
the technical debt, compliance issues, and future problems end up weighing
them down over time.

I think there's just a balance to be had here.

~~~
hinkley
"My customer data is too big to back up with an rsync cron job" is a nice
problem to have.

"My customer data isn't backed up" is a _stupid_ problem to have, and if your
friends and coworkers aren't stopping you, then you need a better class of
friends.

------
hatchnyc
I think that this advice cannot be generalized. There are companies with large
development teams spending staggering amounts of time solving problems they
don't have and probably never will and companies burning through whatever
goodwill they can find to extract maximum profit by throwing garbage, buggy,
and incomplete software out into the market "because agile". Almost no one
gets this right. I think the two sides feed off each other by each pointing to
the other as an example.

------
mindvirus
This is good, difficult advice. I'm working on an app, and it's so easy to go
off the feature deepend. I recently spent a week trying to do data
import/export - an un-requested feature by my 20 users. That time almost
certainly would have been better spent marketing or otherwise finding more
users.

------
coldcode
Nice to have today, executive demand tomorrow. What's important is not to
solve tomorrow's problems today, but to not inhibit tomorrow's solutions today
either.

------
quanticle
_Whilst I 'm building signup, I realise that I probably also need reset
password functionality. If a user signs up, but then forgets their password,
that's a problem. But from my perspective right now, is this a nice problem to
have? Actually, yes! I have zero users, but having this problem implies I
would have users, which would be great. Reset password functionality is
important, and will absolutely be required eventually, but I can do it later.
First, I should ship anything that's stopping me from getting users in the
first place._

While I'm all for building minimum viable products, I would argue that a login
process that does not have a password reset function is too minimal to be
viable. If you're so strapped for time that you can't build a password reset
form while you're building your user sign-up form, I would ask why you're
bothering with building your own sign-up functionality at all. Why not use
OpenID or OAuth based logins that bypass the need for building a sign-up
system at all?

As a user, I would be hesitant to sign up for a product that didn't have
password-reset functionality, and, if I discovered that the service I just
signed up for has no way to reset a password, I would probably stop using it
(since I lost my password and have no way of resetting) and disrecommend it to
people who ask me about it.

~~~
davnicwil
The password thing was just an illustrative example, it's not perfect, but the
point isn't that you don't need it or that not having it won't be really bad
_when_ you have users, it's that whilst you don't have users perhaps there are
other things that are higher priority to build first.

When those are done, reset password might literally be the next item on your
list. You might end up building and shipping it before anyone signs up anyway,
but in the meantime you've at least got something out there and had the
opportunity of getting any users at all.

~~~
ggggtez
And data security will come exactly: never. Because security is never the most
important thing. A company that runs with this mentality will always be
reactive, and never prepared for threats.

~~~
davnicwil
Security is foundational. It's not something to add later. Without it, signup
is not done and shouldn't be shipped. Ironically, not having the reset
password functionality actually _reduces_ security bug surface area :-)

~~~
afarrell
Which is an argument in _favor_ of leaving off some features. Don't half-ass
password reset. Wait until you have the need to whole-ass it and make things
conceptually-coherent.

------
greggyb
I take a different attitude to "nice to have" problems. I work on a
professional services team that is massively undersized relative to demand.
Our role is less than a year old within the organization. We have far more
clients in need of support from my team than we can give.

This is a great problem to have - lots of pent up demand. Nevertheless, it is
a problem, and we must actively strive to solve it. It's nice to have lots of
demand, yet if the problem is not solved, we will be giving up future revenue.
A larger team will be able to support more revenue than a smaller team.

There is no part of this situation where it is a good idea to slow down on
hiring, or to compromise on hiring standards.

Ninja edit: this is in contrast to things that aren't a problem yet. E.g., in
the article, the author discusses not having password reset functionality.
That is not yet a problem in the absence of users. It's not a nice problem to
have. It is not a problem.

~~~
frandroid
> It's not a nice problem to have. It is not a problem.

I think you misunderstand his word usage, though you're seemingly following
the same process.

A "nice problem to have" is one that results from having success. Yes, he
doesn't have the problem now, because he's got no users, so indeed, having to
reset the passwords of existing users would be a "nice to have" problem.

You're already in the "nice to have" zone (clients with problems to solve!),
and you want to fix those problems brought on by popularity.

~~~
greggyb
It's a matter of tense. I think we're all agreeing in this sub-thread.

I am focusing (perhaps too much) on the tense issues. Without tense, "no
password reset mechanism", to continue using the same example, represents a
problem state.

If something _is_ a problem, it exists in the present.

If something _will be_ a problem, with any contingency or timeline, then by
definition it _is not yet_ a problem.

Even in your own phrasing, the tense issue becomes clear:

> Yes, he doesn't have the problem now, because he's got no users, so indeed,
> having to reset the passwords of existing users would be a "nice to have"
> problem.

Specifically "... would be a "nice to have" problem." This indicates that it
_is not_ a problem, rather that it _can become_ a problem.

------
temac
This can be used to justify any kind of crap being shipped in newly introduced
features, merely baring regressions.

Therefore I don't value the approach as presented here. But a sane variant
could be interesting: anyway I suspect it will need domain specific judgment,
preventing from throwing a nice universal rule of thumb to the world.

------
bluedino
The glorification of technical debt.

A 'good problem to have' is 'we need to scale to handle another 1 million
users', not missing basic functionality.

------
IanCal
I deleted my older comment.

For many "nice problems to have" I really disagree.

A nice problem to have can be a real problem. It's nice you are in that
situation but it's still a problem.

Your site offline because of demand is a nice problem to have. It's absolutely
one to solve right now.

~~~
dragonwriter
They are discussing nice problems to have _relative to the status quo_ , so
problems that are really only potential problems right now, but could become
actual problems if good things happened. So I think even with the rewrite,
your comment misses the mark.

OTOH, I think that it's still a bit wrong to say don't solve them now: if you
have a problem that is potentially a business-ending disaster that you won't
have time to fix before it destroys your business if it manifests, it doesn't
matter if the conditions which would cause it to manifest are otherwise an
improvement over your status quo conditions. It still needs fixed before that
happens.

Otherwise, yeah, YAGNI applies.

~~~
davnicwil
Yeah, your first paragraph is spot on. It's pretty much exactly what I was
going to reply to IanCal. Instead I'll just +1 it.

On your second paragraph, 100% agreed. This is really just a useful
prioritization heuristic, not a rule, and in some cases other considerations
should and will override it.

It's mainly useful just to deliberately and routinely check that instinct to
go deep on whatever you're working on when there's a lot of breadth to cover
that's more important to get done first.

~~~
IanCal
Whether the problem is nice to have or not is entirely orthoganal to how
important it is to solve.

"Is this feature important, or a nice to have" is the question they want, not
"is this problem nice to have?".

------
peter_d_sherman
>"It's good advice, but hard to follow in practice. Often when you explore
solutions to a problem, even simple ones, the problem reveals itself to be
more complex than you'd anticipated. You find sub-problems, and tangental
problems, which look just as important as the original. It's easy to go off
track and end up deep into the problem you were supposed to just find a quick
solution to. After all, it's just one more thing, you're thinking about it,
and you'll have to solve it at some point anyway. Why not now?

I've made this mistake a lot. I'm trying to get better at being strict about
saying "not now" to new problems that I discover in the middle of an
iteration, and avoid getting sidetracked from shipping by working on things
that can be left for later. I'd like to share a tactic I use to do this that
has worked well for me. It's to ask a simple question about each new problem I
encounter: "From my perspective right now, is this a nice problem to have?".
If yes, I skip it. If no, I work on it immediately."

Opinion: There is great value to persisting problems that can be
instantaneously or quickly solved, if only for the simple reason that they can
be thought about; meditated upon; and other/better/more novel/more
creative/more elegant solutions devised -- than the one initially determined
by one's mind...

In fact, if in the future, I built a large company, and solved all known
business problems (well, in that business's industry!), then I'd probably want
to get rid of that company and start over again with nothing!

Why?

Well to again rethink/reengineer better solutions -- to the problem set that I
once faced as barriers!

You will always think more creatively the second (and nth) times you revisit
problems and problem sets!

This might sound crazy to most normal people -- but I value problem solving
skills over money.

With problem solving skills, you can always get money -- but the reverse is
not always true...

Anyway, excellent article!

------
masukomi
Having too many customers trying to buy your stuff is something folks would
call a "nice problem to have"

It's a TERRIBLE problem to have not addressed in advance because now you're
loosing money and people may wander off.

almost everything folks call "a nice problem to have" is not really "nice".
It's frequently business hurting and sometimes business killing.

~~~
notriddle
If you have no end-users, then deficiencies in your product won't cause any
actual problems. (points at head)

------
pandamaniac
Does anyone else feel like we are all trying to be high growth startups?

I understand that we all want to build products which others use and pay for
but why not also be building things for yourself?

Is it really such a bad thing to spend some time over-optimizing pieces of a
system for your own pleasure and possibly learning things along the way?

------
thdc
I'd say this is more relevant for (customer facing) features and not so much
for (technical and architectural) problems.

Work on the most important features first but find the middle ground between
some spaghetti that just works and an over engineered system.

------
derfabianpeter
I think this is great advice, but hard to apply or understand if you‘ve never
actually had nice-to-have problems. I can totally relate to those rabbit-hole
kind of problems that only feed the procrastinator in me.

~~~
davnicwil
> I can totally relate to those rabbit-hole kind of problems

Exactly the mechanism that this question aims to address!

------
satyrnein
Obviously it's just an example, but should most new companies just avoid
building login entirely and use something like Auth0, AWS Cognito, Firebase
Auth, etc?

~~~
richardwhiuk
You should definitely do SSO from some other service if you can.

