All services

SaaS platforms

A SaaS rarely fails on its feature set. It fails on four early decisions.

The first customer forgives almost anything. The tenth does not: they want to know how their data is kept apart from everybody else, they reconcile their invoice, they ask what happens during an outage, and they may well be as big as the first nine put together. Those four answers are settled at the beginning or not at all. I take those decisions with you before they get expensive, and where what you have already holds I say so.

AWS Certified Solutions Architect – ProfessionalTenant isolation & billing6M+ users on a payment backendFixed price 1,900 €
What you get
  • A decided tenant model, with the reasoning and with its price in operation, in writing in your repository
  • A worked example as code in a branch of its own: one table, one query and one test
  • The design for billing and usage metering: what gets counted and what turns that into an invoice
  • The list of breaking points at ten times the volume, in order and with the effort per item
Scope & working together

The scoping as a closed one-week engagement, at a fixed price: the deciding happens in conversation, the writing happens in your repository. The production build on top of it afterwards by scope, with the explicit option of doing it without me.

Remote from Germany. Straight with me, no agency in between.

The starting point

The product is not the hard part.

Building a SaaS takes surprisingly little work these days. A framework, a database, a payment provider, and after a few weeks somebody can sign up and pay. That is exactly why the first version almost always looks good, and exactly why nobody notices that in four places a decision was made without anyone making it.

The first is tenant isolation. A shared database with a column for the customer id is quick to build, and it works as long as every query takes that column into account. Isolation then rests on the care of every individual developer, every day, including in the report somebody adds late on a Friday afternoon. The second is billing: whoever counts what a customer consumed only at the end of the month has an estimate rather than a figure, and has to explain it when somebody reconciles it. The third is operations: a backup that has never been restored is a guess.

The fourth only surfaces later and is the most awkward. At some point a customer arrives who generates as much load as all the previous ones together. Where every tenant shares the same database, the same connections and the same background workers, every other customer notices it too. That case can be prepared for without building it today: you only need to know where the platform breaks first and what rebuilding it would cost then.

Does any of this sound familiar?
  • Tenant isolation lives in the application rather than in the database, and holds as long as nobody forgets a condition.
  • A customer invoice cannot readily be traced back to the data it came from.
  • One large customer makes the platform slow for everybody else.
  • A new customer is set up by hand, and only two people know how.
  • There is a backup, but nobody has ever restored it.
  • Every rollout is an evening appointment, because nothing works while it runs.

Who this is for

For product owners whose SaaS idea has a market and now carries technical consequences.

For founders, CTOs and product owners with a validated problem, clear audience and budget for a durable product. Tenancy, billing, permissions and operations need sound decisions early.

01

The problem is validated.

Conversations, pilot customers or an existing manual service show who will use and pay for it.

02

The product needs more than a prototype.

Tenancy, roles, billing, privacy and support are real requirements, not distant backlog items.

03

Ownership is clear.

Product decisions stay with you; architecture and delivery can happen with your team or independently.

What I do

What gets built along the way

01

The scoping before the build

Tenant definitionBilling unitTarget size

Who the tenants are, what the unit is that gets billed, and what customer size the platform should carry in two years. Those three answers settle almost everything that follows, and they cost an afternoon. Afterwards it is also settled what deliberately does not get built.

02

Isolation that does not rest on care

Multi-tenancyRow-level securityIsolation levels

A database per customer, a schema per customer or shared tables with row-level security: each variant has a price in operation, in migrations and in restoring an individual customer. I decide that with you and put the isolation where it cannot be forgotten, in the database rather than in every query.

03

Billing and usage metering

StripeMeteringPlans & quotas

Counting happens where the usage occurs, not at the end of the month out of a report. Consumption travels to the payment provider as a figure of its own, plan changes, credits and cancellations each have a defined path, and every line on an invoice has the records it came from behind it. That is the difference between an invoice and an assertion.

04

Operations with a recovery plan

Multi-AZPoint-in-time recoveryRecovery targets

Two numbers settle the setup: how long the platform may be down and how much data loss is acceptable. From those follow the spread across zones, point-in-time recovery and the path to bring a single tenant back without touching the others. Decided and written down in the scoping; the rehearsal belongs to the build afterwards.

05

The tenth customer

QuotasLoad distributionAmazon Aurora

What happens when one tenant is ten times the size of the rest. Separate queues and quotas so a noisy neighbour does not slow everyone down, a path to move a single customer onto resources of their own, and measurement showing which tenant generates which load. Prepared here means decided and written down, not built today.

06

Rollouts and new customers

TerraformBlue-greenFeature flags

