Tutorial 8 min read March 15, 2025

Why Next.js + PostgreSQL + Neon Is Still My Default Stack in 2026

After building 6 products across 4 industries, I keep coming back to the same foundation. Not because I stopped exploring — I didn't. Here's exactly why this stack keeps winning, and where I layer Redis, Docker, and AWS on top.

Umar Saleem

Umar Saleem

Full Stack AI Engineer & Founder

I've had this conversation a hundred times. Someone asks what stack they should use to build their SaaS, and after six years and a dozen products, my answer is almost always the same: Next.js, PostgreSQL, Neon. Not because I'm stuck in my ways. Because every time I've tried something else for a project, I've ended up missing this setup by the end of it.

What Makes a Stack "Default"

A default stack isn't the most exciting one. It's the one where you spend zero mental energy on infrastructure decisions and all of it on the actual product. The goal is to eliminate the "which tool should I use?" question so you can focus on what matters: shipping something people want to pay for.

Why Next.js Still Wins in 2026

Next.js 16 with React 19 is the most productive environment I've worked in. Server Components mean I write less data-fetching boilerplate than any other framework. Server Actions reduce form handling to a single async function. The image optimisation, font loading, and metadata APIs eliminate entire categories of tooling. And deployment — whether Vercel for simple projects or Docker on EC2 for complex ones — is frictionless.

  • Server Components eliminate API routes for read operations — data flows directly from DB to UI.
  • Server Actions handle mutations without boilerplate. No separate endpoint, no client-side fetch logic.
  • Built-in image optimisation and the fonts API removes entire categories of third-party tooling.
  • The ecosystem for TypeScript, Tailwind, and Drizzle integration is unmatched.

PostgreSQL: Boring Is a Feature

I spent two years with MongoDB. I liked the flexibility. I didn't like debugging inconsistent data at 2am because a schema change wasn't applied cleanly. Postgres has ACID guarantees, real joins, proper foreign key enforcement, full-text search built in, and JSONB columns for the rare times you genuinely need document-style flexibility. Every time I thought I needed a specialised database, I found a Postgres feature that solved the problem instead.

pg_trgm for fuzzy search. JSONB for flexible schema. LISTEN/NOTIFY for real-time. Postgres keeps making the "we need a different database" conversation unnecessary.

Neon: Serverless Postgres That Actually Works

Neon solved friction I didn't know I had. The free tier is genuinely usable for MVPs — no credit card, no artificial time limit. The branch-per-PR workflow is the best developer experience I've had around databases: spin up a clone of your production data for a feature branch, test against real schema, destroy it when the PR merges. Cold starts on the free tier stay under 500ms, which is acceptable for most apps.

typescript
// lib/db.ts — clean connection via Neon's serverless driver
import { neon } from '@neondatabase/serverless'

const sql = neon(process.env.DATABASE_URL!)

export async function getUserById(id: string) {
  const [user] = await sql`
    SELECT id, name, email, created_at
    FROM users
    WHERE id = ${id}
    LIMIT 1
  `
  return user ?? null
}

// For complex queries with joins, raw SQL is cleaner than ORM abstractions
export async function getRecentActivity(userId: string, limit = 20) {
  return sql`
    SELECT a.*, u.name as actor_name
    FROM activity_log a
    JOIN users u ON u.id = a.actor_id
    WHERE a.user_id = ${userId}
    ORDER BY a.created_at DESC
    LIMIT ${limit}
  `
}

When I Reach for Redis

Redis enters the picture when I need sub-millisecond access — rate limiting, session storage, presence tracking — or a lightweight job queue for background tasks like sending emails or processing webhooks. For most MVPs, Postgres handles caching needs well enough. I use Upstash for serverless deployments so there's no Redis server to provision or babysit.

Docker and AWS for Production

When a project outgrows what Vercel can offer — usually because of WebSockets, long-running processes, or a client who needs dedicated infrastructure — I move to Docker on AWS EC2, S3 for file storage, CloudFront as CDN, and Lambda for async jobs. This combination has scaled reliably from 100 to 100,000 users without a meaningful architecture change across three different client projects.

The Full Stack at a Glance (2026 Edition)

  • Frontend + API: Next.js 16, App Router, React 19
  • Database: PostgreSQL via Neon (MVPs) or self-hosted on EC2 with PgBouncer
  • ORM: Drizzle for type-safe queries, raw SQL for anything complex
  • Auth: Clerk or Better Auth — never roll your own session management
  • Payments: Stripe, no serious alternatives
  • Email: Resend with React Email — feels exactly like building components
  • File storage: AWS S3 with CloudFront
  • Background jobs: AWS Lambda or Inngest for event-driven workflows
  • AI: Anthropic Claude or OpenAI depending on the task
  • Deployment: Vercel for simplicity, Docker on EC2 when you need real infrastructure

The goal isn't to use whatever dropped on Hacker News last week. It's to have a stack so familiar that you ship fast, debug confidently, and never second-guess your tools. After six years, this one still does that better than anything else I've tried.

Enjoyed this?

Let's build something together.

If you need help applying any of this to your product, I'm available for consulting and development work.

Book a Call