Back to all posts
4 min readJoye

When We Outgrew the Monolith on Joye

What pushed us from one Node.js app to 12+ services on Azure.

MicroservicesAzureNode.jsJoye

When I started on Joye, most of the product lived in a single Node.js monolith โ€” React on the front, MongoDB on the back, one deploy pipeline. That worked fine for a while. Once we embedded wellbeing coaching in Microsoft Teams and started sending proactive notifications across time zones, the same codebase was handling coaching flows, scheduling, notifications, and a lot of background jobs. Deployments got riskier, and a bug in one area could affect everything else.

We didn't split services because microservices sounded cool. We split when the team kept stepping on each other's releases. Notifications needed KEDA autoscaling on Azure Kubernetes. Coaching sessions needed Redis for session state. We moved to Service Bus for async work and gave each service a clear owner. The rule we followed was simple: extract a service when its failure or deploy shouldn't take down the rest of the product.

It was more operational overhead โ€” more repos, more monitoring, more things to coordinate. But release velocity improved, and we could scale the notification pipeline without touching the coaching API. For Joye, the split made sense because the product had grown in scope, not because someone read a blog post and decided monoliths are bad.

Written by Aman Kanojiya