A multi-tenant product built to scale from day one

Software-as-a-service has its own hard problems - tenant isolation, billing, and infrastructure that scales - solved once, correctly, instead of patched in later.

Built fromCloud & DevOpsCustom SoftwareLedgerly is a made-up product.

The unglamorous parts every SaaS needs

None of these sell the product, and all of them are hard to add once customers are on it. They go in first, in a simple form, so they are never patched in after a close call.

PartWhat it coversWhy it goes in first
Sign-in and accountsEmail and Google sign-in, invites, password reset, SSO when a customer asks.Everything else hangs off who the user is.
TenancyEvery record belongs to one customer, enforced in the database, not only in the UI.Adding it later means touching every query.
Plans and billingTrials, upgrades, proration, failed-payment retries and invoices.Revenue leaks quietly when it is done by hand.
Roles and permissionsOwner, admin and member to start, custom roles per customer when needed.The first larger customer asks for it.
Audit logWho changed what, when and from where, exportable per customer.Security reviews ask for it by name.
Usage limitsMetering what each plan caps, with a warning before anything stops.A plan limit means nothing without it.
Support accessYour team can see into a customer's workspace, with every visit logged.Support needs it from the first week.
Email that arrivesInvites, receipts and alerts sent from your own domain, set up properly.It is set up once, and noticed only when it breaks.

The architecture, drawn simply

One codebase serves every customer. The part that matters is where the line between them is drawn - in the database, where a bug in the app cannot cross it.

Your customers
Brightside Bakery
Harbor Dental
Oakline Studio

Each signs in to their own workspace.

One app, one API
  • Sign-in works out which customer is asking
  • Every query carries that customer's id
  • Plan limits checked before the work is done
  • Every change written to the audit log
Database
Rows kept apart per customer by the database itself
Payments
An established provider; its events update plans
Background jobs
Imports, exports and emails, off the request path

From launch to scale, one step at a time

Built for your growth curve, not only for launch day - and nothing added before the stage that needs it.

Launch

One database with each customer's rows kept apart, one region, plans and billing through a payment provider, the admin above.

Growing

Heavy work moved to background jobs, usage metered per plan, per-customer rate limits, a status page.

Larger customers

SSO, audit log exports, a separate database for a customer who needs one, and a choice of data region.

A good fit if

  • You're building a product multiple paying customers will use independently
  • You need real tenant isolation, not a shared database with a filter

Not yet if

  • You're building for one internal team, not external customers
  • You haven't validated anyone will actually pay for this yet

Questions we get asked

Do we need all of this before launch?

The parts in the table, yes, in a simple form - they are the ones that are painful to add later. The rest is added at the stage it is needed.

How are customers kept apart?

Every record belongs to one customer and the database enforces it, so a missed filter in the code cannot show one customer another's data.

Do you build the billing yourselves?

No. Payments run through an established provider; we build the plans, limits, upgrades and retries around it.

Building a product customers will pay for?

Tell us who the customers are and how they will pay. We come back with the parts it needs at launch, what can wait, and a timeline.

Start a project