Back to Blog

Neon vs PlanetScale: Serverless MySQL vs Postgres

JayJay

Neon and PlanetScale both pioneered serverless database features like branching and scale-to-zero. But they're built on different foundations: Neon on PostgreSQL, PlanetScale on MySQL (via Vitess). Your choice of database often matters more than the platform features.

The Core Difference

Neon is serverless PostgreSQL with innovative architecture:

  • Separates compute from storage
  • Scale-to-zero (stop paying when idle)
  • Instant database branching
  • Standard PostgreSQL wire protocol

PlanetScale is serverless MySQL built on Vitess:

  • Designed for horizontal scale
  • Database branching via deploy requests
  • Non-blocking schema changes
  • MySQL-compatible (with limitations)

Database: PostgreSQL vs MySQL

This is the fundamental decision. The platform features matter less than which database you want.

PostgreSQL (Neon)

SQL
-- Full PostgreSQL features
CREATE TABLE orders (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id UUID REFERENCES users(id) ON DELETE CASCADE,
  items JSONB NOT NULL,
  total DECIMAL(10,2) GENERATED ALWAYS AS (
    (SELECT SUM((item->>'price')::decimal * (item->>'quantity')::int)
     FROM jsonb_array_elements(items) AS item)
  ) STORED,
  created_at TIMESTAMPTZ DEFAULT NOW()
);

-- CTEs, window functions, full JSON support
WITH monthly_sales AS (
  SELECT DATE_TRUNC('month', created_at) AS month, SUM(total) AS revenue
  FROM orders
  GROUP BY 1
)
SELECT month, revenue,
       revenue - LAG(revenue) OVER (ORDER BY month) AS growth
FROM monthly_sales;

You get: foreign keys, advanced JSON operations, CTEs, window functions, extensions (PostGIS, pgvector, etc.).

MySQL via Vitess (PlanetScale)

