Desi Stack
HomeHomeProjectsProjectsCoursesCoursesGamesGamesPricingPricingServicesServicesContactContact
Get Started

Desi Stack

Empowering developers with production-ready projects, comprehensive courses, and professional services. Learn, build, and launch your next big idea.

contact@desistack.com
India

Product

  • Projects
  • Courses
  • Services

Company

  • About
  • Contact
  • Blog

Resources

  • Course Materials
  • FAQs
  • Support

Legal

  • Privacy Policy
  • Refund Policy
  • Terms of Service
Follow our journey

© 2026 Desi Stack. Made with in India

Subscribe
All posts
postgresprismabackend

Postgres + Prisma Tips for Indie SaaS

Desi Stack19 Jul 20263 min read

Indie SaaS is mostly data discipline

Your marketing site can be beautiful. Your game hub can be cinematic. If Postgres and migrations are sloppy, launches still hurt.

This post is the checklist we wish every indie founder had before the first real user pays.

Two database URLs (and why both exist)

On Vercel-style serverless + Supabase you typically need:

Env varPort / modeUsed for
DATABASE_URLTransaction pooler (e.g. 6543 + pgbouncer=true)App queries at runtime
DIRECT_URLSession / direct (e.g. 5432)Prisma CLI migrations

Serverless functions should not hold persistent connections like a single long-running Node server. The pooler exists so thousands of short invocations do not open thousands of real Postgres sessions.

Prisma reads both from schema.prisma:

datasource db {
  provider  = "postgresql"
  url       = env("DATABASE_URL")
  directUrl = env("DIRECT_URL")
}

Rule: never run migrate dev against the pooled URL and expect happiness. Migrations need a real session.

Migration workflow that does not wreck prod

  1. Edit prisma/schema.prisma locally.
  2. npm run db:migrate — creates + applies migration on dev.
  3. Commit the migration folder.
  4. Deploy the app.
  5. npm run db:migrate:prod — deploy only, never invent migrations on production.

migrate dev is for designing history. migrate deploy is for applying history you already reviewed.

If teammates or CI create conflicting migrations, stop and rebase history carefully — do not “just push another fix migration” blindly on live data.

Indexes that matter early

You do not need to index everything. You do need indexes that match real queries:

  • Unique business keys: slug, email, payment provider ids
  • Hot filters: status + publishedAt, userId + createdAt
  • Join helpers that show up in slow query logs

For a blog, @@index([status, publishedAt]) is boring and correct. For orders, indexes on userId and Razorpay ids save support tickets.

Decimal, Date, and JSON gotchas

  • Decimal (prices) is not a JS number. Serialize with Number(...) (carefully) or strings when sending to the client.
  • Date becomes ISO strings across the RSC → client boundary — design types accordingly.
  • Json fields are flexible until you need to query inside them often. Prefer real columns for anything you filter on.

Seeding without lying to yourself

Seed scripts should:

  • Be idempotent (upsert by slug/id)
  • Run against an explicit dev|prod argument
  • Never hardcode production secrets in the repo
  • Leave optional media null if you will upload later in admin (exactly how our blog seed works)

Ops habits that prevent 2am pages

  1. prisma generate in build — cold deploys without a client are comic and sad.
  2. Connection limits — pooler URLs often need connection_limit=1 per serverless instance.
  3. Backups / point-in-time — turn them on before you need them.
  4. Read logs when migrate fails — “migration applied but client outdated” is a generate/deploy order problem.
  5. Test one write path in staging — create order, publish post, grant access — before announcing.

A minimal “am I ready?” checklist

  • Local migrate works
  • Prod migrate deploy is documented
  • DATABASE_URL and DIRECT_URL both set on Vercel
  • Critical unique constraints exist
  • Seed + admin path verified on a non-prod DB
  • You know how to roll forward (preferred) when a migrate fails mid-way

Closing

Postgres will not make your product for you. But a calm Prisma workflow will give you the confidence to ship features instead of fearing every schema change.

When you are ready to practice on a full product shape, grab a Desi Stack project and walk the migrations yourself — muscle memory beats screenshots.

Keep building

Related reads

Browse projects →

More posts coming soon.