Engineering
July 24, 2026
Why Coline runs on PlanetScale
In June we moved Coline's production database from AWS RDS to PlanetScale Postgres with zero downtime. Here's what our old setup looked like, how the cutover went, and what changed after.
Written by
The Coline Team

Everything in Coline eventually lands in Postgres. Messages, mail, notes, tasks, Kairo conversations, Code sessions, and the state created by Cloud Agents all depend on the same database foundation.
That makes database reliability product reliability.
Until last month, our production database ran on AWS RDS. It served Coline well through several generations of the product, but our workload was changing. Coline was becoming more real-time, more agentic, and far less predictable than the application the original database configuration was designed for.
We needed a database platform that could absorb sharp changes in demand, give us much deeper visibility into production queries, and scale without requiring constant capacity planning.
So we moved to PlanetScale.
What we were outgrowing
Our RDS setup was deliberately lean and performed comfortably during normal usage. The challenge was not sustained load. It was the shape of Coline’s growth.
Product launches, agent runs, background jobs, indexing, and real-time activity create concentrated waves of database work. During the release of Coline 0.4.0, that traffic pushed connections to the configured ceiling. Outside launch periods, storage bursting could still cause write latency to rise unpredictably, with the worst observed spike reaching 862 milliseconds.
The database looked healthy when viewed through averages. The moments that mattered told a different story.
Coline’s workload was becoming increasingly bursty, while the infrastructure underneath it was designed around relatively stable capacity. Supporting the next stage of the product on RDS would have meant scaling the instance ahead of demand, provisioning additional IOPS, expanding connection infrastructure, and continuously tuning around the largest traffic events.
That path was entirely possible. It was also the wrong use of our attention.


We wanted to spend our infrastructure time improving Coline, not repeatedly estimating how much database capacity the next launch might require.
Why PlanetScale, and why now
The final push came from Cloudflare.
A large part of Coline’s infrastructure already runs on Cloudflare Workers. When PlanetScale became available directly through Cloudflare, with Hyperdrive integration and unified billing, it fit naturally into the architecture we were already building.
Our PlanetScale cluster runs in Oregon, close to the infrastructure communicating with it most frequently. The previous RDS database ran in Virginia, so many requests travelled across the continent before returning. Moving the database closer reduced that distance and made performance more consistent.
PlanetScale Postgres is also still Postgres. Coline uses Drizzle for schemas and migrations, so moving did not require us to redesign the application or adopt a new data model. Our existing schema, queries, drivers, and migration workflow carried over.
We were not looking for a more exotic database. We wanted a stronger platform underneath the one we already had.
The migration
The migration moved both providers and regions, from AWS RDS in Virginia to PlanetScale in Oregon.
Codex handled much of the repeatable work. It created the new schema from our existing Drizzle migrations, transferred the production data, and ran validation checks against both databases before any application traffic moved.
Once both sides matched, we updated the connection configuration and deployed Coline through our normal release process. The application rolled onto PlanetScale without a maintenance window or interruption to requests.
The move itself took minutes.
We kept the RDS database online for another week as a fallback while we watched production traffic and validated the new environment under real workloads. It was never needed. On June 29, we created final snapshots and retired the RDS instance.
What changed
The most important improvement was not raw speed. It was visibility.
PlanetScale Insights gives us a direct view into the queries running across Coline and lets us identify expensive work by latency, frequency, rows read, and overall cost.
Within days of migrating, we found heavily used queries that had previously disappeared inside aggregate infrastructure metrics. We added missing indexes through our normal migration flow and could immediately see the effect in production.
Database optimization went from something triggered by an incident to something we could do continuously as part of building the product.
The reliability model improved too. Production now runs with a primary and two replicas instead of depending on a single database instance. Backups run every 12 hours, the previous storage-related latency pattern has disappeared, and launch traffic is handled through deliberate pooling rather than oversized idle capacity.
AWS RDS | PlanetScale | |
|---|---|---|
Architecture | Single primary | Primary and two replicas |
Peak traffic | Capacity planned around launch events | Designed to absorb changing workloads |
Write latency | Spikes reached 862 ms | Previous spike pattern eliminated |
Backups | Daily | Every 12 hours |
Query visibility | Aggregate infrastructure metrics | Per-query insights ranked by cost |
Operations | Capacity managed internally | Managed backups, replication, failover, and scaling |
The database also stopped being infrastructure we had to think about separately from the product.
PlanetScale handles backups, replication, failover, and the underlying database platform. We stay focused on schemas, queries, indexes, and migrations, the parts that directly affect how Coline behaves.
The tradeoffs
Managed infrastructure does not eliminate tradeoffs. It changes which ones you choose.
PlanetScale’s connection limits are stricter than the configuration we previously maintained on RDS. That forced us to make pooling an intentional part of the architecture instead of allowing connection counts to grow alongside the application.
The constraint improved the system. Connections now have clear ownership, predictable limits, and a better path for handling bursts of activity.
Some Postgres extensions are also unavailable. PlanetScale’s built-in tooling replaced the extension we relied on most for query analysis, but extension support remains something we consider when introducing new database features.
There is also the dependency that comes with every managed platform. A PlanetScale incident can become a Coline incident. In exchange, we get a team and platform focused specifically on operating Postgres reliably at scale.
For Coline, that is the right trade.
Where this goes
Coline Code made this move more important, not less.
Cloud Agents continuously create and update state across tasks, sessions, environments, commits, previews, walkthroughs, and pull requests. Kairo is becoming more deeply connected to every part of the workspace, and each new product introduces new patterns of database activity.
The database underneath Coline needs to support that growth without forcing the rest of the system to become less ambitious.
We would rather spend our attention making Coline faster, more reliable, and more useful than planning the next instance upgrade or watching storage burst balances.
Postgres remains at the centre of Coline. Operating it no longer needs to be.
Bring your team’s work into one place
Messages, mail, notes, tasks, and now code. Kairo handles the busywork.