A new tenant appears at the push of a button, not in a wiki article. Changes go out without downtime, and whatever should apply to one customer only is a switch rather than a branch of its own in the code. All of it described as infrastructure in code, so the second environment is a configuration.

Are you building a SaaS, or do you have one that no longer holds?

Send me what you sell and how many customers are meant to run on it. You get an assessment of which of the four decisions is the expensive one in your case, before you commission anything.

How it runs

How this runs

Four steps. After the second the tenant model is settled, and settled with reasons.

STEP 01

A 30 minute conversation

What you sell, to whom, and where you stand today. After that I tell you which of the four decisions is still open in your case, or that none of them is and what you have already holds. I say that too, and it is the shortest route both of us can live with.

STEP 02

The four decisions

Tenant model, billing unit, recovery targets and the target size. Decided together, with the cost of each variant next to it. The result is a paper your team can apply without me.

STEP 03

A worked example in the repository

One table, one query and one test in a branch of their own, showing what the isolation looks like day to day. That is where the entry offer ends. The running skeleton as Terraform code in your account is the production build and is quoted by scope afterwards.

STEP 04

Handover

One hour of handover with the people who build on it, plus the list of the points that break first at ten times the volume, in order and with the effort next to them. From then on it runs without me, or with me if that is what you want.

Entry offer

Tenant model decided. Fixed price 1,900 €

A fixed price, not a starting price. The result consists of decisions and a branch in your repository rather than a build in your environment, which is why the figure can be named in advance. The production build afterwards is quoted by scope, before it begins.

Not a build in your environment but the decision that is no longer cheap to change later: after a week the tenant model stands with its reasoning, a worked example sits as a branch in your repository, the billing is designed, and you know what breaks first.

What you get

  • The decided tenant model with its reasoning: a shared database with a tenant column, shared tables with row-level security, separate schemas or separate databases, along with the trade-offs behind it, in writing in your repository
  • The two numbers of operation as a decision: the acceptable recovery time and the acceptable data loss, plus the target size the platform should carry in two years
  • A worked example as code in a branch of its own: one table, one query and one test, showing what the isolation looks like day to day. Not an assessment, a beginning
  • The design for billing and usage metering: what gets counted, where it gets counted, and what turns that into an invoice
  • The list of breaking points: what breaks first when one customer grows as big as all the others put together, with an effort estimate per item and in order
  • One hour of handover with the people who build on it, recorded on request

What you do not get

  • No running skeleton as Terraform code in your account. That is the production build, an offer of its own, and it comes after the scoping if you want it
  • Nothing built or put into production in your environment: no network, no database, no rollout path and no recovery drill. What is produced sits in the repository, not in operation
  • No finished product. What is produced is the scoping, not your domain logic and not a service ready to sell
  • No interface, no visual design and no sign-up journey
  • No connection of a payment provider. The billing is designed, connecting it happens in the build afterwards
  • No migration of existing customers and data into the new model. That depends on what you already have and is a project of its own
  • No second tenant model built for comparison. One is decided, the alternatives are reasoned through
  • No legal or data protection assessment and no certification against ISO 27001 or SOC 2. What the architecture can contribute towards it is in the paper, but your data protection officer decides that, not I
  • No ongoing support without an agreement of its own
  • Read access to one repository is enough. The example branch is created alongside, your main branch stays untouched
  • Where there is no repository yet, because not a line of code has been written, the example is created in a new one that belongs to you
  • The project can be built and started locally, with its dependencies, fixtures and database, otherwise the test does not run. Where that is not achievable in reasonable time, the example is created in a standalone example project
  • From around 200,000 lines or several applications the scope is agreed beforehand
  • One or two sessions with the people who build the platform
  • One person who may decide on the pricing model and the tenant model. Without that decision there is no result, only a list of variants
  • No access to your AWS environment needed. That is precisely why this carries a fixed price
  • The fixed price holds regardless of how long the work takes
  • A result within a week, counted from the day the access is in place
  • What is produced sits in your repository and belongs to you
  • Price net, plus VAT
  • You are committed to nothing. Some teams carry on alone afterwards, and the paper is written for exactly that

The outcome

What is different afterwards

Isolation that holds without discipline

Where the database itself only hands out the rows of one tenant, a forgotten condition in the code is no longer a data breach but an empty result. That does not come for free: the policy has to bind the table owner too, through FORCE ROW LEVEL SECURITY, the application needs a role of its own without BYPASSRLS, and the tenant is set with SET LOCAL inside the transaction rather than with SET, because otherwise a connection pool carries the tenant context of the previous request into the next one. So the care does not disappear. It moves from every single query to one place that is decided once and checked once, and that is the difference between a rule and an intention.

Invoices that survive a question

Every line has the events it came from behind it. The question of how a figure came about is then a query rather than an afternoon.