SQL
-- MySQL-compatible, but no foreign keys
CREATE TABLE orders (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  user_id BIGINT NOT NULL,  -- No REFERENCES, enforced by app
  items JSON NOT NULL,
  total DECIMAL(10,2) NOT NULL,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- MySQL syntax
SELECT DATE_FORMAT(created_at, '%Y-%m') AS month, SUM(total) AS revenue
FROM orders
GROUP BY month;

You get: MySQL compatibility, horizontal sharding capability, familiar syntax if you know MySQL.

You don't get: foreign key constraints (intentional design choice for sharding).

Branching Features

Both platforms offer database branching, but the workflows differ.

Neon Branching

Neon uses copy-on-write architecture. Branches are instant and storage-efficient:

BASH
# Create a branch (instant, regardless of database size)
neon branches create --name feature-x --parent main

# Get connection string
neon connection-string feature-x
# postgres://user:pass@feature-x.neon.tech/db

# Branch has full copy of data
# Uses copy-on-write, so minimal storage overhead

Branches are cheap. Create one for every PR, every developer, every experiment.

PlanetScale Branching

PlanetScale uses a deploy request workflow:

BASH
# Create a development branch
pscale branch create mydb feature-x

# Connect and make schema changes
pscale shell mydb feature-x
> ALTER TABLE users ADD COLUMN phone VARCHAR(20);

# Create deploy request (like a PR)
pscale deploy-request create mydb feature-x --to main

# Review and deploy (non-blocking)
pscale deploy-request deploy mydb feature-x

Deploy requests include schema diff review and deploy non-blocking migrations. More structured workflow, especially valuable for schema changes.

Scale-to-Zero

Neon

Neon suspends compute after inactivity:

  • Default: 5 minutes of no queries
  • Compute stops, storage persists
  • Cold start: ~500ms
  • Only pay for active compute time
JAVASCRIPT
// First query after idle: ~500ms
// Subsequent queries: normal latency
const result = await pool.query('SELECT * FROM users');

Excellent for dev environments, side projects, and variable workloads.

PlanetScale

PlanetScale's Scaler plan is always-on. No scale-to-zero on current plans.

For development, you'd create separate branches that you can delete when not needed, but you're paying for the base plan regardless.

Pricing Comparison

Neon:

  • Free: 0.5 GB storage, 191 compute hours/month
  • Pro ($19/month): 10 GB storage, 300 compute hours
  • Scale-to-zero on all plans
  • Branching included

PlanetScale:

  • No free tier (removed March 2024)
  • Scaler ($39/month): 10 GB storage, 100M row reads
  • Pay for reads, writes, storage
  • Branching included

Neon is significantly cheaper for:

  • Side projects (free tier)
  • Variable workloads (scale-to-zero)
  • Development databases (cheap branches)

PlanetScale's pricing favors consistent production workloads where the MySQL ecosystem matters.

Connection Handling

Both handle serverless connections well.

Neon uses a connection proxy:

JAVASCRIPT
import { Pool } from 'pg';

// Standard pg, Neon proxy handles pooling
const pool = new Pool({
  connectionString: process.env.DATABASE_URL,
});

PlanetScale uses their proxy with connection strings that handle pooling:

JAVASCRIPT
import mysql from 'mysql2/promise';

// Standard mysql2, PlanetScale handles pooling
const connection = await mysql.createConnection(process.env.DATABASE_URL);

Both work well with serverless functions (Vercel, Netlify, Cloudflare Workers).

Developer Experience

Neon

  • Clean, focused dashboard
  • CLI for branching workflows
  • Standard PostgreSQL. Any PostgreSQL tool works
  • Integrations: Vercel, GitHub, etc.

PlanetScale

  • Full-featured dashboard with schema viewer
  • CLI for branch and deploy workflow
  • MySQL Workbench and other MySQL tools work
  • Integrations: Vercel, Netlify, etc.

Both have good developer experience. PlanetScale's schema diff and deploy request UI is more sophisticated. Neon's branching is faster and cheaper.

Limitations

Neon Limitations

  • PostgreSQL only (no MySQL option)
  • Cold starts after idle (500ms)
  • Some extensions not available
  • Newer platform (less battle-tested at extreme scale)

PlanetScale Limitations

  • No foreign key constraints
  • MySQL only (no PostgreSQL option)
  • No free tier
  • Some MySQL features unavailable (Vitess limitations)
  • Triggers and stored procedures have restrictions

The foreign key limitation is significant. If you rely on database-enforced referential integrity, PlanetScale isn't the right choice.

When to Choose Neon

PostgreSQL preference:

  • Team knows PostgreSQL
  • Need foreign keys
  • Want full SQL standard support
  • Using PostgreSQL-specific features (extensions, JSON operations)

Cost sensitivity:

  • Side projects on free tier
  • Development environments
  • Variable/spiky workloads

Branching-heavy workflows:

  • Preview environments for every PR
  • Many developers with isolated databases
  • Frequent experimentation

When to Choose PlanetScale

MySQL requirement:

  • Existing MySQL application
  • MySQL expertise on team
  • MySQL-specific tooling

Schema management focus:

  • Frequent schema changes
  • Need non-blocking migrations
  • Want structured deploy request workflow

Horizontal scaling:

  • Anticipate massive scale
  • Need Vitess's sharding capabilities
  • Building for Instagram-scale problems

Migration Considerations

Moving between these platforms means changing databases (PostgreSQL ↔ MySQL), not just platforms. This is a significant undertaking:

  • Data type differences
  • Syntax changes
  • Feature differences (foreign keys, JSON handling, etc.)
  • ORM/application code changes

Don't choose based on platform features alone. Choose based on which database you want long-term.

The Bottom Line

If you prefer PostgreSQL: Neon is the better choice. Free tier, scale-to-zero, instant branching, full PostgreSQL features.

If you need MySQL: PlanetScale is the better choice (and one of few serverless MySQL options). Deploy request workflow is excellent for team schema management.

The database matters more than the platform. Both Neon and PlanetScale are well-engineered, but PostgreSQL vs MySQL is the fundamental decision.

For most new projects without a MySQL requirement, Neon's combination of features and pricing is hard to beat. PostgreSQL is arguably the better database, the free tier is generous, and scale-to-zero saves real money on variable workloads.

Keep Reading