Why I Stopped Reaching for the Monolith First
Queues aren't clever. They're just honest about the parts of your system that were always asynchronous — whether you admitted it or not.
For years my reflex when starting a new project was to build a monolith. Single repo, single deploy, single database. It's the fastest path to a running product, and for most teams it's the right answer.
But somewhere along the way I noticed a pattern: every monolith I shipped that grew past a certain size eventually grew the same set of pain points — the same kind of long, gnarly request paths that did three things at once, the same retry-and-timeout dance around a slow third-party API, the same Tuesday-morning incidents where one feature took the whole app down.
The thing that broke the pattern wasn't microservices. It was just queues. The honest acknowledgement that some work in your system was never really synchronous in the first place — emails, exports, indexing, billing reconciliation, third-party fan-out — and pretending otherwise was costing you reliability.
So now my default has shifted. I still start with a monolith. But the moment I see code that says 'wait for this thing that doesn't really need to happen right now,' I reach for a queue. It's the cheapest reliability win I know.