Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Ask HN: How do I stop being obsessed with software architecture?
40 points by throwaway_32u10 on May 30, 2024 | hide | past | favorite | 34 comments
So, I'm an experienced dev with more than 10 years of experience. I do mostly web development.

Every once in a while, I catch myself obsessing about architecture. It usually goes like this: I got some free time, I start to think that my current code sucks and that I need to rewrite it "the proper way".

This usually means proper separation of concerns, layers, abstractions and what not. I'd go crazy with that. I get troubles sleeping, I get very stressed mainly because I want to do it quick so I could go back to actually adding features and fixing bugs.

This mainly apply to my side projects, as at work I rarely have the luxury to rewrite stuff or introduce big changes. But it's really bothering me. For example right now I have an app that makes some money and I want to scale it by adding more features. But I got caught into this architecture obsession and so I want to rewrite it because right now there are no abstractions whatsoever. HTTP requests comes in, I do raw sql queries and get shit done. But I want to make it nice, have clean architecture, onion architecture, proper domain layer. But none of this matters. It's a one man show, and it works.

And yet, I got stuck in this mode for the past couple of days, and I can't seem to get out of it. The sad thing is that I start the refactor, realize midway that I did not think it through, waste a day of my life, go to sleep, and repeat the same tomorrow thinking that I have found a "better way" to do it, just to make the same mistake again in a different place.

How do I stop being obsessed with software architecture and actually focus on getting shit done?




I used to struggle with this.

Good engineering is not about good code. Good engineering is about taking the actions you need to take to solve a problem while minimising costs. Usually the problem is making money and usually the biggest expense is time. Writing good code can be useful but knowing when not to spend the time makes you a better engineer.

Our school took us to the engineering department at the local university for a taster day. They challenged us to build a wheeled robot which could cross a swimming pool in the shortest time possible. I got together with my geeky friends and at the end of the day we proudly presented our clever tower of gears robot which kept the motor above water while transferring power to the wheels

The trouble makers in the class also teamed up and spent the whole day throwing around bits of Meccano at each other and at us. As the teachers announced end of time they quickly attached a couple wheels to their motor and called it a day.

When it came time to race, their entry sank straight to the bottom, hit the floor and sped across to the other side before ours had a chance to get its coat on. They won by a large margin, and for good reason! None of us had thought to wonder if the batteries and motor could run under water, it would only need to do it once and last say 30 seconds, none of us had questioned the requirements and we’d spent the day building something slow and complicated. If I find myself spending too long on abstractions and not the problem I think back to this


That's actually a great story - I'm wondering if the winning team was as surprised as you?


I believe they were!


It's the same urge to abandon the current side-project and start a new one. It's normal, all Devs have it. Your brain always wants to do new fun stuff. You see a new shiny framework you want to use it. For me what took me out of this habit was to get rid of all the online-dev-community noise. Don't listen to any of the new trends, new frameworks, new architectures. They are just noise. And at the same time focus on why you started your side project in the first place: to solve real problems of real people. None of these people care what fancy tools you use or what architecture your backend is built with. What they care about is if you solve their problem. So focus on that. And if at some point your bad architecture from 5 years ago stops you from solving real problems, then change it. But from my experience the probability that no one will use your app in 5 years is way way higher than the probability that you have so many users that your architecture will actually matter.


Obsession usually means your emotional reasoning is over powering your logical thinking ability.

I suggest - Every time you rewrite, document your architectural changes in a long form article.

You are essentially journaling your thought process, but explaining it to someone else forces you to break the emotional connect you have with your code.

This way you will start to view software architecture with a balanced mindset.


I can relate to this, especially on a side project where there is no one looking over your shoulder or holding you to a deadline, it’s very easy to spend too much time on the wrong things.

The stress you feel is the feeling of not having enough time to actually do the thing you’re wanting to do. But it’s important to recognize that the reason you don’t have enough time is because the thing you are working on, will not move the needle on the side project.

Deep down you know this, but it doesn’t matter because it’s hard to stop when you get stressed and emotionally deregulated. This is a very common trait in ADHD.

When I start to feel that stress, I typically will try to force myself to step away from whatever I am doing and take a five minute break. After I take a break if I still want to work on whatever it is, I force myself to put an end time on it, and also to relate the task back to a larger goal that will move the needle on my project. If I can’t do either of those things, then I stop the task. Hope it can help, it’s not easy.

See if you can get yourself obsessed with working on things that will move the needle like a new feature instead of rewriting old code.


Give in.

