Skip to content

8. Migrate from Supabase to Neon Database

Date: 2025-10-24

Status

Proposed

Context

During our production database migration to Supabase, the database became inaccessible during a backup restoration operation. After five days of support engagement, the database remains unavailable and backups appear to have been accidentally deleted. Fortunately, this occurred before we started using the production database, so no customers or revenue were affected.

This incident revealed a critical concern:

  • Backup Vulnerability: Backups can be accidentally deleted by support or operations

Decision

Migrate from Supabase to Neon serverless PostgreSQL before production deployment.

Why Neon:

  1. Immutable Backups: 30-day point-in-time recovery that cannot be accidentally deleted
  2. Serverless-First: Built for Vercel/Next.js with fast cold starts (<100ms) and automatic scaling
  3. Database Branching: Git-like workflow for safe testing of schema changes
  4. 100% PostgreSQL Compatible: All custom functions, RLS policies, and indexes work identically

Migration Approach:

  • Apply the existing schema to Neon
  • Copy the only used tables: cargos_states and cargos_citizenship
  • Minimal code changes (Prisma already abstracts database layer)

Alternatives Considered:

  • Stay with Supabase: Reliability concerns remain; as of this ADR’s creation, the production account is still inaccessible
  • AWS RDS: Higher cost ($400-800/month), operational overhead, poor serverless fit
  • PlanetScale: Their PostgreSQL service was just launched and is quite limited. For example, it’s not available in all regions and their PGBouncer doesn’t support replicas; all queries are sent to the main server.
  • Self-hosted: Unacceptable operational burden

Consequences

Benefits

  • Improved Reliability: Multi-AZ storage with immutable backups prevents accidental data loss
  • Better Architecture: Serverless-native design optimized for our Vercel deployment
  • Developer Productivity: Database branching enables safe testing of migrations

Risks & Mitigations

  • Data Loss During Migration: Maintain Supabase for 7 days post-cutover
  • Custom Functions: Recreate snowflake_id() function and test thoroughly in staging
  • RLS Policies: Document and recreate all 3 RLS policies before cutover
  • Performance: Load test staging with production-like traffic before migration

Migration Tasks

  1. Set up Neon staging database and apply Prisma schema
  2. Configure logical replication from Supabase to Neon
  3. Test all custom functions and RLS policies
  4. Update connection strings and deploy to production
  5. Monitor for 48 hours post-cutover; keep Supabase running for 7 days as safety net