Home > Blog > The Modern SaaS Tech Stack: What We Chose for Our Own Products

The Modern SaaS Tech Stack: What We Chose for Our Own Products

Sat, 04.10.2025
Thu, 30.07.2026
Illustration of six SaaS tech stack layers stacked vertically, with the multi-tenancy layer highlighted and a price tag on infrastructure

Almost every article about SaaS tech stacks is a list of options. React or Vue. Node or Python. Postgres or Mongo. They are all technically correct and none of them help, because the hard part was never knowing that React exists. The hard part is committing to one combination and then living with it.

So this is not a list. We have spent over a decade building SaaS and custom software for clients, which is where most of our scar tissue comes from. We also run our own products — LiftUp, an operations platform; PocketGST, a GST compliance app for Indian businesses; URLCrop, link management; and Emplyft for HR operations. Those are the ones where we pay the bills ourselves, which changes how carefully you choose.

What follows is the stack we picked for LiftUp, the reasoning behind each decision, the two we are least sure about, and a framework for choosing your own. One thing to be upfront about: LiftUp is three months old. This is not a five-year retrospective, and anyone offering you one on a stack decision made this year is inventing it. It is a set of live decisions, made deliberately, with the reasoning intact. If you are about to make the same choices, that is probably more useful than hindsight anyway.

If you want the framework and not our opinions, skip to the last two sections.

What a SaaS Tech Stack Actually Includes

Most definitions stop at “frontend and backend,” which is where the trouble starts. That framing was accurate in 2010. A SaaS product has six layers that each need a decision, and the ones people forget are the ones that hurt later.

1. Frontend. What the user sees and clicks. A framework, a styling approach, a build tool.

2. Backend. Business logic, authentication, APIs, background jobs.

3. Data. The primary database, plus whatever you add for caching, search, and queues.

4. Tenancy. How one deployment keeps one customer’s data separate from another’s. Not optional in SaaS, and not something you bolt on.

5. Billing. Subscriptions, plan changes, proration, failed payments, tax. Harder than it looks in every jurisdiction, and much harder in some.

6. Infrastructure. Where it runs, how it deploys, how you find out when it breaks.

Two things are not part of your tech stack, despite showing up in a lot of articles on this topic. Your office internet connection is an operational expense, not architecture — your users reach your product over their own connection, and no amount of bandwidth at your end changes their experience. And your team’s laptops and design tools are procurement. Useful, not architectural. If a stack article is padding the list with these, it is padding.

The distinction matters because layers 4 and 5 — tenancy and billing — are what make a SaaS stack different from a general web application stack, and they are the two most likely to be missing from a generic comparison.

The Stack We Chose for LiftUp

LiftUp is a multi-tenant operations platform. The CRM is live; the blog CMS, AI-assisted editorial tooling, and analytics are in build. It runs on Laravel, serves tenants from a single deployment, and costs nine dollars a month to host.

Here is each decision and why we made it.

Backend: Laravel

Laravel on PHP. Not the fashionable answer, and we would choose it again tomorrow.

The reasoning is unglamorous: Laravel ships with what a SaaS needs on day one. Authentication, queues, task scheduling, mail, migrations, an ORM, policy-based authorisation, and a testing setup are all in the box and designed to work together. On Node you assemble that from packages and then you maintain the assembly. For a small team, “already decided” is worth more than “more flexible.”

It also matters that this is what our team is fastest in. We build client work in Laravel constantly, so choosing it for our own product meant no learning curve and no second toolchain to keep current. That is not a technical argument. It is the correct argument anyway, and we will come back to it.

The honest tradeoff: PHP’s hiring pool skews toward people who learned it in a WordPress or CodeIgniter context, and the gap between that and modern Laravel is real. We spend onboarding time on it. If your differentiator is streaming, heavy websockets, or CPU-bound work, Node or Go is the better fit and we would tell you so.

Frontend: server-rendered, not a single-page app

This is the decision most teams get wrong, and the one we would defend hardest.

LiftUp renders on the server with Blade, using Alpine.js for interactivity and Laravel Reverb for the live pieces. There is no React SPA in front of it.

An SPA gives you two applications instead of one: a frontend with its own routing, state management, build pipeline, and deployment, talking to a backend over an API you now have to design and version. For a product with genuinely app-like interaction — a canvas, a spreadsheet, a collaborative editor — that cost buys something real. For a product that is mostly forms, tables, and dashboards, which describes most B2B SaaS honestly, it buys you a second codebase and a slower feature cycle.

We reach for React or Next.js when the interaction model demands it, and we use Next.js for marketing sites where server rendering helps indexing. For a CRM — records, lists, forms, filters — server-rendered HTML with sprinkles of interactivity ships faster and breaks less.

If you are building a SaaS MVP and reaching for an SPA by default, that default is worth examining. It is the most common source of avoidable complexity we see in early-stage products.