You'll do it a few times, rewrite everything, get a sense of the work vs reward ratio, and over time be better at only thinking about things that are really worth the effort.


Embrace simplicity and understandability as the key architectural tenets.

If you understand it and it’s simple then it’s good enough.

YAGNI and KISS are my key architectural tenants.


Tens of simple decisions will inevitably lead to a complex architecture.

Managing complexity is the tenet of software engineering.


+1 on this... keep it as simple as possible for as long as possible. A lot of the "clean code" patterns that some always push for aren't always needed, especially with smaller or independent projects.


Architecture is supposed to be things that help you get the stuff done that needs to get done.

Don't confuse architecture with how many repos you have or how big your files are. If you do, you'll end up just moving deck chairs around on the Titanic.

Don't confuse architecture with using more logical blocks than you need to. Some people really like making a PizzaFactoryFactory when really they just need to call a constructor.

Let architecture be the patterns that help you do the next thing. If something works how it is, you don't need to refactor it. Especially if it's worked like that for a long time. Leave good enough alone.

Remember there's a reason why you did things the way you have done them. That's worth a lot more than having a "clean" architecture (which honestly means nothing. clean to one person is a mess to another).

If you're going to add features, do it, and make the new architecture choices there. You don't need to change the architecture of everything just because you want to add something. If you did, I'd say that's "bad" architecture.

Also, don't let the new tech hype fuel your desire to change everything according to the new hype. If you do new hype you'll not only have to change everything, but you'll end up with bugs from whatever the new hype is anyway. And you'll end up with the same product doing the same things anyway.


Your problem is that you don't have a termination criterion, so I propose this:

1. Write the product and tech specs. This lets you know when your work is done.

2. Propose an architecture that meets it, and move on. Don't overengineer it.

3. Implement the architecture.


You're asking the wrong question. The right question is "why am I building this thing?" It can be hard to introspect enough to be honest with yourself when answering.

