Skip to content

ADR 001: Self-hosted PostgreSQL instead of Supabase

Source: g2labs-in/linode-infra@4812f10 · docs/adr/001-self-hosted-postgres.md · updated 2026-05-26

Date: 2026-05-25 Status: accepted

Context

Billuu was using Supabase free tier for PostgreSQL. The database is hosted in aws-1-ap-south-1 (Singapore), while the application VPS is in ap-west (Mumbai). This geographic distance causes high latency for every database query, degrading the POS application experience.

Additionally, Supabase free tier imposes connection limits, storage limits, and pauses inactive projects — unacceptable for a production SaaS.

Decision

Deploy a self-hosted PostgreSQL 18 instance on a dedicated Linode VPS in the same region (ap-west/Mumbai) as the application server, connected via Tailscale private network for zero-latency, encrypted communication.

Alternatives considered

OptionProsConsRejected because
Upgrade Supabase tierNo infra workStill remote latency, ongoing costDoesn’t solve latency
PostgreSQL on same VPSZero extra costSingle point of failure, DB competes with app for RAMNo fault isolation
Managed DB (Linode Managed)Automatic backups, HAHigher cost, less controlBudget constrained ($100 credit)
Self-hosted on dedicated VPSLow latency, full control, scalableManual backup setup neededChosen

Consequences

  • Positive: Sub-millisecond DB latency (same data center on Tailscale), full control over extensions and config, no vendor lock-in
  • Negative: Manual backup management required, no automatic failover (acceptable for early stage with zero paying users)
  • Neutral: Added $12/mo to infra cost ($36/mo total)