DEV Community

Chinna G
Chinna G

Posted on • Originally published at nevatrix.com

Next.js 15 + PostgreSQL + Razorpay — The Exact SaaS Tech Stack We Use for Indian Products in 2026

At Nevatrix, we have built SaaS products for clients in India, the USA and Canada over the past few years. After a lot of iteration, we have converged on a stack that works exceptionally well for Indian SaaS products specifically — with Razorpay for billing, Indian GST compliance and the need to run cost-efficiently on limited startup budgets.

Here is the exact stack, the reasoning behind each choice and the tradeoffs we accepted.

The Stack

Frontend: Next.js 15 (App Router)
Styling: Tailwind CSS v4
Auth: Clerk (or NextAuth v5 for budget-constrained projects)
Database: PostgreSQL (via Neon for serverless, or Supabase)
ORM: Prisma
Cache: Redis (Upstash for serverless)
Payments: Razorpay Subscriptions (India) + Stripe (international)
Email: Resend
File Storage: AWS S3 (or Cloudflare R2 for cheaper egress)
Hosting: Vercel (frontend + API routes) + Railway (long-running jobs)
Monitoring: Sentry + Posthog + Uptime Robot
CI/CD: GitHub Actions
Language: TypeScript (strict mode, no exceptions)
Why Next.js App Router over Pages Router

We migrated our last 3 projects from Pages Router to App Router and have not looked back. Server Components eliminate client-side data fetching boilerplate, layouts are finally a first-class concept and the loading.tsx / error.tsx convention is clean.

The one gotcha for Indian SaaS products: if you are using Razorpay's client-side checkout (the redirect flow), you need "use client" on that component. Razorpay's JS SDK is browser-only. Not a big deal once you know it.

Why PostgreSQL over MongoDB

Every SaaS product we initially started with MongoDB eventually migrated to PostgreSQL. SaaS data is fundamentally relational — users belong to organisations, organisations have subscriptions, subscriptions have invoices, invoices have line items. Trying to manage this in document collections gets messy fast.

PostgreSQL with Prisma gives you: type-safe queries, migrations as code, excellent multi-tenancy patterns (row-level security or schema-per-tenant) and a mature ecosystem.

For multi-tenancy specifically, we add tenant_id to every table and enforce it at the ORM layer:

// All queries automatically scoped to tenant
const getTenantPrisma = (tenantId: string) => {
return prisma.$extends({
query: {
$allModels: {
async findMany({ args, query }) {
args.where = { ...args.where, tenantId };
return query(args);
},
},
},
});
};
Razorpay Subscriptions — What Nobody Tells You

Razorpay is the right choice for Indian SaaS. GST-compliant invoices, UPI support, net banking, EMI — all handled. But there are a few things that tripped us up:

  1. Webhook reliability Razorpay webhooks occasionally arrive out of order or with delays. Always implement idempotent webhook handlers and store the raw payload before processing:

// Always store webhook first, then process
await db.webhookEvent.create({
data: {
provider: 'razorpay',
eventId: payload.event,
payload: JSON.stringify(payload),
processedAt: null,
}
});
// Then process asynchronously

  1. Subscription status sync
    Do not rely only on webhooks for subscription status. Run a daily cron that fetches subscription status from Razorpay API and reconciles with your database. Webhooks fail. Crons catch the gaps.

  2. GST on invoices
    Razorpay handles GST invoicing if you configure your GST number in the dashboard. But you also need to store GST details at the organisation level in your database for your own records and for the compliance report you will need to file every quarter.

Clerk vs NextAuth — When to Use Which

Use Clerk when:

You need multi-tenant org management out of the box
You want OAuth (Google, GitHub, LinkedIn) without building it
Your budget allows ₹3,000–₹8,000/month at scale
You want a hosted, maintained auth solution
Use NextAuth v5 when:

Budget is tight (it is free and open source)
You want full control over the auth flow
You are comfortable handling sessions, CSRF and token rotation yourself
For most funded SaaS products, Clerk is worth the cost. For bootstrapped MVPs under ₹5,00,000 budget, NextAuth.

The Folder Structure We Use

src/
app/
(auth)/ ← login, register, onboarding
(dashboard)/ ← authenticated app routes
(marketing)/ ← public pages, blog, pricing
api/ ← API routes
components/
ui/ ← shadcn/ui primitives
features/ ← feature-specific components
lib/
db.ts ← Prisma client singleton
razorpay.ts ← Razorpay client
auth.ts ← Clerk or NextAuth config
hooks/ ← custom React hooks
types/ ← TypeScript types
utils/ ← pure utility functions
The (marketing) / (dashboard) route group split is critical — it lets you have completely different layouts for public pages and authenticated app pages without any conditional rendering logic.

Deployment Cost for an Indian SaaS MVP

Vercel Pro: ₹1,700/month
Neon PostgreSQL: Free tier → $19/month after scale
Upstash Redis: Free tier → $10/month after scale
Clerk: Free up to 10,000 MAU
Resend: Free up to 3,000 emails/month
AWS S3: ~$5/month for typical MVP usage
Razorpay: 2% per transaction (no monthly fee)
Total at MVP stage: ~₹2,000–₹4,000/month
This is why building SaaS in India is exceptional — you can run a fully production-grade stack for under ₹5,000/month until you have real revenue.

What We Would Change

Honestly, not much. The only thing we debate internally is Prisma vs Drizzle. Drizzle is significantly faster for complex queries and the SQL-like API is cleaner. We are migrating our next project to Drizzle + Neon and will write up the experience.

If you are building a SaaS product in India and want to talk architecture, stack choices or just need a development partner — we are at nevatrix.com.

Rathan Babu — Founder, Nevatrix Technologies, Warangal, India

Top comments (0)