Self-hosted PostgreSQL vs Supabase 比較

自分のサーバーで稼働する、1986年から成熟を重ねてきたオープンソースのリレーショナルデータベース

VS
Supabase

本物のPostgreSQLの上に構築された、マネージド型オープンソースバックエンドプラットフォーム

17 分で読了データベース

クイック結論

この決定に唯一の正解はない。小規模なチームでスピードを最優先するなら、Supabaseが正しい選択だ。認証、ストレージ、リアルタイム、コネクションプーラーが用意されている。負荷が予測可能な場合、データ所在地の制約がある場合(17リージョンにトルコは含まれない)、あるいはコストがユーザー数に応じて増える場合は、自前ホスティングのPostgreSQLに軍配が上がる。注意点が一つある。公式ドキュメントは、セルフホストではマネージドのバックアップ/PITRが無効になると記している — 制御権とともにリストアリハーサルも引き受けることになる。バックアップを取ることが基準なのではなく、実際に復旧できることこそが基準だ。

Self-hosted PostgreSQLSupabase
結論をすべて読む

スコア比較

グラフを読み込み中...

詳細スコア

詳細スコア: Self-hosted PostgreSQL Supabase — カテゴリー別10点満点のスコア
カテゴリーSelf-hosted PostgreSQLSupabase
パフォーマンス
8/10
8/10
学習のしやすさ
5/10
8/10
エコシステム
9/10
8/10
コミュニティ
9/10
9/10
求人市場
8/10
7/10
将来性
8/10
8/10

長所と短所

Self-hosted PostgreSQL

長所

  • ソフトウェアは完全に無料(PostgreSQLライセンス)— コストはインフラ費用に固定される
  • 完全な拡張機能の自由:pgvector、PostGIS、pg_cronなど好きなものをインストールできる
  • データは物理的に選んだサーバー上に留まる — データ所在地を直接コントロールできる
  • PITRはコア機能(WALアーカイブ + pg_basebackup)
  • ベンダーロックインがない — すでに自分のインフラ上にいるため
  • メジャーバージョンは5年間公式サポートされ、パッチスケジュールが予測可能
  • RLSは9.5以降コア機能であり、自由に活用できる

短所

  • Auth、Storage、Realtimeはコアに含まれない — 別途構築・運用する必要がある
  • コネクションプーリングにはPgBouncer/Supavisorのような別ツールが必要
  • バックアップ/PITR/HA/監視はすべて自己責任で、公式SLAは存在しない
  • 学習曲線がより急:auth+プーリング+HAを手動で構築するには時間がかかる
  • 公式な導入事例やベンチマークページは公開されていない(コミュニティプロジェクトのため)

最適な用途

固定で予測可能な予算が必要な中〜大規模プロジェクトKVKK/データ所在地が契約上の要件になっているシステムpgvector/PostGISのような特殊な拡張機能の組み合わせが必要な案件DevOpsの余力があり、リストアリハーサルをスケジュールできるチームベンダー非依存性が重要な、長期にわたるプロジェクト

Supabase

長所

  • Auth、Storage、Realtime、Data APIがあらかじめ用意されている — 認証レイヤーをゼロから書く必要がない
  • Freeプランなら月額$0から始められる(500MB DB、5GBのegress、5万MAU)
  • Dedicated/Sharedプーラーの選択肢でコネクションプーリングが標準搭載(Supavisor)
  • HIPAA(BAA)、ISO 27001、GDPR DPAなど、あらかじめ用意されたコンプライアンス認証
  • Health Check Advisorsによりサービスのエラー率が自動監視される(2026年9月)
  • Grafana Cloudとのワンクリック連携によるオブザーバビリティ(2026年7月)
  • 内部で本物のPostgreSQLが動いているため、pg_dumpで移行可能でベンダーロックインが低い

短所

  • コストはユーザー数・データ量の増加に応じて段階的に増える($0.125/GBディスク、$0.09/GB egress、$0.00325/MAU)
  • 17のリージョンの中にトルコは含まれない — KVKKの観点で国外へのデータ移転という論点が生じる
  • Freeプランには自動バックアップがなく、Proプランでも7日間のみ
  • 拡張機能はプラットフォームがキュレーションしたカタログに限定され、OSレベルの完全な自由度はない
  • セルフホストの選択肢は「コミュニティサポート」— 公式SLAはなく、マネージドのバックアップ/PITRは無効になる

最適な用途

一人、または少人数チームでの迅速なゼロからイチへの立ち上げAuth/Storage/Realtimeをゼロから構築したくないプロダクトチームHIPAA/ISO 27001/GDPRなど、既製の認証が必要なプロジェクトマネージドの監視と自動エラー率アラートを求めるチームpg_dumpによるベンダー非依存性を保ちながら素早く始めたい人々

