Moving Vendora from Supabase to PlanetScale
We went in expecting documentation and a support queue. What we got was closer to having a database engineer on the project. — Gordon MacMaster, Vendora
About Vendora
Vendora is a B2B platform for grocery and consumable retail. A single Postgres database backs their entire product: point-of-sale terminals, kitchen displays, inventory management, the merchant portal, and customer storefronts.
Devices need to keep working when store connectivity drops, so Vendora runs an offline sync across its platforms. They keep a local SQLite copy on each device in sync by reading Postgres through a logical replication slot, as a dedicated role with a scoped publication.
Why Vendora left Supabase
Vendora was approaching its storage capacity on Supabase. The team wanted a clearer path for scale as its tenant count grew.
Cost and performance mattered most to them, especially as a startup, and for their workload they found PlanetScale had the best combination of the two.
Why PlanetScale
Compute is billed per millisecond. The throwaway cluster Vendora used to rehearse the migration cost a day of compute rather than a month's minimum.
Storage on EBS clusters autoscales, so capacity grows with the data.
Neki gives Vendora somewhere to go when sharded Postgres becomes the right answer. PlanetScale was also upfront that Neki would require an additional future (zero-downtime) migration.
When Vendora asked how to size production, PlanetScale compared its recommendation against what Vendora was already running and suggested starting smaller, with reads spread across replicas.
Being told Neki was a migration rather than a feature flag, and not worth discussing at our size, is how you end up trusting the rest of what someone tells you. — Gordon MacMaster, Vendora
Getting the cutover order right
Offline Sync was the part of the migration Vendora couldn't afford to get wrong. When they asked whether PlanetScale had migrated a setup like this before, the answer was no, followed by a request for details on exactly how it was wired to get Vendora the perfect solution.
Their offline sync used Postgres purely as a replication source. That meant the cutover could happen in three stages:
- Sync PlanetScale with Supabase through logical replication.
- Move the sync to PlanetScale while application writes keep going to Supabase.
- Cut the application over to PlanetScale once it's caught up.
The sync had to move before application writes did. Doing it the other way around would have left devices connected to a database that had stopped receiving changes.
Rehearsing on staging
Vendora moved staging a week ahead of production, into a cluster sized to match staging on Supabase, with the plan to wipe it afterward and repeat the exercise against production. Staging carries a fraction of production's data, so it wasn't expected to surface many capacity problems, but it caught a few wrong assumptions:
- The import guide assumed only the default Postgres schema. Vendora's data is spread across several schemas, and following the guide literally would have copied almost nothing.
- Three extensions had to exist on the target before the schema would load, in the same schemas they occupied upstream, or the database couldn't resolve their types (including Vendora's vector columns).
- Dump-and-restore didn't recreate the application's permissions, so the grants had to be reapplied.
This is precisely the reason practicing critical cutovers with staging is important, and recommended by PlanetScale.
The production migration
A few things didn't go to plan, but PlanetScale was there to help through the process.
Sequences
Logical replication in Postgres 18 and earlier doesn't include sequence values. Rows arrive with their original ids, but the destination's sequences do not automatically align with the sources. This means the replication can appear healthy until the application inserts a new row. Soon after cutover, inserts started failing with duplicate key value violates unique constraint: almost every sequence was still at its initial value, handing out ids that already existed. The fix was to set each sequence past the max id in its table with setval before the application starts writing. PlanetScale calls this out in their migration guide. Vendora missed it, but they were able to get a fix in quickly.
The Drizzle migration journal
Vendora uses Drizzle, which records each applied migration as a row in __drizzle_migrations. That table was in the publication, but logical replication doesn't include DDL. So when migrations ran against Supabase during the staging window, the schema changes stayed on Supabase while the journal rows replicated to PlanetScale. PlanetScale ended up with a journal saying all migrations had been applied, but two of the schemas those migrations created didn't exist. Drizzle reported nothing to run, and the team spent a while chasing a schema the Drizzle tooling said was already on the destination.
For production they left __drizzle_migrations out of the publication and copied it over manually at cutover, once they'd confirmed the destination schema matched.
Working with the PlanetScale team
Because every company's data and schema is unique, each migration presents unique challenges. Vendora was expecting to have to wade through all of this with docs and support tickets. However, PlanetScale provided hands-on support, much more like having a dedicated migration engineer. They worked through Vendora's architecture, figured out the cutover ordering, and read the PowerSync docs to find the application changes Vendora would need. That continued across time zones and through a conference week.
They were straight about what they hadn't done before, and then worked through the architecture with us rather than guessing at it.
— Gordon MacMaster, Vendora
The results
Within minutes of cutover, Vendora's production database was healthy, replicas were at zero lag, and their offline sync was streaming normally. A check-in twelve hours later showed all systems remained healthy, with no replication lag or outstanding issues.
- All services stayed online through both the staging and production migrations.
- Sizing was based on what Vendora was actually running, with the option to start smaller and spread reads across replicas.
- Storage grows with the data, so there's no capacity ceiling to plan around.
- Sharded Postgres with Neki is available on the same platform when tenant growth needs it.
Get started
Sign up to create a PlanetScale Postgres database, or reach out to talk with our team. If you're moving an existing database, we can help you migrate.
Thanks to Gordon MacMaster and the Vendora team for sharing their story.
← Back to all case studiesYour business deserves a predictable database
Never worry about another 3am wake-up call saying the site is down. Give your engineers the power they deserve with a PlanetScale database today.