PlanetScale’s database is a distributed SQL database, and when you’re connecting your Rails application to it, you’ll need to configure Active Record to play nicely with its specific features.

Let’s see what a typical PlanetScale connection looks like in a Rails database.yml file.

development:
  adapter: postgresql
  encoding: unicode
  database: my_app_development
  pool: 10
  username: root
  password:
  host: 127.0.0.1
  port: 5432

test:
  adapter: postgresql
  encoding: unicode
  database: my_app_test
  pool: 5
  username: root
  password:
  host: 127.0.0.1
  port: 5432

production:
  adapter: postgresql
  encoding: unicode
  database: my_app_production
  pool: 20
  username: <%= Rails.application.credentials.dig(:planetscale, :username) %>
  password: <%= Rails.application.credentials.dig(:planetscale, :password) %>
  host: <%= Rails.application.credentials.dig(:planetscale, :host) %>
  port: 5432

This configuration is pretty standard for PostgreSQL. The adapter is set to postgresql because PlanetScale is wire-compatible with PostgreSQL. The pool size is important; it determines how many database connections your Rails application can open simultaneously. A good starting point for production is usually around 20.

The real magic for PlanetScale happens in how you manage schema changes. PlanetScale uses a non-blocking schema migration system. Instead of locking tables during migrations, it uses a system of branches and sharding that allows you to deploy changes without downtime.

When you create a new PlanetScale database, you’ll get a connection string that looks something like this:

mysql://root@tcp(containers-us-west-2b.2.db.planetscale.com:3306)/my_app?sslmode=disable

Notice that it’s using mysql:// and a MySQL port (3306). This is a key point: while PlanetScale is wire-compatible with PostgreSQL, its native protocol is MySQL. This means your Rails application needs to be configured to talk to PlanetScale using the MySQL adapter, not the PostgreSQL adapter.

If you’re seeing ActiveRecord::ConnectionNotEstablished or similar errors, it’s almost certainly because you’re trying to use the PostgreSQL adapter with PlanetScale.

To fix this, you need to change your database.yml to use the mysql2 adapter.

production:
  adapter: mysql2
  encoding: utf8mb4
  database: my_app_production
  pool: 20
  username: <%= Rails.application.credentials.dig(:planetscale, :username) %>
  password: <%= Rails.application.credentials.dig(:planetscale, :password) %>
  host: <%= Rails.application.credentials.dig(:planetscale, :host) %>
  port: 3306 # PlanetScale uses 3306 for MySQL protocol

You’ll also need to ensure you have the mysql2 gem in your Gemfile:

gem 'mysql2', '~> 0.5.0'

And then run bundle install.

The encoding: utf8mb4 is crucial for proper handling of a wide range of characters, including emojis, which is a common requirement in modern web applications.

The host and port will come directly from your PlanetScale connection string. The username and password should be stored securely, for example, in Rails credentials.

The pool size in database.yml directly maps to the max_connections setting in your PlanetScale database schema. You can set this in the PlanetScale dashboard under "Database Settings" -> "Connection settings". A pool of 20 in Rails will try to open up to 20 connections. If your PlanetScale max_connections is set lower than this, you might hit connection limits. It’s best to set max_connections in PlanetScale to be at least as large as your Rails pool size. For a pool of 20, setting max_connections to 25 or 30 in PlanetScale is a safe bet to allow for some overhead.

When you deploy schema changes on PlanetScale, you do it through "schema branches". You create a branch, make your changes using rails db:migrate, and then "deploy" that branch to your main production branch. This process is designed for zero-downtime deployments, which is a major advantage over traditional single-node databases that require downtime for migrations.

One of the most surprising aspects of PlanetScale’s compatibility is how it handles transactions. Because it’s a distributed system, standard ACID transactions can have different performance characteristics. PlanetScale uses a system that ensures consistency but might involve more coordination behind the scenes than a single-node database. This means you might observe slightly higher latency for complex transactions, but it guarantees data integrity across the distributed nodes.

The next thing you’ll likely encounter is managing PlanetScale’s schema branching workflow within your CI/CD pipeline.

Want structured learning?

Take the full Planetscale course →