Building a multi-tenant SaaS from scratch teaches you humility faster than any course. At Neuron Nest I architected an EdTech platform where many schools, the tenants, share one system but must never, ever see each other's data. Simple to say. I made nearly every mistake there is to make on the way to making it true.
Mistake one: thinking RBAC is simple
Role-based access control sounds like a solved problem. Admin, teacher, student, done. It is never that. Real schools have a finance person who can see fees but not grades. A coordinator who manages some classes but not others. A super admin at the company level who can cross tenants for support, which is exactly the kind of power that, if it leaks, ends you.
My first RBAC design was a flat list of roles. It collapsed the moment real requirements arrived. I rebuilt it as a dynamic permission system where roles are bundles of granular permissions, scoped to a tenant and sometimes to a resource. That redesign cost me weeks I would not have spent if I had taken the problem seriously from day one.
Every shortcut you take in your permission model becomes a security incident with a delay timer on it.
Mistake two: tenant isolation as an afterthought
The big architectural question in multi-tenancy is how you separate data. Shared database with a tenant ID column, separate schemas, or separate databases. I went with a shared database and a tenant ID, which is cheap and operationally simple. The catch is that isolation now lives entirely in your code. One query that forgets the tenant filter and you have a leak.
I learned to never trust myself to remember the filter. I pushed isolation down into the data access layer so that it was nearly impossible to write a query that escaped the current tenant scope. If isolation depends on every developer remembering a WHERE clause forever, it will fail. It is only a matter of when.
The meeting I will never forget
Here is the story that still makes my stomach drop. During testing, a client looking at their dashboard saw a number that was not theirs. Aggregated data from another tenant had bled into their view. It was a reporting query, an analytics rollup, that I had written without the proper tenant scope because it ran in a context where I "knew" the tenant was set. I did not know. I assumed.
It was caught in testing, before any real harm, which is the only reason I can tell this story calmly. But sitting in that meeting, explaining how one client almost saw another client's numbers, was one of the worst professional moments I have had. Trust in a SaaS is everything, and I had nearly spent it on a missing clause.
What I changed after
- Tenant scope became a non-negotiable part of every data path, enforced at the lowest layer, not the highest.
- Analytics and background jobs, the contexts where you "know" the tenant, got the strictest checks, because that is exactly where assumptions hide.
- We wrote tests specifically designed to try to leak data across tenants, and we treated a passing leak test as a release blocker.
- RBAC and tenancy got reviewed together, because a permission bug and an isolation bug are the same family of disaster.
The honest summary
The platform works now. The RBAC is genuinely good, it cut client onboarding time noticeably because permissions are configurable instead of hardcoded. The isolation holds. But none of that was the result of a clean first design. It was the result of making a long list of mistakes, getting scared by the right ones, and rebuilding the foundation while the house was already occupied. If you are building multi-tenant from scratch, assume you will make these same mistakes. Build so that the cheap ones stay cheap and the expensive ones get caught in testing, not in a client meeting.
Saroj Prasad Mainali
Full-Stack Engineer · Kathmandu
MORE FIELD NOTES
03