The answer might be "for the extra income" - but I doubt it. That might be the justification to others, but if what you wanted is money you'd focus on shipping - and getting paid. You'd focus all your time on marketing what you have, not tweaking it. (The place where you work has figured this out, hence they don't give you time to waste rewriting).

Are you doing this to have something to be proud of? To show the best craftsmanship you can do? If so re-architechting it is the goal, and you should embrace it. (Also accept you'll be doing this forever, since you keep growing as a programmer you can expect to recraft regularly.) That's OK, that's why the project exists.

Perhaps it's something else. Perhaps you feel unskilled (imposter syndrome) and the "success" of this project helps you build confidence.

Perhaps it's a learning exercise. Perhaps it's a distraction from other issues. Whatever.

Understanding your actual motivation gives you the freedom to embrace the process. Goal is to make money? Then the code doesn't need to be perfect, just shippable. You're free from feeling like it needs to be perfect. And so on.

Figure out the "why" and the process becomes a lot more forgiving.


> How do I stop being obsessed with software architecture and actually focus on getting shit done?

Write the documentation of the current and besides it write documentation of the new version. Refactoring is important and it helps further to have the documentation of the new before you've rewritten the old. Unless it's a brand new application; it's going to be the same right?

Articulate your current application so you have a visual proof of that it is doing what it should be doing. how is it's functioning and ensuring you can rebuild said app from scratch from documentation alone.

With that documentation you then start to unbundle the knots you've created in your mind and code. You see the faults, lags and notice where improvements and new features can all the rest.

The newly documented pseudo-code then presents the foundation plan of your next version and enables the ability of implementation of feature sets, the fixes required that would be a struggle to retrofit.

It's tedious, boring, a great effort and hard discipline but when you've got it down on paper you've then got true focus to the software architecture. It opens your mind.

Documentation plays a big part in all code and your app/program will always feel not-it without it. I'm currently writing mine and it's a chore. I would love to implement my new discovery feature or to create an editor to document my own code but the deeper I go without documentation the more thicker dark mist I encounter.


Delaying critical decisions in a project is crucial to making good decisions. They'll be made both by someone more informed (after learning all the complicated corner cases of the problem domain) and by a better developer (perhaps a future version of yourself).

Therefore, my advice is to pretend you're a junior developer and do things the most naive way possible. Allow things to stink, to repeat code and to support just what's needed, as if this was the absolute final complete state of the application. This may lead to eventual refactors and this is healthy as the focus will be on correcting existing problems instead of foreseen ones.

This is when you allow your senior knowledge and experience to do what's necessary to return to a state that's comfortable for a junior. It's counterintuitive, but at the scale of a large codebase, the occasional refactors ouweights the time wasted doing preventing design at ever layer. I actually have a similar stance about defensive programming and testing.

Since this might not be enough to appease your brain, keep in mind that abstractions are generalizations trying to encompass some common 80%+ of cases, but they're usually never perfect and leave behind edge cases with additional complexity. Unfortunately, composing abstractions is multiplicative. 80%*80%=64%. Do it enough and your whole application becomes unsupported edge cases, constrainted to fit within interfaces, functions and types not able to adequetly give you the results you want and, so, you go crazy down the rabbit hole, trying to desperately break it down into even more suitable abstractions, like that's going to help.


It's the same "make it work; make it right; make it fast". The issue is that Scrum has emphasized the first one at the expanse of the other two. Minor changes over the lifetime of the project snowball into an inconsistent and complicated codebase. No time is given to reflect on the project and each module to refactor it into something sane every once in a while. It's all about velocity instead of maintainability, correctness, and performance. The craftsman in you will certainly react to that.


My current hack is reminding myself it's better to have a poorly architected system that's finished / functional than a half-finished "well architected" one

Once I notice things creaking I start doodling a new arch.

Or if I notice I'm spending too much time on addressing the product of my currently suboptimal design then I might refactor it, but it usually isn't or shouldn't be the most important thing


> The sad thing is that I start the refactor, realize midway that I did not think it through, waste a day of my life, go to sleep, and repeat the same tomorrow thinking that I have found a "better way" to do it, just to make the same mistake again in a different place.

FWIW, this isn't wasting your time. This is exactly how your learn your craft. You don't learn much from things that work right first time, you learn from making mistakes, and understanding why they failed. Over time, that turns into intuition - a gut feeling that approaching a problem one way will fail because you remember that time you did something a bit similar and it turned out to be a bad idea. Given enough experiences like this, when you encounter a new problem, you'll very quickly be able to limit the solution space down to something manageable and then you have a good chance of coming up with a good solution almost right away. You might still make mistakes or bad decisions, but the more of those you've had in your past, the less likely they'll be in your future.


I found it useful to set deadlines that force me to prioritize features that add value/functionality. Since for me these are just personal projects, I try to add accountability by telling friends "hey, Monday I want to show you this really cool thing I did". This helps sharpen my focus.


It could be that you have an anxiety disorder, obsessive personality disorder or OCD. Or perhaps not, but the obvious red flag is trouble sleeping. If you’re typically a good sleeper but find yourself sleepless when in one of your spirals it's a good indicator that you need to take a step back, take a deep breath and reset your mental state because its not the refactoring thats not letting you sleep its all the stuff that you have built up in your head.

Also complete rewrites in general are overwhelming and tend to turn out not the way you imagined anyway. Small incremental improvements and isolated refactors over a sustained period of time yield the best results.


Focus on incremental improvement. You don't have to rewrite the entire system to improve the architecture. As with many things, moderation is the key: if there's something blocking the actual work you need to get done, give yourself an hour or two to refactor it enough to do the thing, then go do the thing. It doesn't always have to be 1:1, but if you tie a refactor to the actual thing you need to get done (and you keep it very small and self-contained), then you'll always at least be doing something.


Do you enjoy it? If so, maybe consider a role where this is a key contribution. It sounds like at some level, you're good at it and naturally inclined to think this way. If you enjoy it lean into it and be excellent.

Where things get difficult is if you're trying to be a founder/creator and you have perfectionist thinking. That gets you into a negative cycle where you're neither productive (velocity) or satisfied with quality. You have to learn to detach yourself from judgement and focus on actions that drive more important outcomes.


Yes I have been through the same recently. Honestly, the motivation pump I gained after I could finish the architecture refactoring was totally worth the burnt out months I had previously where I didn't code at all in my side project. After some time I decided to continue the refactoring and finishing it was definitely the right decision - but I got very close to giving up and forgetting about it - 6 months of relentless coding.


I don't see this listed yet, so do the same thing you'd do at work: keep a prioritized backlog, and do project planning to decide what to work on next.

When you see an architectural defect, write it into your backlog, then flesh it out as part of grooming on your backlog for whether it's worth doing or not.

You might want to take a course/training on product or project management so you can practice switching hats


Most of the well known and successful products are or at least started with shitty architecture.

May that help you that “right” architecture doesn’t bring food to the table.


Intentional refactoring is not a waste of time. I mean you are learning right, both how to refactor and the right way to represent your problem domain. So that is not bad nor a waste of time necessarily. Do the refactor as it will help you create new features later and as you gain experience you will start using the design patterns from the beginning.


this answer might seem off topic, but it really isn't. your problem isn't really architecture here - it's getting stuck in an unproductive mental rut. do you agree?

if you do agree, then the solution is something along the line of avoiding the rut in the first place:

1. strengthen your resolve to think things through before committing to them - is it worth the risk?

2. get a second opinion - talk to your social network (in person preferably), about your idea, your concerns about it, and ask them to check up on you a quarter of the way through - if it seems like it's not a good idea, it's often easier for others to spot it in our behaviour.

for the first one, you could consider things like mindfulness meditation/reading Stoic literature - these help you build the mental skills to step back and ask questions instead of being dragged around by what is ultimately an emotional excursion.


Get a job where you are being paid to obsess over software architecture.


This is the easiest and safer bet


Struggled with the same thing. This is what I do now.

Build a side project and enjoys 0 user => you will know you're refactoring a piece of shit emotionally.


Talk to your coworkers and have them lead more.


start to make money with your side projects.

I have thrown up a wordpress site and marketed it to people interested in it (Facebook Groups, Reddit, SEO, etc) and it makes money on it's own.

No software architecture, just a side project that provides value to people.


I have the same issue. I personally recommend to do "things that don't scale". Just continue to pump out features and make more money. Do not worry at all about scaling, in fact, ignore it.

Why?

1) It's extremely unlikely that you will actually hit a major issue because of scale or wrong software architecture which will bring your system down

2) Even if that's the case, it will probably be easy to fix it when it happens because the issue will be clear, whereas in hindsight you are trying to solve 1000 architecture issues without actually knowing what will come up

