Rank #4 of 5 in Serverless & Developer Databases
Install
brew install planetscale/tap/pscaleShowcase


Try itExperimental
See what an agent can do with PlanetScale before you ever sign up. Pick a story: recorded sessions replay real probe-harness transcripts; sandboxed self-drive sessions are designed and gated (docs/TRY-IT.md).
$pscale --skillrecorded session — replayed, not liveVerified integrations
Connections to other tracked products — hover a chip for the verbatim evidence quote behind it.
By theme — the product's score on each story themeBy theme
Agent workflows — stories about agent workflows in this arenaAgent workflowsevidence →
Stories about agent workflows in this arena
Agenticness — how well agents can access and operate the productAgenticnessevidence →
How well agents can access and operate the product
Automation depth — how much of the product can run unattendedAutomation depthevidence →
How much of the product can run unattended
Branching workflows — stories about branching workflows in this arenaBranching workflowsevidence →
Stories about branching workflows in this arena
Connectivity pooling — stories about connectivity pooling in this arenaConnectivity poolingevidence →
Stories about connectivity pooling in this arena
Data capabilities — stories about data capabilities in this arenaData capabilitiesevidence →
Stories about data capabilities in this arena
Local dev — stories about local dev in this arenaLocal devevidence →
Stories about local dev in this arena
Migrations schema — stories about migrations schema in this arenaMigrations schemaevidence →
Stories about migrations schema in this arena
Openness — open source, data portability, and self-hosting storiesOpennessevidence →
Open source, data portability, and self-hosting stories
Operations insights — stories about operations insights in this arenaOperations insightsevidence →
Stories about operations insights in this arena
Pricing plans — plan structure and value — what each tier costs and what it unlocksPricing plansevidence →
Plan structure and value — what each tier costs and what it unlocks
Privacy posture — data-handling and privacy storiesPrivacy postureevidence →
Data-handling and privacy stories
Reliability recovery — stories about reliability recovery in this arenaReliability recoveryevidence →
Stories about reliability recovery in this arena
Serverless scale — stories about serverless scale in this arenaServerless scaleevidence →
Stories about serverless scale in this arena
Story verdicts — every judged story with its evidenceStory verdicts
What’s free: 1 free · 2 paid · 0 enterprise · 34 not stated in evidence
Follow the green: where the map greys out is where PlanetScale stops today. ✓ full · ~ partial · ! disputed · — none · n/a not applicable.
Agent workflows — stories about agent workflows in this arenaAgent workflows
Stories about agent workflows in this arena
Agent ops
Agenticness — how well agents can access and operate the productAgenticness
How well agents can access and operate the product
API surface
Drive the product through a documented public API
~6/10
unlocks → Official SDKs · Machine-readable spec · Versioning policy · Full data export
Subscribe to events via webhooks
✓8/10
Build against official SDKs
—–
Issue scoped/least-privilege API credentials for an agent
~6/10
Connect an agent via an official MCP server
✓9/10
Download a machine-readable API spec (OpenAPI or equivalent)
—0/10
Rely on versioned APIs with a documented deprecation policy
—0/10
Test against a sandbox environment without touching production data
✓9/10
Explore an interactive API reference with runnable examples
—0/10
Docs for agents
Point an agent at llms.txt or agent-oriented docs
✓9/10
Agentic features
Delegate tasks to a built-in AI assistant inside the product
~4/10
Operate the product with natural-language commands
~6/10
Plug MCP servers into this product so it can use their tools
n/an/a
Get AI-generated insights and suggestions from my data inside the product
✓8/10
Set up automations that run autonomously in the background
✓7/10
Automation depth — how much of the product can run unattendedAutomation depth
How much of the product can run unattended
Branching workflows — stories about branching workflows in this arenaBranching workflows
Stories about branching workflows in this arena
Connectivity pooling — stories about connectivity pooling in this arenaConnectivity pooling
Stories about connectivity pooling in this arena
Query over HTTP or WebSockets from serverless and edge functions with an official driver built for short-lived connections
—–
Place data or replicas in regions close to my users to keep read latency low worldwide
~5/10
A built-in connection pooler handles thousands of concurrent connections without me operating my own pgbouncer or proxy
~6/10
Data capabilities — stories about data capabilities in this arenaData capabilities
Stories about data capabilities in this arena
Store embeddings and run vector similarity search natively without adding a separate vector database
—–
Run heavy analytical aggregations over large tables fast enough for dashboards without exporting to a separate warehouse
—–
I get real engine compatibility — the Postgres, MySQL, or SQLite dialect and extensions my existing code expects — not a lookalike subset
!4/10
Local dev — stories about local dev in this arenaLocal dev
Stories about local dev in this arena
Migrations schema — stories about migrations schema in this arenaMigrations schema
Stories about migrations schema in this arena
Openness — open source, data portability, and self-hosting storiesOpenness
Open source, data portability, and self-hosting stories
Operations insights — stories about operations insights in this arenaOperations insights
Stories about operations insights in this arena
Pricing plans — plan structure and value — what each tier costs and what it unlocksPricing plans
Plan structure and value — what each tier costs and what it unlocks
Privacy posture — data-handling and privacy storiesPrivacy posture
Data-handling and privacy stories
Reliability recovery — stories about reliability recovery in this arenaReliability recovery
Stories about reliability recovery in this arena
Serverless scale — stories about serverless scale in this arenaServerless scale
Stories about serverless scale in this arena
Sorted by importance (agentic first) (high → low) · 56/56 stories · click a row’s chevron for the rationale and evidence
Connect an agent via an official MCP server G Agent access | ai-native user | Agenticness — how well agents can access and operate the productAgenticness | 3 | full | 9/10 | Tprobed⚿ | |
Drive the product through a documented public API G Agent access | ai-native user | Agenticness — how well agents can access and operate the productAgenticness | 3 | partial | 6/10 | Tprobed⚿ | |
Delegate tasks to a built-in AI assistant inside the product G Agentic features | ai-native user | Agenticness — how well agents can access and operate the productAgenticness | 3 | partial | 4/10 | Tprobed⚿ | |
Plug MCP servers into this product so it can use their tools G Agent access | ai-native user | Agenticness — how well agents can access and operate the productAgenticness | 3 | n/a | 0/10 | ⚿ | |
Point an agent at llms.txt or agent-oriented docs G Agent access | ai-native user | Agenticness — how well agents can access and operate the productAgenticness | 2 | full | 9/10 | Tprobed | |
Use an official CLI G Agent access | ai-native user | Agenticness — how well agents can access and operate the productAgenticness | 2 | full | 9/10 | Tprobed | |
Get AI-generated insights and suggestions from my data inside the product G Agentic features | ai-native user | Agenticness — how well agents can access and operate the productAgenticness | 2 | full | 8/10 | Tprobed⚿ | |
Run the product headlessly / in CI for automation G Agent access | ai-native user | Agenticness — how well agents can access and operate the productAgenticness | 2 | full | 8/10 | Tprobed | |
Subscribe to events via webhooks G Agent access | ai-native user | Agenticness — how well agents can access and operate the productAgenticness | 2 | full | 8/10 | Cclaimed | |
Set up automations that run autonomously in the background G Agentic features | ai-native user | Agenticness — how well agents can access and operate the productAgenticness | 2 | full | 7/10 | Cclaimed | |
Issue scoped/least-privilege API credentials for an agent G Agent access | ai-native user | Agenticness — how well agents can access and operate the productAgenticness | 2 | partial | 6/10 | Tprobed⚿ | |
Operate the product with natural-language commands G Agentic features | ai-native user | Agenticness — how well agents can access and operate the productAgenticness | 2 | partial | 6/10 | Tprobed⚿ | |
Download a machine-readable API spec (OpenAPI or equivalent) G Api quality | ai-native user | Agenticness — how well agents can access and operate the productAgenticness | 2 | none | 0/10 | ||
Explore an interactive API reference with runnable examples G Api quality | ai-native user | Agenticness — how well agents can access and operate the productAgenticness | 2 | none | 0/10 | ||
Rely on versioned APIs with a documented deprecation policy G Api quality | ai-native user | Agenticness — how well agents can access and operate the productAgenticness | 2 | none | 0/10 | ||
Build against official SDKs G Agent access | ai-native user | Agenticness — how well agents can access and operate the productAgenticness | 2 | none | untested | none yet | |
Test against a sandbox environment without touching production data G Api quality | ai-native user | Agenticness — how well agents can access and operate the productAgenticness | 1 | full | 9/10 | Tprobed | |
Create an instant copy-on-write branch of my database — schema and data — to develop and test against production-shaped data C Branching | developer | Branching workflows — stories about branching workflows in this arenaBranching workflows | 3 | full | 9/10 | Xcommunity | |
Restore or branch the database to any point in time within the retention window to recover from bad writes C Recovery | platform-engineer | Reliability recovery — stories about reliability recovery in this arenaReliability recovery | 3 | full | 8/10 | Cclaimed | |
My coding agent can provision a database end to end — create it, fetch the connection string, apply schema, and run queries — through the API, CLI, or MCP without touching the dashboard C Agent ops | ai-native user | Agent workflows — stories about agent workflows in this arenaAgent workflows | 3 | partial | 7/10 | Tprobed⚿ | |
Ship schema changes safely — online DDL, deploy requests, or branch-and-merge workflows — without locking or breaking production C Migrations | developer | Migrations schema — stories about migrations schema in this arenaMigrations schema | 3 | partial | 7/10 | Xcommunity | |
Create a ready-to-connect database in seconds through the CLI or API without capacity planning C Provisioning | developer | Serverless scale — stories about serverless scale in this arenaServerless scale | 3 | partial | 6/10 | Xcommunity | |
Define rules that trigger actions automatically on events G | ai-native user | Automation depth — how much of the product can run unattendedAutomation depth | 3 | partial | 4/10 | Cclaimed | |
I get real engine compatibility — the Postgres, MySQL, or SQLite dialect and extensions my existing code expects — not a lookalike subset C Compatibility | developer | Data capabilities — stories about data capabilities in this arenaData capabilities | 3 | disputed | 4/10 | Dcontradicted | |
Published per-unit pricing for compute, storage, and traffic lets me predict my bill before committing G Pricing | founder | Pricing plans — plan structure and value — what each tier costs and what it unlocksPricing plans | 3 | partialfree | 4/10 | Xcommunity | |
Idle databases scale to zero so prototypes and side projects cost nothing while the data stays durable C Elasticity | founder | Serverless scale — stories about serverless scale in this arenaServerless scale | 3 | partialpaid | 3/10 | Xcommunity | |
Export all of my data in open formats and leave G | ai-native user | Openness — open source, data portability, and self-hosting storiesOpenness | 3 | none | 0/10 | ||
Run the same engine locally and keylessly — no account or cloud dependency — for offline development and CI tests G Local loop | developer | Local dev — stories about local dev in this arenaLocal dev | 3 | none | 0/10 | ||
Self-host the core product G | ai-native user | Openness — open source, data portability, and self-hosting storiesOpenness | 3 | none | 0/10 | ||
Prevent my data from being used to train AI models G | ai-native user | Privacy posture — data-handling and privacy storiesPrivacy posture | 3 | n/a | untested | none yet | |
See slow queries, index recommendations, and performance metrics in a built-in insights view C Insights | platform-engineer | Operations insights — stories about operations insights in this arenaOperations insights | 2 | full | 9/10 | Xcommunity | |
Add read replicas and rely on documented high-availability and failover behavior C Availability | platform-engineer | Reliability recovery — stories about reliability recovery in this arenaReliability recovery | 2 | full | 7/10 | Xcommunity | |
Automatic backups run on a schedule I can see and configure, and restores are self-serve C Recovery | founder | Reliability recovery — stories about reliability recovery in this arenaReliability recovery | 2 | full | 7/10 | Cclaimed | |
Create and tear down per-pull-request database branches automatically from CI or my deploy platform C Branching | platform-engineer | Branching workflows — stories about branching workflows in this arenaBranching workflows | 2 | partial | 7/10 | Tprobed | |
The official CLI covers my daily loop — create, connect, shell into, and inspect databases — without opening the dashboard C Local loop | developer | Local dev — stories about local dev in this arenaLocal dev | 2 | partial | 7/10 | Tprobed | |
A built-in connection pooler handles thousands of concurrent connections without me operating my own pgbouncer or proxy C Pooling | platform-engineer | Connectivity pooling — stories about connectivity pooling in this arenaConnectivity pooling | 2 | partial | 6/10 | Cclaimed | |
An agent can run SQL and schema operations through scoped tools that distinguish read-only from destructive actions, so I can safely delegate database work C Agent ops | ai-native user | Agent workflows — stories about agent workflows in this arenaAgent workflows | 2 | partial | 6/10 | Tprobed⚿ | |
Do everything through the API that I can do in the UI G | ai-native user | Openness — open source, data portability, and self-hosting storiesOpenness | 2 | partial | 6/10 | Tprobed | |
Cheaply create thousands of isolated databases — one per agent, tenant, or preview — and manage the fleet programmatically C Agent ops | ai-native user | Agent workflows — stories about agent workflows in this arenaAgent workflows | 2 | partialpaid | 5/10 | Tprobed | |
Perform bulk operations across many items at once G | ai-native user | Automation depth — how much of the product can run unattendedAutomation depth | 2 | partial | 5/10 | Tprobed | |
Place data or replicas in regions close to my users to keep read latency low worldwide C Latency | developer | Connectivity pooling — stories about connectivity pooling in this arenaConnectivity pooling | 2 | partial | 5/10 | Cclaimed | |
Schedule recurring jobs or workflows G | ai-native user | Automation depth — how much of the product can run unattendedAutomation depth | 2 | partial | 5/10 | Cclaimed | |
Choose where my data is stored (region/residency) G | ai-native user | Privacy posture — data-handling and privacy storiesPrivacy posture | 2 | partial | 4/10 | Cclaimed | |
Compute autoscales up and down with load automatically, without manual resizes or downtime C Elasticity | platform-engineer | Serverless scale — stories about serverless scale in this arenaServerless scale | 2 | partial | 4/10 | Xcommunity | |
A genuinely usable free tier lets me run real prototypes before paying G Pricing | founder | Pricing plans — plan structure and value — what each tier costs and what it unlocksPricing plans | 2 | none | 0/10 | ||
Read the product's source under an open license G | ai-native user | Openness — open source, data portability, and self-hosting storiesOpenness | 2 | none | 0/10 | ||
Control data retention and deletion G | ai-native user | Privacy posture — data-handling and privacy storiesPrivacy posture | 2 | none | untested | none yet | |
Opt out of telemetry and usage tracking G | ai-native user | Privacy posture — data-handling and privacy storiesPrivacy posture | 2 | none | untested | none yet | |
Query over HTTP or WebSockets from serverless and edge functions with an official driver built for short-lived connections C Drivers | developer | Connectivity pooling — stories about connectivity pooling in this arenaConnectivity pooling | 2 | none | untested | none yet | |
Run heavy analytical aggregations over large tables fast enough for dashboards without exporting to a separate warehouse C Analytics | developer | Data capabilities — stories about data capabilities in this arenaData capabilities | 2 | none | untested | none yet | |
Store embeddings and run vector similarity search natively without adding a separate vector database C Ai data | developer | Data capabilities — stories about data capabilities in this arenaData capabilities | 2 | none | untested | none yet | |
The database works out of the box with my ORM and framework (Prisma, Drizzle, Django, Rails) with documented guides C Integrations | developer | Migrations schema — stories about migrations schema in this arenaMigrations schema | 2 | none | untested | none yet | |
Import an existing production database with minimal downtime using a documented migration path C Migrations | developer | Migrations schema — stories about migrations schema in this arenaMigrations schema | 1 | full | 8/10 | Xcommunity | |
Version, review, and roll back my automations G | ai-native user | Automation depth — how much of the product can run unattendedAutomation depth | 1 | full | 7/10 | Cclaimed | |
Reset a branch from its parent or restore it to an earlier state without rebuilding from a dump C Branching | developer | Branching workflows — stories about branching workflows in this arenaBranching workflows | 1 | partial | 6/10 | Cclaimed | |
Set spend caps or usage alerts so a runaway query or traffic spike cannot produce a surprise bill G Cost controls | founder | Operations insights — stories about operations insights in this arenaOperations insights | 1 | none | 0/10 |
Opportunities — the stories that would move this product's scores, from its own judged verdictsOpportunitiestop 8 of 38 stories with headroom
What would move PlanetScale’s scores — derived from its own judged verdicts, biggest headroom first. Each line quotes what the judge found missing; shipping it (or evidencing it publicly) is the fix.
Local dev — stories about local dev in this arenaRun the same engine locally and keylessly — no account or cloud dependency — for offline development and CI tests
nonemoves PA Scoreimpact 30
PlanetScale is a cloud-hosted database platform; there is no evidence of a downloadable/local engine that runs keylessly offline.
Openness — open source, data portability, and self-hosting storiesExport all of my data in open formats and leave
nonemoves PA Scoreimpact 30
The evidence pack shows no vendor documentation of a bulk data-export feature or open-format dump/leave workflow (only an import tool for MySQL/MariaDB is documented).
Openness — open source, data portability, and self-hosting storiesSelf-host the core product
nonemoves PA Scoreimpact 30
PlanetScale is a fully-hosted cloud database platform with no documented self-host/on-prem option; community evidence explicitly confirms it cannot be installed locally or run offline and is not open source ('Can I install this locally?...
Agenticness — how well agents can access and operate the productBuild against official SDKs
nonemoves agent-readyimpact 30
Missing: any documentation of official SDKs/client libraries (Node, Go, Python, etc.), API reference tied to those SDKs, or independent confirmation of their existence.
Agenticness — how well agents can access and operate the productExplore an interactive API reference with runnable examples
nonemoves API qualityimpact 30
Probes explicitly show no OpenAPI/interactive API reference exists (docs.md 404, all openapi.json candidate paths 404), and no evidence pack item describes a runnable-example API console; only static CLI/API docs and changelog entries are present.
Agenticness — how well agents can access and operate the productDownload a machine-readable API spec (OpenAPI or equivalent)
nonemoves API qualityimpact 30
The probe explicitly checked for an OpenAPI/Swagger spec at all standard candidate paths and found only 404s, with no other evidence of a published machine-readable API spec.
Agenticness — how well agents can access and operate the productRely on versioned APIs with a documented deprecation policy
nonemoves API qualityimpact 30
No evidence pack items mention API versioning scheme or a documented deprecation policy; probes for OpenAPI specs return 404s and changelog entries are feature announcements, not API-version/deprecation documentation.
Agenticness — how well agents can access and operate the productDelegate tasks to a built-in AI assistant inside the product
partialq4/10moves Built-in AIimpact 27
Missing: a first-party in-app chat/assistant UI, independent hands-on confirmation of the self-improving-database feature actually running end-to-end, and clarity that it's not just MCP-enabled third-party agents.
Showing the top 8 of 38 — every none/partial verdict in the story verdicts table is headroom.
Think a verdict is wrong? Every verdicts-table row has a Flag link — see the methodology.
Coverage map — which docs area, API section, or community source covers which judged storiesCoverage map5 surfaces · 38 covered stories
Where the cited evidence behind each covered verdict came from — the same citations the verdicts table shows, no extra judging.
docs34 stories
- My coding agent can provision a database end to end — create it, fetch the connection string, apply schema, and run queries — through the API, CLI, or MCP without touching the dashboard
- An agent can run SQL and schema operations through scoped tools that distinguish read-only from destructive actions, so I can safely delegate database work
- Cheaply create thousands of isolated databases — one per agent, tenant, or preview — and manage the fleet programmatically
- Point an agent at llms.txt or agent-oriented docs
- Run the product headlessly / in CI for automation
- Connect an agent via an official MCP server
- Use an official CLI
- Drive the product through a documented public API
- Issue scoped/least-privilege API credentials for an agent
- Get AI-generated insights and suggestions from my data inside the product
- Set up automations that run autonomously in the background
- Delegate tasks to a built-in AI assistant inside the product
- Operate the product with natural-language commands
- Test against a sandbox environment without touching production data
- Perform bulk operations across many items at once
- Define rules that trigger actions automatically on events
- Schedule recurring jobs or workflows
- Version, review, and roll back my automations
- Reset a branch from its parent or restore it to an earlier state without rebuilding from a dump
- Create and tear down per-pull-request database branches automatically from CI or my deploy platform
- Create an instant copy-on-write branch of my database — schema and data — to develop and test against production-shaped data
- Place data or replicas in regions close to my users to keep read latency low worldwide
- I get real engine compatibility — the Postgres, MySQL, or SQLite dialect and extensions my existing code expects — not a lookalike subset
- The official CLI covers my daily loop — create, connect, shell into, and inspect databases — without opening the dashboard
- Import an existing production database with minimal downtime using a documented migration path
- Ship schema changes safely — online DDL, deploy requests, or branch-and-merge workflows — without locking or breaking production
- Do everything through the API that I can do in the UI
- See slow queries, index recommendations, and performance metrics in a built-in insights view
- Published per-unit pricing for compute, storage, and traffic lets me predict my bill before committing
- Add read replicas and rely on documented high-availability and failover behavior
- Automatic backups run on a schedule I can see and configure, and restores are self-serve
- Restore or branch the database to any point in time within the retention window to recover from bad writes
- Compute autoscales up and down with load automatically, without manual resizes or downtime
- Create a ready-to-connect database in seconds through the CLI or API without capacity planning
Changelog docs17 stories
- Run the product headlessly / in CI for automation
- Issue scoped/least-privilege API credentials for an agent
- Subscribe to events via webhooks
- Set up automations that run autonomously in the background
- Define rules that trigger actions automatically on events
- Version, review, and roll back my automations
- Reset a branch from its parent or restore it to an earlier state without rebuilding from a dump
- Create and tear down per-pull-request database branches automatically from CI or my deploy platform
- Place data or replicas in regions close to my users to keep read latency low worldwide
- A built-in connection pooler handles thousands of concurrent connections without me operating my own pgbouncer or proxy
- The official CLI covers my daily loop — create, connect, shell into, and inspect databases — without opening the dashboard
- Do everything through the API that I can do in the UI
- Choose where my data is stored (region/residency)
- Add read replicas and rely on documented high-availability and failover behavior
- Automatic backups run on a schedule I can see and configure, and restores are self-serve
- Restore or branch the database to any point in time within the retention window to recover from bad writes
- Compute autoscales up and down with load automatically, without manual resizes or downtime
Hacker News14 stories
- Cheaply create thousands of isolated databases — one per agent, tenant, or preview — and manage the fleet programmatically
- Get AI-generated insights and suggestions from my data inside the product
- Test against a sandbox environment without touching production data
- Create and tear down per-pull-request database branches automatically from CI or my deploy platform
- Create an instant copy-on-write branch of my database — schema and data — to develop and test against production-shaped data
- I get real engine compatibility — the Postgres, MySQL, or SQLite dialect and extensions my existing code expects — not a lookalike subset
- Import an existing production database with minimal downtime using a documented migration path
- Ship schema changes safely — online DDL, deploy requests, or branch-and-merge workflows — without locking or breaking production
- See slow queries, index recommendations, and performance metrics in a built-in insights view
- Published per-unit pricing for compute, storage, and traffic lets me predict my bill before committing
- Add read replicas and rely on documented high-availability and failover behavior
- Compute autoscales up and down with load automatically, without manual resizes or downtime
- Idle databases scale to zero so prototypes and side projects cost nothing while the data stays durable
- Create a ready-to-connect database in seconds through the CLI or API without capacity planning
llms.txt2 stories
Probe proofs — replayable recordings from the probe harnessProbe proofs
Replayable recordings from our probe harness — see the Prove-It protocol to submit one.
$pscale --skillreproduced$ pscale --skill
---
name: pscale-cli
description: "Automate PlanetScale with the pscale CLI. Use when the user asks to run pscale commands or manage PlanetScale databases, branches, deploy requests, or SQL from scripts or agents. Always pass --format json."
---
# PlanetScale CLI — agent guide
For **any** automated agent or script using `pscale`. Always pass **`--format json`**. Substitute placeholders from the user's request or from prior command output (`org list`, `database list`, `branch list`).
If you only have the installed `pscale` binary and this guide is not already in your context, load it and check auth:
```bash
pscale --skill
pscale auth check --format json
```
Use direct CLI automation for shell commands and scripts. Use the hosted PlanetScale MCP server for MCP clients.
This file documents **how to invoke `pscale`**. For database assessment, safety review, and operational workflows, install the [PlanetScale skills pack](https://github.com/planetscale/skills) (`14-pscale-cli-automation` covers CLI automation; `00-safe-orchestrator` runs the full review). In application repositories, add a separate **project** `AGENTS.md` with org, database, branch, and approval rules (see skill `09-mcp-agent-operating-model` in that repo).
## Public repository safety
This repository is public. Do not include internal or sensitive information in commits, commit messages, pull request titles, or pull request descriptions. Do not name or link private repositories, internal issues or pull requests, Slack conversations, customer details, credentials, or private infrastructure. Include references only when the referenced resource is public.
## Concepts
PlanetScale is a serverless database platform for **MySQL** (via Vitess) and **PostgreSQL**. Resources are namespaced: an **organization** (org) owns **databases**, and each database contains **branches** — isolated copies of schema (and, for Postgres, data) that work like git branches. The default branch is typically `main` (production). Most commands target a database + branch and take `--org` to say which organization they belong to. Throughout this guide, `<org>`, `<database>`, and `<branch>` are placeholders for those names — pick a branch with `"ready": true` from `branch list`.
On Vitess/MySQL, schema changes ship via **deploy requests**: online, non-blocking migrations you review and then deploy.
Many commands are engine-specific, and some operations use different commands per engine. Schema changes: Vitess/MySQL uses `deploy-request`; Postgres branches apply DDL directly. Access: Vitess/MySQL uses `password`; Postgres uses `role`. Resize: Vitess/MySQL uses `[redacted]space resize`; Postgres uses `branch resize`. Vitess/MySQL-only: `deploy-request`, `[redacted]space`, `workflow`, `connect`, `password`. Postgres-only: `role`, `traffic-control`, branch `switchover`/`maintenance`/`parameters`, and `import d1`. The rest (`database`, `branch`, `sql`, `shell`, `insights`, `metrics`, `backup`, `org`, `auth`, `api`) work on both.
When a database is "weird" (slow, erroring, locked, bloated):
- **`insights`** — historical analysis computed from production traffic. Start here.
- **`inspect`** — live, point-in-time state over a direct connection (locks, in-flight queries, sizes).
- **`metrics`** — time-series for latency, throughput, connections.
See "Diagnostics: insights + inspect" below for the full commands.
## Flag placement
- **`--org`** is a flag on resource subcommands (`database`, `branch`, `sql`, `api`, …). It is **not** on root `pscale` — `pscale --org …` fails.
- **`--format json`** is a global flag. It can go on `pscale` or on the subcommand.
- Commands with positional args (`sql`, `branch list`, …): put **positionals first**, then flags.
```bash
# Correct
pscale auth check --format json
pscale org list --format json
pscale database list --org <org> --format json
pscale branch list <database> --org <org> --format json
pscale sql <database> <branch> --org <org> --format json --query "SELECT 1"
# Also valid — global --format
pscale --format json database list --org <org>
# Wrong — unknown flag: --org
pscale --org <org> database list --format json
```
## Workflow
1. **Guide** — if this file is not already in your context, load the skill:
```bash
pscale --skill
```
2. **Auth** — check before anything else:
```bash
pscale auth check --format json
```
`"status": "ok"` and `"authenticated": true` with no blocking `issues` means proceed. `"status": "action_required"` exits non-zero — log in, pick an org, or fix credentials (see `issues` and `next_steps`).
3. **Login** (when not authenticated):
```bash
pscale auth login --format json
```
Pending JSON is written to **stderr** while waiting; **stdout** has a single final JSON object when login completes (`status: ok` or `action_required` if org setup fails after credentials are saved). Fields include `verification_url`, `user_code`, and `browser_opened`. Open `verification_url` manually if the browser does not open. Do not retry login in a loop without browser access.
4. **Organization** — use `"organization"` from `auth check`, ask the user, or list orgs:
```bash
pscale org list --format json
```
Pass `--org <org>` on resource commands (`database`, `branch`, `sql`, `api`, …). Not on `org list`.
Organization settings:
```bash
pscale org update --org <org> --format json --billing-email billing@example.com
pscale org update --org <org> --format json --idp-managed-roles=false
pscale org update --org <org> --format json --idp-sso-managed-roles=true
pscale org update --org <org> --format json --spend-alert=true --spend-alert-amount 2500
pscale org update --org <org> --format json --spend-alert=false
```
Organization members (email or the USER_ID from list):
```bash
pscale org member list --org <org> --format json
pscale org member list --org <org> --format json --page 2 --per-page 25
pscale org member show user@example.com --org <org> --format json
pscale org member update user@example.com --org <org> --format json --role member
pscale org member remove user@example.com --org <org> --format json --force
```
Only org admins can change another member's role or remove someone else. Nobody can change their own role. `--role` is `admin`, `member`, or `analyst`.
Organization SSO (admin session, or a [redacted] with `manage_sso`). Disable, directory disable, and domain delete need `--force` in JSON. Success JSON includes `next_steps`. Configure, directory enable, and domain verify return `portal_url` and `browser_opened`; if `browser_opened` is false, open `portal_url`. `enable` JSON includes `domain_verification_url` when present. `domain verify` does not return a domain id. Prefer `domain verify --wait`: it prints the portal URL, polls `domain list` until a new domain id appears, then polls `domain show` until that domain is verified or failed. Without `--wait`, open `portal_url`, then `domain list` and `domain show <domain-id>` to check state. `--idp-sso-managed-roles` is for SSO profile roles; `--idp-managed-roles` is for directory sync roles. They are mutually exclusive: enabling one turns the other off, and enabling both in one call is rejected.
```bash
pscale org sso show --org <org> --format json
pscale org sso enable --org <org> --format json
pscale org sso configure --org <org> --format json
pscale org sso disable --org <org> --format json --force
pscale org sso directory enable --org <org> --format json
pscale org sso directory disable --org <org> --format json --force
pscale org sso domain list --org <org> --format json
pscale org sso domain show <domain-id> --org <org> --format json
pscale org sso domain verify --org <org> --format json
pscale org sso domain verify --org <org> --format json --wait
pscale org sso domain delete <domain-id> --org <org> --format json --force
```
Organization teams and team members:
```bash
pscale org team list --org <org> --format json
pscale org team list --org <org> --format json --page 2 --per-page 25
pscale org team show <team-id-or-name> --org <org> --format json
pscale org team create --name <name> --description <description> --org <org> --format json
pscale org team update <team> --name <name> --description <description> --org <org> --format json
pscale org team delete <team> --org <org> --format json --force
pscale org team member list <team> --org <org> --format json
pscale org team member list <team> --org <org> --format json --page 2 --per-page 25
pscale org team member add <team> <email-or-id> --org <org> --format json
pscale org team member remove <team> <email-or-id> --org <org> --format json --force
```
Team identifiers may be IDs, names, or slugs. Team and membership deletion requires approval before using `--force`. SSO/directory-managed teams cannot be updated, deleted, or have members added or removed through the API.
5. **Discover resources** before SQL:
```bash
pscale database list --org <org> --format json
pscale database regions list <database> --org <org> --format json
pscale database read-only-regions list <database> --org <org> --format json
pscale branch list <database> --org <org> --format json
```
`database regions list` returns the regions available to that database for
its engine. `database read-only-regions list` returns configured Vitess
read-only regions for the database's default branch.
6. **Query** (read-only default):
```bash
pscale sql <database> <branch> --org <org> --format json --query "SELECT 1"
```
## Cloudflare-billed databases
To create a database billed to a Cloudflare account, Cloudflare must mint an HMAC billing proof. Pass the JSON proof directly:
```bash
pscale database create <database> --org <org> --format json \
--cloudflare-billing '{"account_id":"<cloudflare_account_id>","timestamp":"<unix_timestamp>","signature":"<hmac_hex>"}'
```
For automation, pass `@-` to read the proof from stdin so the signature is not exposed in process arguments:
```bash
printf '%s' "$CLOUDFLARE_BILLING_JSON" | \
pscale database create <database> --org <org> --format json --cloudflare-billing @-
```
The CLI does not mint the signature. The JSON object must contain non-empty `account_id`, `timestamp`, and `signature` strings.
## Flags
| Flag | Purpose |
|------|---------|
| `--format json` | JSON on stdout |
| `--org <org>` | Organization (on resource subcommands only) |
| `--api-url` | Non-production API base URL — pass on every command when not using production |
| `--cloudflare-billing` | Cloudflare billing proof JSON on `database create`; pass `@-` to read it from stdin |
## JSON errors
With `--format json`, any command that fails prints exactly one JSON envelope on **stdout**:
```json
{
"status": "error",
"error": "human-readable message",
"issues": [{ "code": "NOT_FOUND", "message": "human-readable message" }],
"next_steps": ["pscale org list --format json", "pscale database list --org <org> --format json"]
}
```
- `status` is `"error"` or `"action_required"`. `action_required` means an agent can recover by following `next_steps` (log in, ask the user for approval, fix the invocation). Exit code is `1` for `action_required` and `2` for `error`.
- `issues[].code` is stable and machine-readable; branch on it, not on message text.
- `next_steps` are concrete commands or instructions, ordered by likelihood.
Some commands add fields to this envelope (for example `query_kind` on destructive SQL or `migration_id` on imports) but `status`, `issues`, and `next_steps` are always present on failure.
| Code | Meaning |
|------|---------|
| `NO_AUTH` | Not authenticated or [redacted] expired; run `pscale auth login --format json` |
| `AUTH_INVALID` | Stored credentials rejected by the API; log in again |
| `SERVICE_[redacted]_INVALID` | Service [redacted] id/secret rejected; verify the values |
| `NO_ORG` | Authenticated but no organization configured |
| `INVALID_FLAG_PLACEMENT` | `--org` was passed on `pscale` root; move it to the subcommand |
| `INVALID_USAGE` | Missing arguments or required flags; the message names them |
| `UNKNOWN_COMMAND` | Command does not exist; check `pscale --help` |
| `UNKNOWN_FLAG` | Flag does not exist on this command; check `--help` |
| `TTY_REQUIRED` | Command needs an interactive terminal; use the JSON alternative in `next_steps` |
| `CONFIRMATION_REQUIRED` | Destructive or gated action; ask the user, then re-run with `--force` |
| `DESTRUCTIVE_SQL` | Query would delete data or schema; ask the user, then re-run with `--force` |
| `NOT_FOUND` | Org, database, branch, or resource does not exist; run the discovery commands |
| `NETWORK_ERROR` | Transport-level failure; check connectivity and `--api-url`, then retry |
| `COMMAND_FAILED` | Unclassified failure; read `error` and rule out auth first |
## Authentication
`pscale auth login` stores credentials in the OS [redacted]chain; agents on the same machine reuse them.
Headless / CI: pass `--service-[redacted]-id` and `--service-[redacted]` on the subcommand that needs auth.
## SQL
Non-interactive queries. Default **`--role` is `reader`** (unlike `pscale shell`, which defaults to admin). Use `pscale shell` for interactive sessions.
```bash
# Read (default)
pscale sql <database> <branch> --org <org> --format json --query "SELECT 1"
# Read from replica
pscale sql <database> <branch> --org <org> --format json --replica --query "SELECT 1"
# PostgreSQL — optional --dbname (default postgres)
pscale sql <database> <branch> --org <org> --format json --query "SELECT 1"
# MySQL multi-[redacted]space — optional --[redacted]space (default @primary)
pscale sql <database> <branch> --org <org> --format json --[redacted]space <[redacted]space> --query "SELECT 1"
```
| Flag | Purpose |
|------|---------|
| `--role` | `reader` (default), `writer`, `readwriter`, `admin` — same names as `pscale shell` |
| `--replica` | Route reads to replicas |
| `--dbname` | PostgreSQL database name (default `postgres`) |
| `--[redacted]space` | MySQL [redacted]space (default `@primary`); may include a shard and tablet type: `my[redacted]space/-80`, `my[redacted]space/-80@replica` |
| `--force` | Allow destructive SQL after explicit user approval |
**`--role` by engine** (same as `pscale shell`):
| `--role` | MySQL (Vitess) | PostgreSQL |
|----------|----------------|------------|
| `reader` | Branch password, reader role | Ephemeral role inheriting `pg_read_all_data` |
| `writer` | Branch password, writer role | Role inheriting `pg_write_all_data` |
| `readwriter` | Branch password, readwriter role | Role inheriting read + write |
| `admin` | Branch password, admin role | Role inheriting `postgres` |
### Destructive SQL
`DELETE`, `DROP`, and `TRUNCATE` anywhere in a query are blocked by default (word match, not substring — `deleted_at` is fine). Returns `"status": "action_required"` with `"query_kind": "destructive"`.
1. Ask the user to approve the query.
2. Re-run with `--force` only after they approve:
```bash
pscale sql <database> <branch> --org <org> --format json --force --query "DELETE FROM ..."
```
Never use `--force` without explicit user approval.
### SQL JSON
Success: `status`, `database`, `branch`, `kind` (`mysql` or `postgresql`), `role`, `row_count`, `columns`, `rows`; `replica` when `--replica` was used.
MySQL may return synthetic column names (e.g. `:vtg1 /* INT64 */`). PostgreSQL may use names like `?column?`.
Error: one JSON object on stdout with `status: "error"`, `error`, `issues`, and `next_steps` (see JSON errors above).
Destructive SQL without `--force`: `status: "action_required"`, `query_kind: "destructive"`, `issues`, and `next_steps` (includes `--force` retry command).
## Metrics
Query historical or current branch metrics through the public metrics API:
```bash
pscale metrics show <database> <branch> --org <org> --format json --metric queries --metric latency_p99 --period 1h
pscale metrics instant <database> <branch> --org <org> --format json --metric planetscale_volume_usage_percentage
pscale metrics report <database> <branch> --org <org> --format json --period 1d
pscale metrics queries <database> <branch> --org <org> --format json --metric latency_p99 --fingerprint <fingerprint> --[redacted]space <[redacted]space> --period 1h
pscale metrics tables <database> <branch> --org <org> --format json
pscale metrics [redacted]space-tables <database> <branch> --org <org> --format json
pscale metrics tablets <database> <branch> --org <org> --format json --metric replication_lag --period 1h
pscale metrics tablets instant <database> <branch> --org <org> --format json --metric replication_lag
pscale metrics tags <database> <branch> --org <org> --format json --metric queries --tag-set Busername=alice --tag-set Busername=bob --period 1h
```
- `--metric` is required for series and instant commands and may be repeated or comma-separated.
- Specialized query, tablet, and tag metrics accept the filters exposed by their API endpoints. `--metric` and `--query-id` may be repeated or comma-separated. `--tag-set` is repeated for independent series; comma-separate [redacted]s inside one set (`Busername=alice,Senv=production`). Tag [redacted]s need the Insights type prefix from `insights tags`.
- `metrics queries` requires a query selector. Use `--fingerprint` with `--[redacted]space`, or `--query-id` as `<fingerprint>-<[redacted]space>`. The short `id` from `insights queries` is not a query pattern ID.
- `metrics tags` requires at least one `--tag-set`. `--budget-id` and `--rule-id` apply only to the `traffic_control_warnings` and `traffic_control_throttled` metrics.
- `metrics tablets --workflow` applies only to `--metric vreplication_lag` and must name an existing workflow on the branch.
- Filters that match nothing return zero-filled series rather than an empty response, so check the point values, not the series count.
- `metrics tables` and `metrics [redacted]space-tables` preserve the untyped storage-metrics API response in JSON.
- `metrics report` detects whether the database uses MySQL or PostgreSQL and queries a curated set of performance sections. It supports `--period`, custom `--from`/`--to` ranges, and `--steps`; JSON returns a composite report and CSV includes the section name on each row.
- Historical queries support `--period`, or a custom `--from`/`--to` ISO 8601 range, plus `--steps` and dimension filters such as `--tablet-type`, `--[redacted]space`, `--shard`, `--role`, `--pod`, and `--pods`.
- JSON preserves the API response: historical results contain `start_date`, `end_date`, `interval`, and `series`; each series contains `metric`, `label`, `labels`, and `[Unix timestamp, value]` points. Instant results contain current values grouped by their dimensions.
- Human output summarizes each historical series with latest/min/average/max values and a sparkline. CSV flattens historical samples or instant values to one row each.
## Diagnostics: insights + inspect
Two complementary read-only surfaces. When diagnosing database health or performance, **check both** — they see different things.
**`pscale insights`** — server-side analysis computed from production traffic (works even when you can't or don't want to connect to the database):
```bash
pscale insights queries <database> <branch> --org <org> --format json --sort totalTime # top queries; sorts: totalTime, count, p99Latency, rowsRead, rowsReadPerReturned, errorCount, ...
pscale insights queries samples <database> <branch> <fingerprint> --org <org> --format json --[redacted]space <[redacted]space> # recent executions; [redacted]space from queries list
pscale insights queries traffic-budgets <database> <branch> <fingerprint> --org <org> --format json --[redacted]space <[redacted]space> --page <n> --per-page <n> # traffic budgets affecting a query fingerprint
pscale insights queries show <database> <branch> <query-id> --org <org> --format json # one execution; query-id comes from the samples list
pscale insights queries summary <database> <branch> <fingerprint> --org <org> --format json --[redacted]space <[redacted]space> # aggregate stats for one query pattern
pscale insights errors <database> <branch> --org <org> --format json # failing queries with error messages
pscale insights errors show <database> <branch> <fingerprint> --org <org> --format json # individual queries behind one error fingerprint (use error_fingerprint from the errors list)
pscale insights anomalies <database> <branch> --org <org> --format json # detected resource anomalies (CPU, memory, IOPS, rows)
pscale insights anomalies show <database> <branch> <id> --org <org> --format json # one anomaly plus its correlated queries
pscale insights tags <database> <branch> --org <org> --format json # query tag [redacted]s (sqlcommenter / system); use names with summaries
pscale insights tags summaries <database> <branch> --org <org> --format json --tags username # stats grouped by tag; names match the Insights UI [redacted] picker
pscale insights recommendations <database> --org <org> --format json # schema recommendations with ready-to-apply DDL
pscale insights recommendations show <database> <number> --org <org> --format json # one recommendation plus full DDL (number from list)
pscale insights recommendations dismiss <database> <number> --org <org> --format json --force # dismiss a recommendation
pscale branch query-patterns list <database> <branch> --org <org> --format json
pscale branch query-patterns show <database> <branch> <report-id> --org <org> --format json
pscale branch query-patterns delete <database> <branch> <report-id> --org <org> --format json --force
```
`queries show` takes an individual execution/sample `id`; `queries samples` and `queries summary` take a query `fingerprint`. These identifiers are not interchangeable. `queries summary` requires the [redacted]space from the queries list and accepts `--period`, or a paired `--from`/`--to` ISO 8601 range.
`branch query-patterns download` generates a new report, waits, and writes CSV. Use list/show/delete for reports that already exist.
**`pscale inspect`** — live, point-in-time checks run over a direct connection (same credentials model as `pscale sql`, always read-only):
```bash
pscale inspect all <database> <branch> --org <org> --format json # every applicable check, one report
pscale inspect <check> <database> <branch> --org <org> --format json
```
Checks: `table-sizes`, `index-sizes`, `unused-indexes`, `redundant-indexes`, `seq-scans`, `long-running-queries`, `locks`, `outliers`, `calls`, `bloat`, `vacuum-stats`, `replication-slots`, `subscriptions`. Checks adapt per engine; ones that don't apply explain the alternative. JSON results include `next_steps` pointing at the matching `insights` command — follow them.
Caveats:
- Statistics are since last server restart and per-connection-target: on sharded Vitess databases they reflect a single shard's MySQL instance. Use `--[redacted]space` to pick a [redacted]space, or pin an exact shard with `--[redacted]space 'my[redacted]space/-80'` (enumerate with `pscale sql <database> <branch> --org <org> --format json --query "SHOW VITESS_SHARDS"`; rows are `[redacted]space/shard`). Databases can have hundreds of shards — inspect one shard at a time rather than fanning out. On PostgreSQL, stats are scoped to one database (use `--dbname`; if CONNECT is denied, retry with `--role admin`).
- `outliers`/`calls` need `pg_stat_statements` on PostgreSQL; if missing, use `pscale insights queries` instead (no extension needed).
- Rule of thumb: start with `insights` (traffic-aware, historical), use `inspect` for live state (locks, in-flight queries) and physical layout (sizes, bloat, index usage).
## Vitess database throttler
Database-level default for future deploy request migrations (not per-DR, not tablet/vtctld):
```bash
pscale database throttler show <database> --org <org> --format json
pscale database throttler update <database> --org <org> --format json --ratio 25
pscale database throttler update <database> --org <org> --format json \
--configuration main=10 --configuration sharded=40
```
`--ratio` is 0–95 (0 disables throttling; 95 is slowest). Use either `--ratio` or `--configuration [redacted]space=ratio`, not both. Vitess only.
## Vitess aggressive cutover
Database-level setting for future deploy requests (not the same as `deploy-request force-cutover`):
```bash
pscale database aggressive-cutover show <database> --org <org> --format json
pscale database aggressive-cutover enable <database> --org <org> --format json
pscale database aggressive-cutover disable <database> --org <org> --format json
```
Vitess only. See https://planetscale.com/docs/vitess/schema-changes/aggressive-cutover
## Vitess deploy requests (inspect + throttler)
Core lifecycle is already covered (`list/create/show/diff/review/deploy/apply/unblock/update/cancel/close/revert/skip-revert`). `update` (`edit` is an alias) sets auto-apply and auto-delete-branch. `unblock` clears the queue after a failed deploy or revert (dashboard “Unblock deploy queue”); it is not `apply`. These inspect commands are read-only:
```bash
pscale deploy-request queue <database> --org <org> --format json # database deploy queue (first page)
pscale deploy-request operations <database> <number> --org <org> --format json # per-table schema ops + progress
pscale deploy-request reviews <database> <number> --org <org> --format json # existing reviews (create with review)
pscale deploy-request deployment <database> <number> --org <org> --format json # deployment detail (cutover flags, queue state)
pscale deploy-request storage-check <database> <number> --org <org> --format json # enough_storage / bytes needed
pscale deploy-request throttler show <database> <number> --org <org> --format json # per-DR throttler ratios (not database throttler)
```
Throttler update mutates the deploy request (use after `throttler show`):
```bash
pscale deploy-request throttler update <database> <number> --org <org> --format json --ratio 25
pscale deploy-request throttler update <database> <number> --org <org> --format json \
--configuration main=10 --configuration sharded=40
```
Alias: `pscale dr …` works the same. Vitess only. `--ratio` is 0–95 (0 disables throttling; 95 is slowest). Use either `--ratio` or `--configuration [redacted]space=ratio`, not both.
```bash
pscale deploy-request update <database> <number> --org <org> --format json --enable-auto-apply
pscale deploy-request update <database> <number> --org <org> --format json --auto-delete-branch=false
```
After a failed deploy or revert (`complete_error` / `complete_revert_error`), unblock the queue. This is not `apply` (gated cutover) and it cannot fix a deploy-check `error`:
```bash
pscale deploy-request unblock <database> <number> --org <org> --format json
```
## Maintenance schedules (Vitess Enterprise)
Read-only visibility into planned maintenance windows for a Vitess database (Enterprise plans):
```bash
pscale maintenance list <database> --org <org> --format json
pscale maintenance show <database> <schedule-id> --org <org> --format json
pscale maintenance windows <database> <schedule-id> --org <org> --format json
```
`--org` is required. Schedules include next/last window times, frequency, and any pending Vitess/MySQL version updates. Vitess Enterprise only.
## Postgres branch changes (size, replicas, parameters) — Postgres only
`pscale branch resize` queues a single asynchronous **change request** for a Postgres branch covering cluster size, replica count, and configuration parameters in any combination. Track it with `resize status`; cancel it with `resize cancel` while queued.
```bash
# Read the parameter catalog first (names, current/default values, restart/immutable flags)
pscale branch parameters list <database> <branch> --org <org> --format json
pscale branch parameters list <database> <branch> --org <org> --format json --namespace pgconf
# Extensions available on the cluster image (not CREATE EXTENSION state)
pscale branch extensions list <database> <branch> --org <org> --format json
# Default postgres role (read-only; reset-default rotates the password)
pscale role default <database> <branch> --org <org> --format json
pscale role reset-default <database> <branch> --org <org> --format json --force
# Role connection details for a branch replica, read-only replica, or PgBouncer
pscale role get <database> <branch> <role-id> --org <org> --format json --replica
pscale role get <database> <branch> <role-id> --org <org> --format json --read-only-replica <replica-name>
pscale role get <database> <branch> <role-id> --org <org> --format json --bouncer <bouncer-name>
# Change parameters (repeat --parameters; [redacted]s are namespace.name)
pscale branch resize <database> <branch> --org <org> --format json --parameters pgconf.max_connections=200
# Combine size, replicas, and parameters into one change request
pscale branch resize <database> <branch> --org <org> --format json \
--cluster-size PS_10_GCP_X86 --replicas 2 --parameters pgconf.max_connections=500
# Block until the change finishes (default timeout 10m; tune with --wait-timeout)
pscale branch resize <database> <branch> --org <org> --format json --parameters pgconf.work_mem=64MB --wait
# Inspect the latest change request / cancel a queued one
pscale branch resize status <database> <branch> --org <org> --format json
pscale branch resize cancel <database> <branch> --org <org> --format json
```
- At least one of `--cluster-size`, `--replicas`, or `--parameters` is required.
- The `role get` connection target flags are mutually exclusive. Targeted role responses keep the same shape while changing `username`, `access_host_url`, and `database_url` as needed.
- `--parameters` values are validated against the catalog before submission; unknown or immutable parameters fail fast. Parameters with `"restart": true` in the catalog restart the database when applied — surface this to the user before changing them.
- Change request `state` is one of `queued`, `pending`, `resizing`, `completed`, `canceled`. Only `completed` and `canceled` are terminal. Without `--wait`, poll `resize status` instead of assuming completion.
- A no-op (branch already matches the requested configuration) prints `{"result": "no_change", "branch": "<branch>"}` in JSON mode instead of a change request.
- `resize cancel` prints `{"result": "canceled", "branch": "<branch>"}` in JSON mode.
- MySQL databases are rejected: use `pscale [redacted]space resize` for Vitess [redacted]spaces.
## Postgres read-only replicas
Read-only replicas provide dedicated regional capacity for Postgres queries
that can tolerate replication lag. They are separate from the replicas in the
primary branch cluster and from Vitess read-only regions.
```bash
pscale read-only-replica list <database> <branch> --org <org> --format json
pscale read-only-replica show <database> <branch> <name> --org <org> --format json
pscale read-only-replica create <database> <branch> <name> --region <region> --org <org> --format json
pscale read-only-replica create <database> <branch> <name> --region <region> --replicas 2 --cluster-size PS_10_GCP_X86 --org <org> --format json
pscale read-only-replica update <database> <branch> <name> --replicas 3 --org <org> --format json
pscale read-only-replica update <database> <branch> <name> --cluster-size PS_20_GCP_X86 --parameters pgconf.max_connections=300 --org <org> --format json
pscale read-only-replica delete <database> <branch> <name> --org <org> --format json --force
```
- `create` requires a name and `--region`. The API defaults to one instance and the primary cluster size when `--replicas` and `--cluster-size` are omitted.
- `show`, `update`, and `delete` identify the read-only replica by name.
- `update` requires at least one of `--replicas`, `--cluster-size`, or repeatable `--parameters namespace.name=value`. Parameter values must be greater than or equal to the primary's corresponding values.
- Creating and updating replicas is asynchronous; inspect `state` and `ready` in the returned object or with `list`.
- `delete` requires explicit approval before using `--force`.
- PostgreSQL only. For Vitess/MySQL, use `pscale [redacted]space read-only-regions`.
## Postgres switchovers
`pscale branch switchover` moves the primary of a Postgres branch to a replica. It is Postgres-only; Vitess/MySQL databases are rejected before any API call.
```bash
# Promote an automatically selected replica
pscale branch switchover <database> <branch> --org <org> --format json
# Promote a specific replica (names from `pscale branch infra`)
pscale branch switchover <database> <branch> --org <org> --format json --candidate <replica-name>
# List switchovers for a branch (supports --page and --per-page)
pscale branch switchover list <database> <branch> --org <org> --format json
# Show current status and details for one switchover
pscale branch switchover show <database> <branch> <id> --org <org> --format json
```
- The command returns the created switchover (`id`, `state`, `method`) and exits; it does not wait. A fresh switchover is `pending` and `method` is empty until the operator picks one.
- `method` is `switchover` (replica promoted) for branches with replicas, or `restart` for single-node branches, which are restarted in place and unreachable while they come back. Warn the user before running this against a single-node branch.
- Writes are briefly interrupted while the switch completes. A branch accepts one switchover at a time.
- A switchover that ends in `failed` has an unconfirmed outcome: the primary may still have moved and nothing is rolled back. Check the current primary with `pscale branch infra <database> <branch> --org <org> --format json` before retrying.
- `--candidate` is rejected for branches without replicas. Poll status with `pscale branch switchover show <database> <branch> <id> --org <org> --format json`.
## Postgres branch maintenance
`pscale branch maintenance run` upgrades a Postgres branch to the latest cluster image. This is how regular version bumps, bugfixes, and quality-of-life improvements reach a branch; PlanetScale otherwise upgrades images only in emergencies, such as patching security issues.
```bash
# Run maintenance now
pscale branch maintenance run <database> <branch> --org <org> --format json
# Also upgrade to the latest PostgreSQL minor version
pscale branch maintenance run <database> <branch> --org <org> --format json --update-postgres-minor-version
```
- The upgrade is applied to the replicas first, followed by a switchover from the old primary to an upgraded replica. That failover leads to a short period of database unavailability (seconds) and terminates all direct connections. A branch running a single instance has no replica to switch over to and is unavailable until it comes back. Warn the user before running this.
- The command returns `{"result": "maintenance started", "branch": "<branch>"}` and exits; it does not wait. Check progress with `pscale branch infra <database> <branch> --org <org> --format json`.
- Rejected while a change request from `pscale branch resize` is still in progress — check `pscale branch resize status` first.
- `--update-postgres-minor-version` is rejected when the branch is already on the latest minor version or the upgrade is unavailable for it.
- Postgres only; Vitess/MySQL databases are rejected before any API call.
- See https://planetscale.com/docs/postgres/operations-philosophy
## Billing payment methods
Update the organization's card through Stripe-hosted Checkout. The CLI never collects PAN; the human must finish Checkout in a browser. There is only one current card.
```bash
pscale billing payment-method update --org <org> --format json
pscale billing payment-method status <setup-id> --org <org> --format json
pscale billing payment-method show --org <org> --format json
pscale billing payment-method delete --org <org> --format json --force
```
`--org` is required (same as other resource commands). `status <setup-id>` takes the `id` returned by `update` (pending JSON on stderr, or the setup object on stdout). That id is a **setup** id, not the saved card id. `show` and `delete` operate on the organization's current card.
**Happy path — leave `update` running.** It creates a setup, opens Checkout when possible, and **polls until a terminal state**. Do not poll `status` yourself unless `update` was interrupted.
Same JSON shape as `auth login`: pending object on **stderr** immediately; a single setup object on **stdout** when polling finishes.
```json
{
"status": "pending",
"id": "<setup-id>",
"checkout_url": "https://checkout.stripe.com/...",
"browser_opened": true,
"message": "Complete Stripe Checkout in the browser to continue",
"next_steps": [
"Complete Stripe Checkout",
"pscale billing payment-method status <setup-id> --org <org> --format json"
]
}
```
1. Surface `checkout_url` to the user. If `browser_opened` is false, tell them to open it. You cannot complete Checkout.
2. Keep `update` running. Do not start a second `update` while the first is waiting — that creates a new Checkout session.
3. When `update` exits, read **stdout**. Branch on `state`: `completed`, `failed`, or `expired`. `failed` includes a user-facing `error`.
A non-`completed` terminal state exits non-zero and prints an error envelope on **stdout** carrying `id`, `state`, and the recovery command:
| Code | Meaning |
|------|---------|
| `PAYMENT_METHOD_SETUP_FAILED` | Verification failed; `error` has the user-facing reason. The Checkout session is spent — run `update` again. |
| `PAYMENT_METHOD_SETUP_EXPIRED` | Checkout was not completed in time; run `update` again. |
| `PAYMENT_METHOD_SETUP_INTERRUPTED` | Polling stopped while the setup was still pending. `action_required`; resume with `status <setup-id>`, do not run `update` again. |
Follow `next_steps`. Only `PAYMENT_METHOD_SETUP_INTERRUPTED` is resumable; for the other two, `status` will keep returning the same terminal state.
**If `update` is killed or times out**, take `id` from the pending stderr object (do not call `update` again) and GET once:
```bash
pscale billing payment-method status <setup-id> --org <org> --format json
```
`status` does **not** poll. If `state` is still `pending`, wait and call `status` again with the same setup id. Same terminal states as `update`.
**Current card.** `show` returns the saved card. `delete` requires user approval, then `--force` in JSON (`CONFIRMATION_REQUIRED` without it). Failures print the same envelope as other agent commands (`status`, `error`, `issues`, `next_steps`):
| Code | Meaning |
|------|---------|
| `NOT_FOUND` | No current card. Next step is `pscale billing payment-method update --org <org> --format json`. |
| `UNPAID_INVOICES` | `delete` rejected because the organization has unpaid invoices. Pay them, then retry. |
## Billing invoices
Read-only invoice history for an organization. `--org` is required.
```bash
pscale billing invoice list --org <org> --format json
pscale billing invoice show <invoice-id> --org <org> --format json
pscale billing invoice line-items <invoice-id> --org <org> --format json
```
- `list` and `line-items` are paginated and return **one page per call**: `--page` (default 1) and `--per-page` (default 25). Invoices with thousands of line items are common, so walk pages deliberately. Human output prints the next page number; in JSON compare the row count to `--per-page` to decide whether to fetch again.
- JSON preserves the API objects. Line items include the billed database and nested resource (usually a branch).
- Requires `read_invoices` on a service [redacted].
## Imports (Cloudflare D1) — Postgres only
`pscale import d1` migrates a Cloudflare D1 (SQLite) export into a PlanetScale Postgres branch. Every subcommand supports `--format json` and returns `status`, `issues`, and `next_steps`; stateful steps return a `migration_id` — pass it back with `--migration-id` to resume.
```bash
pscale import d1 doctor --format json # check prerequisites (pgloader, psql)
pscale import d1 lint --input <file> --format json # pre-import checks; errors block import
pscale import d1 start <database> --org <org> --input <file> --dry-run --format json # plan + migration ID, no writes
pscale import d1 start <database> --org <org> --input <file> --format json # run the import
pscale import d1 verify <database> --org <org> --migration-id <id> --sqlite <file> --format json
pscale import d1 complete <database> --org <org> --migration-id <id> --format json
```
Branch is an optional second positional (defaults to the default branch). `status --migration-id <id>` shows saved migration state; `convert-schema --input <file>` converts schema only.
**`start` in JSON mode does not prompt.** The confirmation prompt is human-format only; with `--format json`, `start` loads data immediately. Run `start --dry-run` first, show the user the plan, and only run the real `start` after they approve.
## API passthrough
```bash
pscale api --org <org> organizations/<org>/databases
```
## MCP
For MCP clients, use the hosted PlanetScale MCP server:
```text
https://mcp.pscale.dev/mcp/planetscale
```
See the current MCP docs: https://planetscale.com/docs/connect/mcp
## PlanetScale agent skills
Operational workflows (inventory, safety review, Insights, schema recommendations, Traffic Control) live in the public skills repo — not in this file.
```bash
git clone https://github.com/planetscale/skills.git && cd skills && script/setup
# or: npx skills add planetscale/skills -g -y
```
After installing skills, load `14-pscale-cli-automation` for CLI conventions (or run `pscale --skill` from any `pscale` binary to print this reference). Use `00-safe-orchestrator` when the user asks for a full PlanetScale assessment.
$pscale --version # installed via `brew install planetscale/tap/pscale`reproduced$ pscale --version # installed via `brew install planetscale/tap/pscale` pscale version 0.329.0 (build date: 2026-09-04T21:14:34Z commit: 1db86769)
$curl -si -X POST https://mcp.pscale.dev/mcp/planetscale -H 'Content-Type: application/json' -d '<jsonrpc initialize>'reproduced$ curl -si -X POST https://mcp.pscale.dev/mcp/planetscale -H 'Content-Type: application/json' -d '<jsonrpc initialize>'
HTTP/2 401
date: Sun, 06 Sep 2026 21:10:37 GMT
content-type: application/json
content-length: 81
access-control-allow-credentials: true
access-control-allow-headers: Accept, Content-Type, Content-Length, Accept-Encoding, Authorization, User-Agent, Gram-Session, Gram-Project, Gram-[redacted], Gram-[redacted], idempotency-[redacted], Gram-Admin-Override, Gram-Chat-ID, Gram-Assistant-ID, Gram-Chat-Session, MCP-Protocol-Version, Mcp-Method, Mcp-Name, Mcp-Session-Id, X-Gram-Scope-Override, X-Gram-Source
access-control-allow-methods: POST, GET, OPTIONS, PUT, DELETE
access-control-allow-origin: https://app.getgram.ai
access-control-expose-headers: Accept, Content-Type, Content-Length, Accept-Encoding, x-trace-id, Gram-Session, Gram-Chat-ID, Gram-Chat-Session, Mcp-Session-Id
mcp-session-id: c8358496-bddd-446d-a76c-97ac6dde8118
www-authenticate: Bearer resource_metadata="https://mcp.pscale.dev/.well-known/oauth-protected-resource/mcp/planetscale"
x-request-id: 11972c46e90f47780459733ad70e3025
x-trace-id: 1cfe1aadc716291255789b81d6485e0d
strict-transport-security: max-age=31536000; includeSubDomains
content-security-policy: base-uri 'none'; connect-src 'self' https://api.github.com https://metrics.speakeasy.com https://browser-intake-datadoghq.com https://*.usepylon.com wss://*.pusher.com https://*.pusher.com https://*.posthog.com https://chat.speakeasy.com https://chat.dev.speakeasy.com https://app.getgram.ai https://dev.getgram.ai https://cdn.prod.getgram.ai https://cdn.dev.getgram.ai https://app.cal.com https://storage.googleapis.com https://*.clairedefermat.com; default-src 'self'; font-src 'self' https://*.getgram.ai https://fonts.googleapis.com https://fonts.gstatic.com https://*.usepylon.com https://*.posthog.com; frame-ancestors 'self'; frame-src 'self' https://polar.sh https://*.polar.sh https://app.svix.com https://app.cal.com https://cal.com; img-src 'self' blob: https: android-webview-video-poster: data:; media-src 'self' https://*.posthog.com; object-src 'none'; script-src 'self' 'wasm-unsafe-eval' https://www.datadoghq-browser-agent.com https://metrics.speakeasy.com https://widget.usepylon.com https://*.posthog.com https://*.getgram.ai https://app.cal.com https://*.clairedefermat.com; style-src 'self' 'unsafe-inline' https://*.getgram.ai https://fonts.googleapis.com https://*.usepylon.com https://*.posthog.com; worker-src 'self' blob:; report-to browser-intake-datadoghq
permissions-policy: fullscreen=(), compute-pressure=(), camera=(), microphone=(self), geolocation=(), accelerometer=(), bluetooth=(), gyroscope=(), payment=(), usb=(), midi=(), magnetometer=()
referrer-policy: strict-origin-when-cross-origin
reporting-endpoints: browser-intake-datadoghq="https://browser-intake-datadoghq.com/api/v2/logs?dd-[redacted]
x-content-type-options: nosniff
x-frame-options: deny
x-xss-protection: 1; mode=block
{"error":{"code":-32001,"message":"unauthorized access"},"id":1,"jsonrpc":"2.0"}
Claims vs evidence — vendor claims reconciled against independent verdictsClaims vs evidence
12 of 19 testable claims verified · 0 contradicted → integrity 63/100
29 distinct capability claims found in PlanetScale’s own claimed-docs/GitHub materials, reconciled against our judge’s independent verdicts.
12
Verified
7
Unverified
0
Contradicted
18
Undersold
Verified (19)
“Postgres instance, storage, and PgBouncer metrics have dedicated, shareable graph pages”
See slow queries, index recommendations, and performance metrics in a built-in insights viewfullproof ↗
“Org admins can enable and manage SSO directly from the CLI”
“CLI can list switchovers for a branch and show a specific switchover by ID”
Add read replicas and rely on documented high-availability and failover behaviorfullproof ↗
“CLI can show a single service token by its ID”
Issue scoped/least-privilege API credentials for an agentpartialproof ↗
“Database schemas can be branched the same way code is branched”
Create an instant copy-on-write branch of my database — schema and data — to develop and test against production-shaped datafullproof ↗
“Postgres branches are isolated deployments for development, testing, and restoring from backups”
Create an instant copy-on-write branch of my database — schema and data — to develop and test against production-shaped datafullproof ↗
“Branching plus deploy requests lets you ship schema changes to production with zero downtime”
Ship schema changes safely — online DDL, deploy requests, or branch-and-merge workflows — without locking or breaking productionpartialproof ↗
“An in-dashboard import tool migrates an existing internet-accessible MySQL/MariaDB database with no downtime”
Import an existing production database with minimal downtime using a documented migration pathfullproof ↗
“Appending |replica to a username routes connections to a read replica branch”
Add read replicas and rely on documented high-availability and failover behaviorfullproof ↗
“pscale sql lets agents and scripts run SQL non-interactively”
Run the product headlessly / in CI for automationfullproof ↗
“pscale sql lets agents and scripts run SQL non-interactively”
The official CLI covers my daily loop — create, connect, shell into, and inspect databases — without opening the dashboardpartialproof ↗
“Server-side analysis surfaces aggregated query stats, failing query patterns, resource anomalies, and schema recommendations from production traffic”
See slow queries, index recommendations, and performance metrics in a built-in insights viewfullproof ↗
“Server-side analysis surfaces aggregated query stats, failing query patterns, resource anomalies, and schema recommendations from production traffic”
Get AI-generated insights and suggestions from my data inside the productfullproof ↗
“MCP-compatible tools like Claude, Cursor, and Notion can connect to PlanetScale databases and Insights”
“Read replicas reduce load on the primary database by serving reads”
Add read replicas and rely on documented high-availability and failover behaviorfullproof ↗
“CLI can open a secure interactive MySQL or PostgreSQL shell”
The official CLI covers my daily loop — create, connect, shell into, and inspect databases — without opening the dashboardpartialproof ↗
“Dashboard shows current and historical usage per database”
Published per-unit pricing for compute, storage, and traffic lets me predict my bill before committingpartialproof ↗
“Top queries can be listed ranked by a chosen performance metric”
See slow queries, index recommendations, and performance metrics in a built-in insights viewfullproof ↗
“Development branches can be created and used before shipping schema changes to production”
Create an instant copy-on-write branch of my database — schema and data — to develop and test against production-shaped datafullproof ↗
Unverified (12)
“Webhooks can include a custom Authorization header (e.g. Bearer token) for authentication”
“Webhook events fire on backup success or failure so you're notified automatically”
“Webhook events fire on backup success or failure so you're notified automatically”
Automatic backups run on a schedule I can see and configure, and restores are self-servefullproof ↗
“Postgres branches can be created restored to a specific point-in-time timestamp”
Restore or branch the database to any point in time within the retention window to recover from bad writesfullproof ↗
“Postgres branches can be created restored to a specific point-in-time timestamp”
Reset a branch from its parent or restore it to an earlier state without rebuilding from a dumppartialproof ↗
“CLI can list available regions for a database and its configured Vitess read-only regions”
Place data or replicas in regions close to my users to keep read latency low worldwidepartialproof ↗
“Postgres branches are isolated deployments for development, testing, and restoring from backups”
Reset a branch from its parent or restore it to an earlier state without rebuilding from a dumppartialproof ↗
“Backups can be created, scheduled, and restored for production and development branches”
Automatic backups run on a schedule I can see and configure, and restores are self-servefullproof ↗
“An agent can autonomously identify high-impact performance issues, edit code, and open a pull request”
Set up automations that run autonomously in the backgroundfullproof ↗
“Agents can run on a recurring schedule to review Insights/Schema Recommendations and open performance-improvement PRs”
Set up automations that run autonomously in the backgroundfullproof ↗
“Agents can run on a recurring schedule to review Insights/Schema Recommendations and open performance-improvement PRs”
“Manual backups can be created in addition to the automatic daily default backups”
Automatic backups run on a schedule I can see and configure, and restores are self-servefullproof ↗
Undersold (18)
My coding agent can provision a database end to end — create it, fetch the connection string, apply schema, and run queries — through the API, CLI, or MCP without touching the dashboardpartialproof ↗
An agent can run SQL and schema operations through scoped tools that distinguish read-only from destructive actions, so I can safely delegate database workpartialproof ↗
Cheaply create thousands of isolated databases — one per agent, tenant, or preview — and manage the fleet programmaticallypartialproof ↗
Point an agent at llms.txt or agent-oriented docsfullproof ↗
Drive the product through a documented public APIpartialproof ↗
Delegate tasks to a built-in AI assistant inside the productpartialproof ↗
Operate the product with natural-language commandspartialproof ↗
Test against a sandbox environment without touching production datafullproof ↗
Perform bulk operations across many items at oncepartialproof ↗
Define rules that trigger actions automatically on eventspartialproof ↗
Create and tear down per-pull-request database branches automatically from CI or my deploy platformpartialproof ↗
A built-in connection pooler handles thousands of concurrent connections without me operating my own pgbouncer or proxypartialproof ↗
Do everything through the API that I can do in the UIpartialproof ↗
Choose where my data is stored (region/residency)partialproof ↗
Compute autoscales up and down with load automatically, without manual resizes or downtimepartialproof ↗
Idle databases scale to zero so prototypes and side projects cost nothing while the data stays durablepartialproof ↗
Create a ready-to-connect database in seconds through the CLI or API without capacity planningpartialproof ↗
Claims outside our story set (4)
Real capability claims found in PlanetScale’s own materials, but no story in this arena’s taxonomy covers them yet — that’s feedback on the taxonomy, not a mark against the product.
“Large monolithic databases can be sharded and spread across multiple servers”
source ↗“Metal offering provides high-IOPS NVMe SSD performance for demanding workloads”
source ↗“Metal delivers reduced latency, consistent IO, and unlimited IOPS”
source ↗“Sharding logic can be kept out of application code”
source ↗
Pricing signals
- $5per month (entry plan)entry planPlanetScale Postgres single node starting price for development/low-traffic workloadssource ↗as of 2026-09-07
- freeper GB-monthfree tierFirst 10 GB of network-attached storage is included free before per-GB pricing appliessource ↗as of 2026-09-07
Extracted verbatim from the vendor’s own pricing page — hover a figure for the exact quote.
Business model
Per-cluster pricing from $15/month (PS-5) by instance size, storage, and egress across Postgres and Vitess/MySQL; Metal NVMe clusters and Managed/BYOC enterprise deployments are priced custom. No free tier.
pricing ↗Score trend
How this product’s scores have moved as evidence and verdicts are re-derived — a point per change, not per day.
Try Experimental
Run it in the microterminal →Recorded agent sessions — and a live MCP handshake where the vendor ships one.
Flag
⚑ Flag a verdictThink a verdict is wrong? Opens a prefilled GitHub issue — or use the ⚑ next to any verdict above.
For agents
Agent surface uptime MCP 100% · llms.txt 100% (30d, checked every 6h since Sep 8 '26)