Data: relational, decided early

A relational database. The argument between MySQL and PostgreSQL generates more heat than it deserves — both will outlast your product.

What matters more: pick relational unless you have a specific reason not to. SaaS data is relational. Tenants have users, users have records, records have history. Document stores are excellent for genuinely schema-less data and expensive when you eventually need a join across three collections plus a consistency guarantee you never designed for.

Postgres is where we lean for anything new. JSONB gives you document-style flexibility inside a relational database, which covers most of what people reach for MongoDB to solve, and its concurrent-write behaviour holds up better under load.

Tenancy: the decision you cannot reverse

Multi-tenancy is what separates SaaS architecture from ordinary web architecture, and it is the one decision here you genuinely cannot defer.

There are three shapes.

Shared schema with a tenant column. Every table carries a tenant_id, every query filters on it. Cheapest to run, simplest to deploy — and one missing where clause leaks one customer’s data to another. You mitigate that with scoping enforced at the model layer rather than trusted to each developer on each query.

Schema per tenant. One database, one schema per customer. Better isolation and straightforward per-tenant backup and restore. Migrations become a loop over N schemas that gets slower every time you sign a customer.

Database per tenant. Strongest isolation, easiest compliance story, most operational overhead. Usually where you end up selling to enterprises with data residency requirements.

We run shared schema with enforced scoping, which is the right default for most products at most sizes. But the important part is not which one you pick. It is that retrofitting tenancy into a single-tenant schema is close to a rewrite — every query, every relationship, every background job, every export. If there is any chance your product serves multiple customers from one deployment, build the tenant boundary while the schema is still empty. It costs almost nothing on day one.

Billing: Razorpay first, and why the order matters

LiftUp bills through Razorpay. One processor, not two, and that was a deliberate sequencing decision rather than an oversight.

We sell into India first. That makes Razorpay the obvious starting point, and the reasons are specific rather than patriotic:

  • It handles Indian payment methods properly — UPI, netbanking, local cards. A processor that does not support UPI is not a serious option for Indian B2B, whatever else it does well.
  • Recurring mandates in India have their own rules. The RBI framework around e-mandates and additional factor authentication for recurring payments is genuinely fiddly, and a processor built for it saves you from implementing that understanding yourself.
  • Settlement and reconciliation happen in INR without a currency conversion sitting between your revenue and your bank.

Stripe is the better product in most other respects — its subscription handling, proration, dunning, and tax tooling are the best available. When we sell internationally in volume, we will add it. We have not yet, because adding a second processor before you have customers in a second currency is work that buys nothing.

The part worth taking from this, if you are in a similar position: decide now whether a second processor is ever likely, and if it is, put the interface in before you need it. A thin PaymentGateway abstraction with one implementation behind it costs maybe a day while your billing code is small. Adding it later means unpicking processor-specific assumptions from subscription logic that has grown around them, and that is a different order of work entirely. We know which side of that we are on and it is on the roadmap rather than in the codebase, which is an honest place to be and not a comfortable one.

One thing that is not optional regardless of processor count: webhooks are your source of truth, not the response to your API call. Payments succeed and fail asynchronously, and you will receive the same event twice. Every billing state change should be driven by a verified webhook, handled idempotently.

Infrastructure: Hetzner, nine dollars a month

LiftUp runs on a Hetzner VPS, separate from the box serving our other properties, with nginx terminating TLS in front of it. Application, database, and background workers on one instance. Not a managed platform. Nine dollars a month.

Hetzner has been the price/performance answer in European hosting for years, and the honest 2026 version of that story is more complicated. There were two increases this year. On 1 April the whole cloud lineup rose by up to 37%, and that one applied to existing customers. On 15 June the dedicated and AMD shared vCPU families were repriced far harder — CPX up roughly 144–176%, CCX up 113–169%. A CCX13 went from €15.99 to €42.99 a month, putting it at rough parity with an equivalent DigitalOcean droplet and removing most of the reason you would have picked it on price.

Two things matter if you are running there or considering it:

The cost-optimised lines are still genuinely cheap. The Intel-shared CX and ARM-based CAX families rose about 30–38%, not 150%, and sit around €5.50–6.00 for 2 vCPU and 4 GB. For a SaaS application that is not CPU-bound, shared vCPU is fine. The 20 TB of included European traffic is a real advantage over providers who meter it much lower.

Existing servers keep their old pricing — until you rescale. A rescale reprices you at current rates. That is an unpleasant trap, because the natural response to growing load is to bump the instance size, and doing that can multiply your bill by more than the resources you gained. If you are on a grandfathered price, price the new tier before you click.