An outage is a procedure

Recovery time and data loss are numbers settled in advance and tested once. You can give them to a customer before they ask, and in a sales conversation that is worth more than any availability promise without evidence.

The big customer is an offer, not a risk

Once you know where the platform breaks at ten times the volume and what the rebuild costs, you can accept a large contract and price it in rather than hope.

Technologies I use

Technologies I use

Languages
  • Golang
  • PHP 8
  • TypeScript
Interfaces
  • REST
  • gRPC
  • Webhooks
Tenant isolation
  • Multi-tenancy
  • Row-level security
  • Feature flags
Data
  • PostgreSQL
  • Amazon Aurora
  • Redis
Billing
  • Stripe
  • Stripe Billing
  • Metering
Runtime
  • Amazon ECS
  • AWS Lambda
  • API Gateway
Rollouts
  • Terraform
  • Blue-green
  • GitHub Actions
Operations
  • OpenTelemetry
  • CloudWatch
  • Multi-AZ

From practice

Tim Rutte, Cloud & Software Architect

Who you are talking to

Directly with me as a freelancer. No agency in between.

I am Tim Rutte. More than 20 years in software development. Today I build the platforms other people sell their product on. You talk to the person who touches your code, from the first call to the handover.

  • 20+years in software development
  • 50+successful projects
  • 2003working remotely since then
More about me

Common questions

Common questions about SaaS platforms

We have not written a line of code yet. Is this too early?

No, this is the cheapest moment. The tenant model costs a week at the start and a rebuild during live operation later, with customers who are not supposed to notice any of it. What I will not do is build you a platform nobody knows yet whether anyone will buy. That is exactly why the entry offer is cut small: one decision, one example in the code, one design and one list. You do not need to bring a repository along either: where there is none yet, the example is created in a new one that belongs to you. What gets built after that, you decide after that.

We already have a SaaS, it just no longer holds. Is this the right page?

Yes, with one difference in the sequence: for an existing platform the first step is finding out which of the four points is actually the expensive one. Sometimes it is the isolation, often it is the billing, and in some cases it is none of them but a single query. Where the real problem is code nobody wants to touch any more, legacy modernization is the better entry point, and then I say so. And where it is not the tenant model that breaks but a single path under load, that does not belong here either but on the page about Go services alongside PHP: there the measurement comes first, showing where the time actually goes, before anything gets rewritten.

One database for all tenants or one per customer?

That depends on three things: what your customers require contractually, how many of them there will be, and how often you change the schema. Shared tables with row-level security are the cheapest to run and make restoring a single customer the hardest. A database per customer reverses both and turns every migration into a hundred migrations. Separate schemas sit in between. There is no generally correct answer, only a reasoned one for your case, and that is precisely the result.

Why is billing an architecture question rather than something for later?

Because it determines what you have to measure, and measuring only works while something is happening. Whoever bills by usage and counts only at the end of the month is reconstructing from logs that were never meant for it. On top of that comes the payment provider: plan changes mid-month, credits, cancellations and outstanding amounts each take a path through your data. Adding that path later touches every customer who has already had an invoice.

Do you build the whole product for us?

Not at the fixed price, and not the skeleton either. The entry offer is the scoping: decided, reasoned and shown on an example in the code. The production build, meaning the running skeleton in Terraform inside your account, is an offer of its own and is quoted by scope after the scoping. What your SaaS does for its customers you know better than I do anyway, and for that you do not need an engagement but your own team.

What does building a SaaS platform cost?

The entry offer costs 1,900 euros net at a fixed price and covers the decided tenant model with its reasoning, a worked example in the code, the design for billing and usage metering and the list of breaking points. Why a fixed price here and not a starting price: the result consists of decisions and a branch in your repository rather than a build in your environment. That way the effort does not hang on somebody else's accounts, approval processes and access, and the figure can be named in advance. The production build afterwards is quoted by scope before it begins, not in a supplementary invoice.

Does this have to run on AWS?

Not for the entry offer. The tenant model, the billing unit and the list of breaking points are independent of the provider, and at this price nothing gets built in your environment anyway. For the production build afterwards AWS is the cheapest route, because the database, point-in-time recovery, the spread across zones and the measurement are all there to be configured rather than built. Whoever still has to get there finds that route under AWS migration. Another platform or your own data centre works too, only the effort is a different one, which is why that is quoted separately.

How long does it really take?

A week to the result, counted from the day the access is in place. What it takes on your side is read access to one repository, or a new one where none exists yet, and one or two sessions with the people who build the platform. Where a grown system has to be understood first, you see that in the first conversation and not on the last day; from around 200,000 lines or several applications we agree the scope beforehand.

Other services

What else I help with.