The breaking point for me wasn't the code complexity, but the process. Every time our marketing team wanted to change an email subject or bump a delay from 1 day to 2 days, I had to stop what I was doing, write code, and push a deployment. It felt ridiculous to deploy a new build just to change a timer.
I ended up ripping about 400 lines of boilerplate state-management code out of our backend. I moved all that logic to an orchestration layer instead (I built a tool called Flowripple for this). Now my backend just fires a 'user_signed_up' event and forgets about it. The orchestration layer handles the state, the delays, and the retries by a visual workflow builder on flowripple.
It has mostly solved the "separation of concerns" headache for us, but I'm curious how you all handle complex onboarding flows? Do you stick with Cron/Queues to keep it simple, or do you offload the state management elsewhere?