PlanetScale Architecture
PlanetScale is MySQL-compatible database built on Vitess (used by YouTube, Slack, GitHub). It adds:
- Database branches: Like git, but for schemas
- Non-blocking schema changes: ALTER TABLE without locks
- Horizontal sharding: Auto-scale to millions of queries/sec
Branching Workflow
# Install PlanetScale CLI
brew install planetscale/tap/pscale
# Connect to branch
pscale shell myapp main
# Create development branch
pscale branch create myapp add-user-avatar
# Connect to branch
pscale connect myapp add-user-avatar --port 3309
# Make schema changes on branch
mysql -h 127.0.0.1 -P 3309 -u root myapp
ALTER TABLE users ADD COLUMN avatar_url VARCHAR(500);
CREATE INDEX idx_users_email ON users (email);
# Create deploy request (like a pull request)
pscale deploy-request create myapp add-user-avatar
# After review, deploy to main (non-blocking!)
pscale deploy-request deploy myapp 1
Connection in Node.js
import mysql2 from 'mysql2/promise'
const pool = mysql2.createPool({
host: process.env.DATABASE_HOST,
database: process.env.DATABASE_NAME,
username: process.env.DATABASE_USERNAME,
password: process.env.DATABASE_PASSWORD,
ssl: { rejectUnauthorized: true },
pool: {
min: 2,
max: 10,
acquireTimeout: 30000,
},
})
// Or use the PlanetScale serverless driver (edge-compatible)
import { connect } from '@planetscale/database'
const conn = connect({
host: process.env.DATABASE_HOST,
username: process.env.DATABASE_USERNAME,
password: process.env.DATABASE_PASSWORD,
})
const results = await conn.execute('SELECT * FROM users WHERE id = ?', [userId])
Vitess Limitations
Foreign keys are disabled in Vitess (use application-level integrity):
// Instead of foreign key constraint, validate in application
async function createPost(userId: string, title: string) {
// Check user exists
const user = await db.query('SELECT id FROM users WHERE id = ?', [userId])
if (!user.rows.length) throw new Error('User not found')
return db.query('INSERT INTO posts (user_id, title) VALUES (?, ?)', [userId, title])
}
Schema Changes in Production
PlanetScale uses Vitess's Online DDL:
-- These run online, no blocking
ALTER TABLE orders ADD COLUMN tracking_number VARCHAR(100);
ALTER TABLE products MODIFY COLUMN description TEXT;
CREATE INDEX idx_orders_date ON orders (created_at);
DROP INDEX idx_old_unused ON products;
Horizontal Sharding
-- Define a sharding key in schema
CREATE TABLE orders (
id BIGINT NOT NULL,
customer_id BIGINT NOT NULL, -- This becomes the shard key
amount DECIMAL(10,2),
PRIMARY KEY (customer_id, id) -- Customer ID in PK for co-location
) ENGINE=InnoDB;
Performance Numbers
PlanetScale/Vitess handles:
- 1.5 million QPS (YouTube in 2019)
- Unlimited horizontal scale
- Zero-downtime schema changes on tables with billions of rows