The broader lesson is not about Hetzner. It is that cheap infrastructure is a rented advantage, not a structural one. Two increases in ten weeks from a provider whose entire pitch was price predictability is a reminder to keep your deployment portable enough that moving is a project rather than a rewrite. Ours is nginx, a process manager, and a database — deliberately boring, deliberately movable.

Managed platform or your own server?

Worth stating plainly, because we would not give every client the answer we gave ourselves.

A managed platform — Render, Railway, Fly.io, or a PaaS on one of the big clouds — costs more per month and removes a category of work: provisioning, patching, TLS renewal, monitoring setup. When you are pre-revenue and your own time is the scarce resource, that is a good trade and you should take it.

We run our own because we have people comfortable with servers and because we operate several products, so the fixed cost of knowing how spreads across all of them. If you are one founder with one product, pay for the managed platform and spend the saved evenings on the product. We say the same in our cloud work.

What it costs to run

Nine dollars a month for compute.

That is the real figure for the instance LiftUp runs on — application, database, and workers on one box. We mention it because the gap between that and what people assume is enormous. Ask a founder to guess the hosting bill for a multi-tenant SaaS platform and you will hear hundreds, sometimes thousands. That assumption comes from a decade of AWS-first advice, where the same workload genuinely does cost that much once assembled from managed services.

Two caveats before anyone treats nine dollars as a target:

That is compute, not total infrastructure. Running the database on the same instance is normal and fine at this scale — you do not need a separate managed database until you have a reason, and “it feels more professional” is not a reason. But domains, transactional email, object storage, monitoring, and backups all sit on top, and together they exceed it.

It scales in steps, not smoothly. At some point one box is not enough, you separate the database, add a second application instance, and put something in front of them. That jump is not gradual. Budget for the step rather than extrapolating the line.

The four costs that actually hurt, none of which are servers:

  • Transactional email at volume. Free tiers end around a few thousand sends a month. A SaaS sending notifications, digests, invoices, and password resets crosses that quietly, and then it is a real monthly number.
  • Object storage egress, not storage. Keeping files is cheap. Serving them repeatedly is where the bill appears, and it scales with how much people use your product rather than how much data you hold.
  • Per-seat developer tooling. Error tracking, CI minutes, monitoring, design tools. Individually trivial. Collectively significant by the time the team is ten people, and every one is a subscription that never ends.
  • Payment processing percentage. Irrelevant at $500 of monthly revenue. Your largest infrastructure-adjacent cost at $50,000.

Model those four at projected scale. Model servers last.

Frontend: Choosing Between React, Vue, and Server-Rendered

Since the frontend question generates more argument than any other, here is the decision compressed.

ApproachUse whenCost
Server-rendered (Blade, Rails views, Django templates) plus light JSForms, tables, dashboards, CRUD-heavy B2B toolsAwkward for genuinely app-like interaction
React or Vue SPAReal-time collaborative editing, canvases, complex client-side stateTwo codebases, an API contract, a build pipeline
Next.js or NuxtSEO on public pages and app-like interaction behind loginMost moving parts; server rendering plus hydration complexity

React has the largest hiring pool, which is a real argument if you plan to grow the team. Vue is often pleasanter for a small team with a shallower learning curve. TypeScript is worth adopting on either from the first commit rather than migrating to later.

For styling, Tailwind CSS has effectively won for product interfaces, and the reason is maintenance rather than aesthetics: it removes the question of where a style lives.

Backend: What “Commercial Backend” Actually Means

People search for what a commercial backend for a SaaS company involves, and the honest answer is less about language and more about a set of capabilities you will definitely need:

  • Authentication and authorisation, including roles, and eventually SSO if you sell to larger companies
  • Background job processing — anything slow moves off the request cycle. Report generation, imports, email sending, third-party API calls
  • A scheduler for recurring work: billing cycles, digest emails, cleanup
  • An API layer, because someone will want to integrate with you
  • Audit logging, which enterprise buyers ask for and which you cannot reconstruct retroactively
  • Rate limiting, before someone finds your public endpoints rather than after

Laravel gives you most of that in the framework. Node with NestJS gives you a structured way to build it. Django gives you a strong admin and ORM. Rails gives you conventions that keep a small team consistent. All four are correct answers, and the right one is the one your team can maintain at 2am.

The pattern worth internalising: across our REST API work, the difference between a backend that scales and one that does not is rarely the framework. It is whether slow work was moved to queues early.

Stacks by SaaS Type

The right stack differs by what you are building far more than by what is trending.