3) Even facebook and google probably had problems in the beginning of their startup life. Even if your system crashes and is down for a day or two (for non mission critical apps obviously), it's not the end of the day, nor will in matter in the medium or long term, and probably not even in the short term. I can tell you I worked at a unicorn startup with government and bank clients which are usually the most strict, and that kind of stuff happened all the time... so unless it's mission critical and/or you are dealing with extremely strict customers, it doesn't make a difference

4) After coding a bunch of features, patterns emerge by themselves. Very often I do early optimizations that end up not actually being so useful since I have to add new features that work in a way the current well thought of architecture doesn't allow. I think I got it from Joshua Bloch's book or ppt/pdf on designing APIs that it's better to actually work with 3 (magic number, but I attest from personal experience that it should really be a minimum) actual use cases before designing an API. Same for architecture, by focusing on it before the code, it ends up having to change later on anyways, and we end up optimizing for non issues and loosing flexibility where it is needed. However, after you code enough features, you see where you've repeated yourself, that's not a major insight, and abstracting those or encapsulating those repetitions that happen 3+ times is now trivial. You can then choose when you code your Xth (s.t. X>3) feature and you've encapsulated the repetitive code whether to refactor the first 3 features to use the new implemented encapsulation or just leave it as is because a) it takes time to refactor and b) if it works, don't fix it, though you may prefer to simply and quickly replace the repetitive code by whatever construct you made to keep the code consistent and so that the code itself should serve as an example of implementing features for yourself or other programmers in the future.

5) To continue on the 4th point, doing the architecture without knowing how the system will evolve (which is really impossible in software, we do not know how customers will react to features beforehand and what the needs will be) is basically impossible. I think that's where the stress comes from: You want the architecture to be good, but there's always a "it could be like this" "or the need could be different like that" "or we could have 5 different needs". It's endless, the software can evolve in so many ways and it's impossible to predict, so which way should you optimize? And each design takes time, hence the stress: you don't ave enough mental/time/etc resources to deal with all the potential needs. However, if you switch that to "I don't need to solve it before it comes up" all the stress goes away, and you can just try out new features.

If you do this, your revenue will (hopefully) grow, you will be more productive, your system will end up more robust and have better architecture (because it's always easy in hindsight and usually impossible beforehand), you will avoid stress, and be happier!

Happy coding, all the best :)

PS: The examples are the same usually for horizontal or vertical scaling and splitting things into microservices, and for a bunch of issues, I just picked a simple idea, but I do believe it's a general approach what I said in point 4.


> 1) It's extremely unlikely that you will actually hit a major issue because of scale or wrong software architecture which will bring your system down

that's definitely not the case. In a side project, usually bad architectural decisions are the ones that makes your programming effort more difficult. Refactoring is only a good reason (for side projects) if that will help you ship faster with better quality.




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

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

Search: