Planetscale
Build with PlanetScale as a serverless MySQL database. Use this skill when the
You are a database specialist who integrates PlanetScale into projects. PlanetScale
is a serverless MySQL platform powered by Vitess, offering database branching,
non-blocking schema changes, and horizontal scaling.
## Key Points
- Use deploy requests for all production schema changes
- Use branching for development — one branch per feature
- Enforce referential integrity in application code (or use Prisma's relation mode)
- Use the serverless driver for edge/serverless, mysql2 for long-lived servers
- Add indexes for every query pattern — check the Insights tab for slow queries
- Use connection pooling in serverless environments
- Relying on foreign key constraints for data integrity — use application-level checks
- Running ALTER TABLE directly on production — use deploy requests
- Not using parameterized queries — SQL injection risk
- Creating too many branches without cleanup — they consume storage
- Using `SELECT *` on large tables without LIMIT
- Not monitoring the Insights dashboard for query performance
## Quick Example
```bash
npm install @planetscale/database
# Or with Drizzle
npm install @planetscale/database drizzle-orm
```
```prisma
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
relationMode = "prisma" // Required — PlanetScale doesn't enforce FK constraints
}
```skilldb get database-services-skills/PlanetscaleFull skill: 156 linesPlanetScale Serverless MySQL Integration
You are a database specialist who integrates PlanetScale into projects. PlanetScale is a serverless MySQL platform powered by Vitess, offering database branching, non-blocking schema changes, and horizontal scaling.
Core Philosophy
MySQL with branching
PlanetScale brings git-like branching to MySQL. Schema changes happen on branches and get reviewed via deploy requests before merging to production — no downtime, no locking.
Non-blocking schema changes
Schema migrations in PlanetScale never lock tables. The platform handles online DDL behind the scenes using Vitess's VReplication. You can alter massive tables without affecting production traffic.
No foreign keys (by design)
PlanetScale uses Vitess for sharding, and Vitess doesn't support foreign key constraints across shards. Enforce referential integrity in your application layer or use the recently added foreign key support in non-sharded keyspaces.
Setup
Install
npm install @planetscale/database
# Or with Drizzle
npm install @planetscale/database drizzle-orm
Connect (serverless driver)
import { connect } from '@planetscale/database';
const conn = connect({
url: process.env.DATABASE_URL,
});
const results = await conn.execute('SELECT * FROM posts WHERE status = ?', ['published']);
With Drizzle ORM
import { connect } from '@planetscale/database';
import { drizzle } from 'drizzle-orm/planetscale-serverless';
import * as schema from './schema';
const connection = connect({ url: process.env.DATABASE_URL });
const db = drizzle(connection, { schema });
With Prisma
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
relationMode = "prisma" // Required — PlanetScale doesn't enforce FK constraints
}
Key Techniques
Queries
import { connect } from '@planetscale/database';
const conn = connect({ url: process.env.DATABASE_URL });
// Select
const { rows } = await conn.execute(
'SELECT p.*, u.name as author_name FROM posts p JOIN users u ON p.author_id = u.id WHERE p.status = ? ORDER BY p.created_at DESC LIMIT ?',
['published', 20]
);
// Insert
const { insertId } = await conn.execute(
'INSERT INTO posts (title, content, author_id, status) VALUES (?, ?, ?, ?)',
['Hello', '...', userId, 'draft']
);
// Update
await conn.execute(
'UPDATE posts SET title = ?, updated_at = NOW() WHERE id = ?',
['Updated', postId]
);
// Delete
await conn.execute('DELETE FROM posts WHERE id = ?', [postId]);
// Transaction
const tx = conn.transaction(async (tx) => {
await tx.execute('UPDATE posts SET status = ? WHERE id = ?', ['published', postId]);
await tx.execute('INSERT INTO notifications (user_id, type) VALUES (?, ?)', [userId, 'published']);
});
Branching workflow
# Create a development branch
pscale branch create mydb feature-add-tags
# Connect to branch for local development
pscale connect mydb feature-add-tags --port 3309
# Apply schema changes on the branch
mysql -h 127.0.0.1 -P 3309 -u root < migration.sql
# Create a deploy request (like a PR for schema changes)
pscale deploy-request create mydb feature-add-tags
# Deploy to production (non-blocking)
pscale deploy-request deploy mydb 1
Safe schema changes
-- These run without locking tables in PlanetScale:
ALTER TABLE posts ADD COLUMN tags JSON;
ALTER TABLE posts ADD INDEX idx_status_created (status, created_at);
ALTER TABLE users MODIFY COLUMN name VARCHAR(500);
CREATE TABLE comments (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
post_id BIGINT NOT NULL,
body TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
Best Practices
- Use deploy requests for all production schema changes
- Use branching for development — one branch per feature
- Enforce referential integrity in application code (or use Prisma's relation mode)
- Use the serverless driver for edge/serverless, mysql2 for long-lived servers
- Add indexes for every query pattern — check the Insights tab for slow queries
- Use connection pooling in serverless environments
Anti-Patterns
- Relying on foreign key constraints for data integrity — use application-level checks
- Running ALTER TABLE directly on production — use deploy requests
- Not using parameterized queries — SQL injection risk
- Creating too many branches without cleanup — they consume storage
- Using
SELECT *on large tables without LIMIT - Not monitoring the Insights dashboard for query performance
Install this skill directly: skilldb add database-services-skills
Related Skills
Cassandra
Build with Apache Cassandra for high-availability distributed data. Use this skill
Clickhouse
Build with ClickHouse for real-time analytics and OLAP workloads. Use this skill
Cockroachdb
Build with CockroachDB as a distributed SQL database. Use this skill when the
Convex
Build with Convex as a reactive backend. Use this skill when the project needs
Drizzle
Use Drizzle ORM for type-safe SQL in TypeScript. Use this skill when the project
Dynamodb
Build with Amazon DynamoDB as a serverless NoSQL database. Use this skill when