Architecture Decision (Day 0)
Most people treat architecture as a day 300 problem. It's not. It's a day 0 decision — and it matters more than you think.
Some overly smart system design folks will tell you to go Golang microservices from day 1 and optimize for scale before you've even validated anything. Ignore them.
The more sane take: stick to a monolith, but make it modular. Smart service layers, clean repositories, intentional abstractions. Observability and determinism baked in from the start — Sentry error logging, Alembic migrations — these aren't nice-to-haves, they're load-bearing.
One of my current projects has 38 service modules, all wired with that intent since day 1. New devs join, they know exactly where to look. Service, repository, model. That's it.
And that matters when you're at a startup shipping 10 features a week with 100s of active bugs across the QA pipeline. Good architecture isn't a luxury — it's how you avoid 10 devs on 10 laptops fighting over the same file.
Messy codebases don't happen because people are bad engineers. They happen because architecture was an afterthought. And once you're in a place where only one person understands one service — and everyone else just creates a new service rather than touching it — that debt doesn't disappear. It compounds.
The flip side kills you too. I've debugged codebases with so many abstraction layers that hitting next on the debugger 10 times still doesn't get you to actual business logic. Over-engineering is its own trap.
Somewhere in between is where the good software lives.