Beginner May 3, 2026 · 2 min read

Loom targets PlanetScale (MySQL-compatible) for production. The same DSN works against any MySQL 8 server, so local MariaDB or MySQL also work for dev.

DSN format

Two equivalent forms are accepted:

# URL form (preferred, easier to read)
export DATABASE_URL='mysql://user:pass@host/dbname?tls=true'

# Raw go-sql-driver DSN (direct, no parsing)
export DATABASE_URL='user:pass@tcp(host:3306)/dbname?tls=true'

The runtime normalises the URL form to the raw DSN before opening the connection.

Where to get the DSN

In PlanetScale: Branches → Connect → General. Choose the password type (Read-write for loom serve / loom stitch) and copy the URL. PlanetScale already includes tls=true — keep it; the connection refuses unencrypted traffic.

Branches and loom stitch

PlanetScale uses Git-style branches. Each branch is a fully isolated database; deploy requests merge schema changes between them.

The recommended workflow:

  1. main branch is production. Never connect Loom directly with a destructive command.
  2. Feature branches for schema changes. Connect Loom against the feature branch:
    export DATABASE_URL='mysql://...feature-branch...'
    loom stitch --preview      # always preview first
    loom stitch                # apply against the feature branch
    
  3. Open a deploy request in PlanetScale to merge schema changes back to main.

Local MySQL for dev

For laptop development without a PlanetScale account, a local MySQL or MariaDB works fine:

docker run --rm -d --name loom-mysql \
  -p 3306:3306 \
  -e MYSQL_ROOT_PASSWORD=loom \
  -e MYSQL_DATABASE=loom_dev \
  mysql:8

export DATABASE_URL='mysql://root:loom@127.0.0.1:3306/loom_dev'

Drop tls=true from the URL since local connections don't need TLS.

What Loom expects

Loom does not require any special database setup. On first loom stitch, it creates a loom_migrations audit table for change tracking, then your Thread tables. There is no schema lock-in — every table is plain InnoDB.

What Loom does not do

  • Foreign key enforcement. PlanetScale doesn't support FK constraints, so Loom emits FK relationships as comments in the SQL, not enforced constraints. The runtime relies on application-level checks.
  • Cross-region failover. That's PlanetScale's responsibility.
  • Connection-pool tuning beyond defaults. If you need a different pool size, see the PingTimeout and connection pool tuning recipe.
Was this article helpful?