I think hexagonal architecture should be the default for almost any project bigger than a script. Not because it's trendy or because some book said so, but because the math is wildly in your favor: the cost is tiny and the payoff is large.
Let me make that case.
What you actually pay
Hexagonal architecture asks you for two things:
A port — an interface describing what your domain needs from the outside world. "I need something that can save a User ." "I need something that can send an email."
An adapter — a concrete implementation of that port. The Postgres class that saves the user. The SendGrid client that sends the email.
That's it. That's the whole tax.
In statically-typed languages, the port is a literal interface (or trait, or protocol). In interpreted languages, such as Python, Ruby, or JavaScript, you don't technically need to declare anything; duck typing handles it. I still recommend writing the contract down somewhere, even informally as a base class or a Protocol or just a comment block.…