コード比較

Self-hosted PostgreSQL
# セルフホストPostgreSQL - WALアーカイブ + PITR構築 (postgresql.conf)
wal_level = replica
archive_mode = on
archive_command = 'test ! -f /var/backups/pg_wal_archive/%f && cp %p /var/backups/pg_wal_archive/%f'
max_wal_senders = 3

# ベースバックアップを取得 (pg_basebackup)
pg_basebackup -D /var/backups/base -Ft -z -P -U replicator -h localhost

# PITR: 特定の時刻へ復元する (recovery.signal + postgresql.conf)
# 1) ベースバックアップをリストアディレクトリに展開する
# 2) 以下の行をpostgresql.confに追加し、recovery.signalファイルを作成する
restore_command = 'cp /var/backups/pg_wal_archive/%f %p'
recovery_target_time = '2026-09-23 09:00:00+03'

# pg_hba.conf - アプリケーションサーバーからの接続のみ許可
host    appdb    app_user    10.0.0.5/32    scram-sha-256

-- SQL (psql): 拡張機能のインストール (完全な自由 - セルフホスト特有)
CREATE EXTENSION IF NOT EXISTS vector;
CREATE EXTENSION IF NOT EXISTS postgis;
CREATE EXTENSION IF NOT EXISTS pg_cron;

# コネクションプーリング (PgBouncer, pgbouncer.ini)
[databases]
appdb = host=127.0.0.1 port=5432 dbname=appdb
[pgbouncer]
pool_mode = transaction
max_client_conn = 500
default_pool_size = 25
Supabase
-- SQL (Supabase SQL Editor): 1) テーブルを作成しRLSを有効化する (Data APIがこれを必須にする)
create table public.notes (
  id uuid default gen_random_uuid() primary key,
  user_id uuid references auth.users not null,
  content text not null,
  created_at timestamptz default now()
);
alter table public.notes enable row level security;

create policy "kullanicilar kendi notlarini okur"
  on public.notes for select
  using (auth.uid() = user_id);

create policy "kullanicilar kendi notlarini yazar"
  on public.notes for insert
  with check (auth.uid() = user_id);

// 2) supabase-jsでクエリを実行する (RLSは自動的に適用される)
import { createClient } from '@supabase/supabase-js'

const supabase = createClient(
  process.env.SUPABASE_URL!,
  process.env.SUPABASE_ANON_KEY!
)

const { data: notes, error } = await supabase
  .from('notes')
  .select('id, content, created_at')
  .order('created_at', { ascending: false })

// 3) Postgresクライアントでの接続文字列 (公式の "Endpoints and IP versions" テーブルより)
// Direct connection (永続的なバックエンド、pg_dump、マイグレーション向け):
// postgresql://postgres:[YOUR-PASSWORD]@db.[PROJECT-REF].supabase.co:5432/postgres
// Dedicated pooler (transactionモードのみ、有料プラン限定):
// postgresql://postgres:[YOUR-PASSWORD]@db.[PROJECT-REF].supabase.co:6543/postgres
// 文字列を手動で組み立てる場合: Dashboard > Connect画面からコピーする (shared poolerのホスト名はリージョンから導出できない)。

結論

この決定に唯一の正解はない。小規模なチームでスピードを最優先するなら、Supabaseが正しい選択だ。認証、ストレージ、リアルタイム、コネクションプーラーが用意されている。負荷が予測可能な場合、データ所在地の制約がある場合(17リージョンにトルコは含まれない)、あるいはコストがユーザー数に応じて増える場合は、自前ホスティングのPostgreSQLに軍配が上がる。注意点が一つある。公式ドキュメントは、セルフホストではマネージドのバックアップ/PITRが無効になると記している — 制御権とともにリストアリハーサルも引き受けることになる。バックアップを取ることが基準なのではなく、実際に復旧できることこそが基準だ。

無料相談を受ける
FAQ

よくある質問

Supabaseは標準的なPostgreSQLを使用しているため、`pg_dump`/`pg_dumpall`、またはネイティブなPostgresレプリケーションを使ってエクスポートできる。公式ドキュメントでは、プロジェクト間の移行手順をNode.jsスクリプトの例(認証・ストレージを含む)で説明している。Auth、Storage、Realtimeのようなsupabase固有のサービスをセルフホスト側で再構築すること(公式のセルフホストDocker Composeスタックを稼働させること)は別の作業であり、データ移行とサービスの機能パリティを揃えることは異なるステップだ。

関連ブログ記事

すべての記事を見る
すべての比較