B2B SaaS product development
Multi-tenant SaaS is one decision you make early and pay for slowly.
Everything expensive about a B2B SaaS product traces back to three choices: how you isolate tenants, how you handle enterprise identity, and how usage becomes an invoice. Get them wrong and you find out in the quarter a serious customer asks for SAML and a security review. This page is what we’d build, and why.
Row level security
Put the boundary somewhere a developer cannot forget it.
Postgres row level security turns tenant scoping from a convention into a constraint. Two details decide whether it works. A USING clause filters the rows a statement is allowed to see, so it governs SELECT, UPDATE and DELETE. A WITH CHECK clause governs the rows a statement is allowed to write. Declare only USINGand you have built a system where a tenant cannot read another tenant’s row but can happily insert one stamped with their neighbour’s identifier. That’s a real bug, it’s quiet, and it usually surfaces as corrupted data rather than as a security alert.
The second detail is boring and costs more money: every policy predicate needs a supporting index. Postgres appends the policy to your query, so a tenant filter without a leading index on the tenant column turns a list endpoint into a sequential scan across every customer’s rows. Fast in staging with four tenants, over at four hundred. Composite indexes generally need the tenant column first, and you check plans under the policy rather than without it.
Then there’s the question of how the database learns which tenant is asking. A session variable set per request is simple and works anywhere, but it’s session state, and if you run transaction-mode connection pooling that state doesn’t belong to your request for longer than a statement. Set it inside the transaction and let it die with the transaction, never on a checked-out connection. The alternative is signed claims carried in a JWT and read directly by the policy, which removes the session-state problem and replaces it with token lifetime and revocation questions. Both are defensible. Choosing one by accident isn’t. We work through this in detail on our Supabase and Postgres RLS work.
Two operational requirements quietly eliminate options. Migrations across thousands of schemas need online change tooling and a resumable runner, because a fleet migration will fail halfway at some point and you’ll need to know which tenants are on which version. And per-tenant point-in-time restore, which enterprise contracts increasingly ask for by name, is close to trivial with a database per tenant and painful in a shared schema, where restoring one customer means extracting their rows from a full-cluster snapshot into a staging instance and replaying them without touching anyone else. If that requirement is real, decide it before you write the first migration.
SOC 2, without pretence
We hold no certification. The architecture half is still ours.
EdgeBrain Studios is not SOC 2 certified and has not been through an audit. No agency can hand you a report anyway. A licensed CPA firm issues SOC 2 to your company, against controls your company operates. You bring the auditor, the policies, the onboarding and offboarding process, the vendor register and the risk assessment. A compliance platform will handle most of the paperwork side of that.
What an engineering partner can own is the half of the Trust Services Criteria that turns into architecture and cannot be bolted on afterwards. Immutable audit logging with an actor, a resource, a before-and-after and a timestamp on every state change, written in the same transaction as the change so the log cannot drift from reality. Access review evidence that’s queryable, because an auditor asking who had admin on this tenant in March is a database question if you modelled it that way and a forensic exercise if you didn’t. Change management traceability linking a deployed commit to a reviewed pull request. And an honest encryption scope: transport and at-rest encryption are the easy claims, key custody and rotation generate the follow-up questions.
The pattern is the same in every direction. Retrofitting audit logging into a product that has been mutating rows in place for two years is one of the most expensive pieces of work in B2B SaaS, and emitting events from the first week avoids all of it. If you’re weighing that kind of retrofit against starting again, our guide to judging a rewrite against a refactor covers how we make that call.
When not to hire us
Some of these products should not be built at all.
If you’re building an internal tool that happens to serve several departments, you don’t have a multi-tenant SaaS problem and you shouldn’t pay for one. Departments aren’t tenants. Use one database, real roles, and skip every word above.
If your idea sits in a well-served horizontal category, buy the incumbent. Applicant tracking, help desk, expense management, e-signature, basic CRM: all solved at a price no custom build reaches. The test is whether your differentiation lives in the workflow or only in the interface. Interface dissatisfaction is not a business case, and a configured off-the-shelf product with an integration layer on top is usually the right answer.
And if you haven’t validated demand yet, a multi-tenant platform is premature. A single-tenant instance for your first three design-partner customers will teach you more, cost a fraction, and can be migrated later at a known price. Don’t let an architecture article talk you into infrastructure your revenue doesn’t justify. Our writeups on what an MVP actually costs and choosing between fixed price and time and materials are the plain versions of that conversation.
Send us your tenancy model.
One paragraph on what you’re building, how tenants are separated today, and the largest customer you want to close. We reply with the architectural risks we can see, a scope and a price, inside two working days.