Tenant boundary
Tenant ids on every table, an application role with no bypass privilege, policies forced on so ownership is no escape hatch, and tests that attempt cross-tenant reads.
Isolation test suiteSoftware
We build the SaaS layer that makes software sellable repeatedly: a tenant boundary the database enforces, entitlements the app reads on every request, and the identity and audit surfaces enterprise buyers check.
Most SaaS projects are not hard because the features are hard. They are hard because everything has to be true for every tenant at once. One customer’s report cannot touch another customer’s rows, one customer’s bulk import cannot starve the queue, and the plan somebody bought in March has to still be the plan the code enforces in November. Features are the easy half; the invariants underneath them are what takes the time.
So we put the tenant boundary where a tired developer cannot forget it. Rows carry a tenant id, policies are forced on at the table so even the owning role obeys them, and tenant context is set per transaction rather than per session, because a pooler hands the same session to the next request. Billing is the other half: entitlements live in your database, driven by webhooks, so a provider outage degrades checkout rather than locking every customer out.
| What is true of this work | What it forces | What we do about it |
|---|---|---|
| One codebase serves every tenant | isolation cannot rely on discipline | forced row-level policies, cross-tenant tests |
| Connection poolers reuse database sessions | tenant context cannot live in the session | set per transaction, verified in tests |
| Plans change; signed contracts persist | entitlements must be versioned state | plan catalogue inside your database |
| Payment providers have outages | the request path cannot depend on them | webhooks sync, application reads locally |
| Inference cost scales with usage | flat per-seat pricing can invert margin | compute and model spend tagged per tenant |
Tenant ids on every table, an application role with no bypass privilege, policies forced on so ownership is no escape hatch, and tests that attempt cross-tenant reads.
Isolation test suiteA plan catalogue you can change without a deploy, entitlements the app checks in-process, proration that reconciles, idempotent webhook handling, and dunning that recovers failed cards instead of silently churning accounts.
Entitlement serviceAn event pipeline that counts what customers consume, aggregates it per tenant per period, shows the same number in the product and on the invoice, and can shadow-run new pricing.
Metered usage pipelineSignup, workspaces, invites, domain-claimed joins, and roles that mean something before single sign-on arrives, then per-tenant SAML or OIDC connections and SCIM provisioning in the order buyers ask for them.
SSO and SCIM provisioningThe tool support lives in: tenant search, plan overrides, credits, feature flags, and impersonation that writes an audit entry naming the staff member, not the customer they were acting as.
Audited admin consolePer-tenant rate limits, queue quotas, and job fairness so one customer’s overnight import does not become everybody’s incident, plus cost tags attributing compute, storage, and inference spend back to the tenant.
Per-tenant quota policyWe settle two things before any feature work: where the tenant boundary sits, and how money is counted. Pooled or isolated, per seat or per unit, who can invite whom. Both decisions leak into every table.
You getTenancy and pricing decision record
We build the boring spine end to end: signup, tenant provisioning, first login, invite a colleague, switch workspace, and an isolation test that tries to read another tenant’s rows and fails.
You getRunning signup-to-workspace demo
Now the thing customers buy: the workflow that justifies a recurring invoice, with tenant context threaded through the API, jobs, and exports. Then plans, checkout, proration, and the entitlement checks the product reads before acting.
You getPaid workflow with billing in test mode
Roles, audit log, admin console, per-tenant limits, backups you have restored at least once, and the runbooks your team needs at 2am. Infrastructure as code lands in your own cloud accounts.
You getProduction tenant on your accounts
Share one database, with forced row-level security.
Pooled tables scale to thousands of tenants on one migration, one connection pool, one backup. Schema-per-tenant sounds safer and becomes a deploy that touches five thousand schemas and drifts. We build routing indirection on day one, so a single tenant can be lifted out without a rewrite.
We’d choose otherwise whena signed contract or a residency rule requires a tenant’s data physically apart.
No. The provider owns money; your database owns entitlements.
The provider handles cards, invoices, tax, and dunning. Your database holds the row the request path reads to decide whether this tenant may export, invite, or call the API again. Webhooks keep the two in sync, with idempotency and a reconciliation job.
We’d choose otherwise whenthe product is pure self-serve with three static plans and no enterprise contracts.
Sell seats first, but meter consumption from day one.
Seats are easy to forecast and easy to buy, and they let you launch while you learn what a heavy customer looks like. Instrument consumption immediately anyway, because retrofitting a meter into a year-old codebase is a rewrite, and shadow-bill before switching anyone.
We’d choose otherwise whenthe product’s own cost genuinely tracks usage, as with anything inference-heavy, and buyers expect metering.
Buy identity; keep the user table in your database.
Single sign-on is not a login form. It is per-tenant SAML and OIDC connections, certificate rotation, SCIM lifecycle, and a support queue full of somebody else’s identity provider. A hosted provider is worth its bill for years of that work.
We’d choose otherwise whenyou already run an identity provider in-house, or your tenancy model breaks every vendor’s workspace assumption.
You see a working multi-tenant demo within 14 days of kickoff, and a first sellable release typically lands between ten and sixteen weeks. The variable is not engineering speed; it is how long pricing and permissions take to settle. Teams arriving with a decided plan structure and a named first customer ship sooner.
You own all of it. The IP assignment is in the contract you sign at the start, not a handover performed at the end, and the repository, infrastructure definitions, billing configuration and cloud accounts sit in your organisation from the first week. No runtime licence, no hosted component we keep, nothing held back.
Under a hundred tenants on pooled infrastructure, hosting is the smallest line: database, cache, object storage, a queue. The costs that surprise people are the percentage a billing provider takes on usage-based plans, the per-connection price of enterprise identity, and inference if the product has AI features. We show those as cost per tenant before you set prices.
Usually not for your first enterprise deal: a completed security questionnaire and a dated audit plan clear most procurement. Regulated buyers and large procurement teams do hard-gate on the report itself. Build the evidence either way: an append-only audit log, roles rather than an admin flag, access reviews you can run, and encrypted backups you have restored.
Every build carries a 30-day warranty from handover: defects in what we shipped are fixed by us, at no charge, on the same priority we would give our own production. You also get the runbooks, alert thresholds and restore procedure your team needs for everything else. Beyond the warranty, on-call and change work move to a support retainer.
Thirty minutes with the engineers who would build it. You leave with a scope, a timeline and a fixed price — or an honest no, and the reason why.