TypeSensible defaultWhy
Micro-SaaS (solo, one narrow job)Laravel or Rails, server-rendered, managed hosting, one payment processorOptimise for shipping alone. Every extra layer is a layer you maintain alone.
B2B SaaS (teams, seats, admin)Laravel or Django, server-rendered app, Postgres, shared-schema tenancy, SSO on the roadmapRoles and permissions dominate. Real-time rarely does.
Startup MVP (validating)Whatever your team already knows, managed hosting, ship in weeksThe stack that gets you to feedback fastest wins. You may throw it away, and that is fine.
Real-time collaborativeNode or Elixir, websockets first-class, React or Vue frontendThe concurrency model is the whole product.
Data or analytics heavyPython backend, Postgres plus a columnar store, queue-based ingestionEcosystem gravity. Fighting it costs more than it saves.
Enterprise-facingAdd audit logs, SSO, database-per-tenant, compliance groundworkProcurement will ask. Retrofitting is expensive.

How to Choose Your Own: Four Questions

If you take nothing else from this, take these four, in this order.

1. What does your team already know?

The most under-weighted factor in every stack discussion. A team shipping confidently in a five-year-old framework will beat a team learning the current favourite, every time, for at least the first year. Novelty has a cost and it is paid in bugs.

This is genuinely why LiftUp is a Laravel application. We are fast in it. That reason is less interesting than a benchmark and considerably more predictive of whether a product ships.

Only override it when the mismatch is structural — a real-time product on a stack with no real-time story, for instance. “It would be interesting to learn” is not a structural mismatch.

2. What does the product actually have to do?

Write down the three hardest technical requirements before naming a single technology. Not features — requirements. “Must handle 500 concurrent websocket connections.” “Must generate PDFs from templated data in under two seconds.” “Must isolate customer data at the database level for a compliance audit.”

Those three sentences eliminate more options than any comparison table. Most stack debates happen because nobody wrote them down.

3. What happens when it grows?

Not “will it scale,” which has no useful answer. Specifically: which decision here is hardest to reverse?

Frontend framework — annoying to change, entirely possible. Backend framework — expensive, done regularly. Database engine — painful. Tenancy model — effectively a rewrite. Spend your deliberation proportional to reversibility, and spend most of it on tenancy.

4. What will it cost in year three?

Not month one. Year three, at ten times the customers.

Per-seat tooling that is free for three developers and painful for fifteen. Managed database pricing that steps at a threshold you will cross. Object storage where egress, not storage, becomes the bill. A payment processor whose percentage matters once revenue is real. A hosting provider that raises prices twice in ten weeks.

Run the numbers at projected scale, not current scale. Our development cost calculator covers the build side; the ongoing side is worth modelling in a spreadsheet you keep.

The Two Decisions We Are Least Sure About

LiftUp is three months old, so what follows is not a retrospective. It is the two places we expect to be tested, written down now so we cannot pretend later that we saw it coming.

The billing abstraction we have not built. We are on one processor with no gateway interface in front of it. That is the right call today and it becomes the wrong call the moment we sell internationally in volume. We know the shape of that work and we have chosen to defer it, which is different from not having thought about it — but it is still a bet that we will get to it before the subscription logic has grown around Razorpay-shaped assumptions. Ask us in a year.

Shared-schema tenancy under enterprise scrutiny. Shared schema with enforced scoping is the right default and we would recommend it to most clients. It is also the shape that gets hardest questions from buyers with compliance requirements, and the migration path to schema-per-tenant is real work. We built the tenant boundary properly on day one specifically so that migration stays possible, which is the mitigation rather than the solution.

What we are not uncertain about: Laravel, server-rendered over an SPA, and relational over document. Three months in, those three have needed no revisiting, and the deeper reason is that they are all decisions our team was already good at executing.

Final Thoughts

The stack that kills a SaaS product is almost never the one that benchmarked slightly slower. It is the one nobody on the team wanted to work in, or the one where a decision made in week two — usually about tenancy — turned into a rewrite in year two.

So: pick something your team can maintain. Decide tenancy before you write a line of schema. Put an abstraction in front of payments if you will ever cross a border, and know which side of that line you are on. Move slow work to queues early. Then stop reading comparison articles and go build the thing, because your stack matters considerably less than whether anyone wants what you are making.

We design and build SaaS products for clients and we run our own, so these tradeoffs are ones we live with rather than recommend from a distance. If you want a straight opinion on a stack you are considering — or a review of one you have already committed to — tell us what you are building.

Related reading:
Cloud-First, Fail-Less: How Smart Startups Build Scalable Infrastructure · Harnessing Node.js for Scalable and Fast Web Development · Custom Software Development for Startups

Abidhusain Chidi, CEO and Founder of QalbIT Infotech Pvt Ltd, wearing a white shirt and glasses, facing forward with a confident and focused expression.
Abidhusain Chidi

Leading QalbIT Infotech Pvt Ltd, he brings over a decade of expertise in web, mobile, and cloud technologies, driving digital success for startups and businesses. His strategic approach to SaaS, PaaS, and BaaS solutions delivers innovative, scalable results tailored to client needs.

  • SaaS Development
  • Tech Stack

Frequently asked questions