---
title: "ElectricSQLとは？Postgres同期エンジンの仕組み・導入手順と2026年の変化"
url: "https://www.issoh.co.jp/tech/details/7220/"
published: 2025-06-12
updated: 2026-10-18
categories: ["データベース"]
publisher: "株式会社一創"
---

# ElectricSQLとは？Postgres同期エンジンの仕組み・導入手順と2026年の変化

ElectricSQLは、PostgreSQLのデータの一部を「Shape」という単位で切り出し、HTTP経由でブラウザやモバイルアプリへ流し続ける同期エンジンです。データベースそのものではありません。日本語の解説にはSQLiteとの双方向同期やCRDTによる競合解決を中心に説明するものが残っていますが、その構成は2024年7月の作り直しで廃止されています。さらに2026年9月にはホスティングのElectric Cloudが停止し、使うならセルフホストが前提になりました。この記事では2026年10月18日時点の公開済み最新版（同期サービス1.8.1）を基準に、仕組み、導入手順、書き込みと認証の設計、代替の同期エンジンとの違いまでを公式ドキュメントとGitHubの記録から整理します。

## まとめ

- ElectricSQLとして知られる同期エンジン（現行の製品ページではPostgres Sync）は、Postgresの論理レプリケーションで変更を受け取り、Shape単位でクライアントへ配信する**読み取り専用の同期エンジン**です。書き込みはアプリ側のAPIが担います。
- 旧版のSQLite双方向同期・CRDT・DDLXは2024年7月の作り直しで外れ、2025年3月17日に1.0が正式版になりました。公開済みの最新版は2026年9月7日の同期サービス1.8.1です。
- 導入の条件は、PostgreSQL 14以上、`wal_level=logical`、REPLICATION属性を持つロール、論理レプリケーションに対応する接続経路の4点です。
- Electric自体は利用者ごとの認可を行わず、シークレットを持つ接続元には同期用ロールが読めるデータへのアクセスを許すため、本番では`ELECTRIC_SECRET`を設定し、認可はアプリ側のプロキシで行います。プロキシを置くなら、HTTP/2まわりの不具合が直った1.8.1以上を使います。
- 2026年8月11日にElectricのDatabricks合流が発表され、Electric Cloudは9月下旬までに停止しました。オープンソース版は継続しています。

## ElectricSQLの旧版と現行版：同期方向と提供機能の違い

「ElectricSQL」で検索して見つかる情報は、2024年7月より前の旧版と現行版が混ざっています。どちらの説明かを先に見分けないと、存在しないAPIで設計を始めることになります。

### 2024年の作り直しで外れた機能の対照表

開発元は[2024年7月17日のブログ](https://electric.ax/blog/2024/07/17/electric-next)で、同期エンジンを一から作り直す方針（当初の名称はElectric Next）を発表しました。理由として、旧版は範囲が広すぎて安定させられず、利用者がDockerのネットワークやマイグレーションツール、クライアント側のビルドツールの問題に時間を取られていたと説明しています。

| 項目          | 旧版（0.x、2024年7月まで）    | 現行版（1.x）                       |
| ----------- | -------------------- | ------------------------------ |
| 同期の方向       | Postgresとクライアントの双方向  | Postgresからクライアントへの読み取りのみ       |
| クライアント側の保存先 | SQLite、PGliteなど      | 指定なし（メモリ、PGlite、TanStack DBなど） |
| 通信方式        | WebSocket（Satellite） | HTTP（キャッシュ可能）                  |
| 競合解決        | CRDTで自動              | 書き込みを受けるAPI側で設計                |
| 認可          | DDLXによる権限制御を構想（未実装）  | プロキシなど自前のHTTP認可                |
| npmパッケージ    | `electric-sql`（非推奨）  | `@electric-sql/client`ほか       |

旧版のコードは`electric-sql/electric-old`リポジトリ、ドキュメントは`legacy.electric-sql.com`に残っていますが、開発元は旧版をサポートしないと明言しています。npmの`electric-sql`パッケージ（最終版0.12.1）にも「同期エンジンを作り直した」という非推奨メッセージが付いています。`ALTER TABLE ... ENABLE ELECTRIC`、`npx electric-sql generate`による型付きクライアントの生成、`ElectricDatabase.init`が出てくる解説は旧版のものなので、現行版では動きません。

### 1.0正式版から1.8.1までのリリース経緯

作り直した版は2024年12月10日にBETA、[2025年3月17日に1.0.0](https://electric.ax/blog/2025/03/17/electricsql-1.0-released)となり、開発元は「APIは安定し、ミッションクリティカルな本番アプリで使える」と宣言しました。1.0の発表では、一般的なPostgres 1台で100万の同時接続クライアントまで遅延とメモリ使用量が横ばいだったというクラウドでのベンチマーク結果と、Trigger.devなどの本番利用例が挙げられています。

その後のリリースはほぼ週単位で続き、同期サービスは2026年9月1日に1.8.0、9月7日に1.8.1が出ました。TypeScriptクライアント`@electric-sql/client`は1.5.28、Reactフック`@electric-sql/react`は1.0.57です（いずれも9月9日公開）。1.8.0にはテレメトリのメトリクス名の接尾辞をマイクロ秒記号`μs`からASCIIの`us`へ変える破壊的変更が入っているため、監視ダッシュボードを組んでいる場合は更新前に名前を置き換えます。

1.8.1の後、10月18日まで[GitHub Releases](https://github.com/electric-sql/electric/releases)に同期サービスの新しい版は出ていません。リポジトリ上は10月2日に1.8.2（Dockerイメージへのラベル追加のみ）へ上がっていますが未公開で、10月上旬にはDocker Hubのリポジトリ障害でイメージを公開できない期間がありました（[PR #4825](https://github.com/electric-sql/electric/pull/4825)、10月6日に復旧）。

### 2026年のDatabricks合流とElectric Cloudの停止

開発元は2026年4月29日にAIエージェント向けのElectric Agentsを発表し、GitHubリポジトリの説明も「The agent platform built on sync.」に変わりました。ドキュメントは`electric-sql.com`から`electric.ax`へ移っています。

2026年8月11日には、[ElectricがDatabricksに合流する](https://electric.ax/blog/2026/08/11/electric-joining-databricks)と発表しました。合流先は、2025年にDatabricksが買収した[サーバーレスPostgresのNeon](/tech/details/16444/)のチームで、[Databricks](/tech/details/3557/)のマネージドPostgresであるLakebaseに同期の仕組みを加えるとしています。発表は、Postgres Sync（この記事で扱う同期エンジン）、PGlite、TanStack DB、Durable Streamsは既存のライセンスのままオープンソースを続け、ホスティングのElectric Cloudは終了に向かうと説明していました。

その停止はすでに済んでいます。9月28日にマージされた[PR #4810](https://github.com/electric-sql/electric/pull/4810)は「Electric Cloud has been shut down」と書き、クラウド向けのリリース処理を削除しました。同日の[PR #4812](https://github.com/electric-sql/electric/pull/4812)も、Electric Agentsのアプリに残るElectric Cloudへのサインインは動かないと注記しています。一方で、10月18日時点の公式サイトには料金ページ（`/pricing`）とクラウドの案内、デプロイガイドの「Electric Cloudが最も簡単な使い方」という囲み記事がまだ残っています。サイトからクラウドの記述を消すPRは未マージです。料金ページを見てマネージドで使えると判断しないでください。新しく採用するなら、**同期サービスと永続ストレージを自前で運用する前提**で評価します。

## Shapeを単位にした同期の仕組み

Electricが解決するのは「Postgresの一部のデータを、多数のクライアントへ、最新の状態のまま届ける」という問題です。部分レプリケーション、配信先への振り分け、データの配送を同期サービスが引き受けます。

### 論理レプリケーションからHTTPのShapeログまでの流れ

同期サービスはElixirで書かれたWebサービスで、Dockerイメージとして配布されています。Postgresには論理レプリケーションで接続し、[WAL（ライトアヘッドログ）](/tech/details/16285/)に書かれた変更を受け取ります。受け取った変更は、クライアントが要求しているShapeの条件に一致するものだけがShapeごとのログに追記され、クライアントはHTTPでそのログを読み進めます。データベースの変更を外部へ流すという点では[CDC（Change Data Capture）](/tech/details/15871/)と同じ系統の技術ですが、配信先がKafkaなどではなく、エンドユーザーのアプリである点が違います。

ShapeはSQLの`WHERE`句で絞った、1テーブル分の部分レプリカです。基本は`table`、`where`、`columns`の3つで定義します。`columns`を指定する場合は主キーを必ず含めます。

### /v1/shapeのパラメータとライブモード

ShapeはHTTPの`GET /v1/shape`で取得します。最初のリクエストは`offset=-1`でログの先頭から取得を始めます。データが大きい場合は複数の応答に分かれるため、応答ヘッダーの`electric-handle`（Shapeの識別子）と`electric-offset`（次に読む位置）を次のリクエストに付けて続きを読みます。

```
# 初回同期：todosテーブルを先頭から取得
curl -i 'http://localhost:3000/v1/shape?table=todos&offset=-1'

# 追いついた後：handleとoffsetを付けてライブモードで待機
curl -i 'http://localhost:3000/v1/shape?table=todos&live=true&handle=HANDLE&offset=OFFSET'
```

`live=true`を付けると、サーバーは新しい変更が届くまで接続を保持し（ロングポーリング）、タイムアウトした場合は`up-to-date`のメッセージだけを返します。ロングポーリングの代わりにServer-Sent Eventsを使う`live_sse`もあります。制御メッセージには、部分スナップショットの終了を示す`snapshot-end`などもあります。通常の同期で扱う`up-to-date`は「サーバーが把握していた全データを受け取った」、`must-refetch`は「手元のデータを捨てて最初から同期し直す」を意味します。クライアントライブラリはこれらを自動で処理するため、HTTPを直接叩くのは動作確認やクライアントの自作に限られます。

## 導入手順：PostgreSQLの要件確認からShape取得まで

同期サービスを起動する前に、Postgresの論理レプリケーション設定と接続ロールの権限を確認します。

### PostgreSQL側の4つの要件

[公式のデプロイガイド](https://electric.ax/docs/sync/guides/deployment)が挙げる要件は、PostgreSQL 14以上であること、論理レプリケーションが有効（`wal_level=logical`）であること、`REPLICATION`属性を持つロールで接続すること、の3点です。版は[PostgreSQLのバージョン確認方法](/tech/details/16965/)で先に確かめておきます。4点目は接続経路で、原則として**接続プーラーを経由しない直接接続**を選びます。多くの接続プーラーは論理レプリケーションに対応していないためです。公式ガイドはpgBouncerが1.23から論理レプリケーションに対応したことにも触れていますが、推奨はあくまで直接接続です。レプリケーション以外の問い合わせだけをプーラーに向けたい場合は`ELECTRIC_POOLED_DATABASE_URL`を別に指定します。

```
-- 現在の設定を確認（logical 以外なら変更が必要）
SHOW wal_level;

-- 変更はサーバーの再起動後に反映される
ALTER SYSTEM SET wal_level = 'logical';

-- 同期サービス用のロール
CREATE ROLE electric WITH LOGIN REPLICATION PASSWORD 'change-me';
```

マネージドPostgresの多くは`wal_level=logical`が既定で無効です。SQLではなく管理画面のパラメータ設定で変更するサービスもあるため、各サービスの手順に従ってください。publicationの作成などロールに追加で与える権限は構成によって変わるので、公式のPostgreSQL Permissionsガイドで自分の構成に合うものを選びます。

### Dockerでの同期サービス起動と動作確認

同期サービスは`electricsql/electric`イメージで起動し、既定のポートは3000です。公式手順の`latest`タグは更新のたびに中身が変わるため、ここでは版を固定しています。ホスティング各社のワンクリックテンプレートには`1.2.8`のような古い版を固定したものもあるので、使う前にタグを確かめます。

```
docker run \
  -e "DATABASE_URL=postgresql://electric:change-me@db.example.com:5432/app" \
  -e "ELECTRIC_INSECURE=true" \
  -p 127.0.0.1:3000:3000 \
  -t electricsql/electric:1.8.1
```

`ELECTRIC_INSECURE=true`はシークレットなしで動かす設定です。公式はネットワーク等でアクセスを制限した本番利用にも言及していますが、本記事では開発用途に限定します。本番では`ELECTRIC_SECRET`を設定し、同期サービスが書き出すShapeログの保存先`ELECTRIC_STORAGE_DIR`を再起動後も消えない永続ボリュームに置きます。起動後は、接続先に`todos`テーブルが存在し、同期用ロールに必要な権限があることを確認してから、前章の`curl`を実行します。さらに行を追加・更新し、その変更がライブ同期で届くことを確認します。PostgresごとDockerで試したい場合は、公式が配布する`docker-compose.yaml`を取得して`docker compose up`で起動する方法もあります。

Shapeが増えてメモリが足りなくなる場合は、[設定リファレンス](https://electric.ax/docs/sync/api/config)の`ELECTRIC_SHAPE_SUSPEND_CONSUMER`を`true`にすると、休止したまま一定時間（`ELECTRIC_SHAPE_SUSPEND_AFTER`、既定10分）使われないShapeの処理プロセスを終了させ、メモリを空けられます。代わりにCPU使用量がわずかに増え、サブクエリで他のShapeと依存し合うShapeは終了の対象になりません。

### Supabaseにつなぐときの直接接続URLとIPv6

SupabaseのPostgresは論理レプリケーションが有効で、Electricに必要な権限もそろっています。注意点は接続URLです。プール経由のURLは論理レプリケーションに対応していないため、Supabaseの接続設定で接続プーラーの表示をオフにし、直接接続のURLを使います。この直接接続URLはIPv6専用なので、Electric側に`ELECTRIC_DATABASE_USE_IPV6=true`を設定します。実行環境がIPv6を使えない場合は、SupabaseのProまたはTeamプランでIPv4アドオンを有効にする方法があります。

## TypeScript／ReactクライアントでのShape購読

アプリからは`@electric-sql/client`を使います。`ShapeStream`が変更メッセージの流れ、`Shape`がそれを適用した最新の行の集合です。

```
import { ShapeStream, Shape } from '@electric-sql/client'

type Todo = { id: string; title: string; done: boolean }

const stream = new ShapeStream<Todo>({
  url: 'http://localhost:3000/v1/shape',
  params: {
    table: 'todos',
    where: 'project_id = $1',
    params: ['p1'],
    columns: ['id', 'title', 'done'],
  },
})

const shape = new Shape(stream)
shape.subscribe(({ rows }) => {
  // rows は条件に一致する行の最新状態
  console.log(rows.length)
})
```

`where`に値を埋め込まず`params`で渡すと、SQLインジェクションを避けられます。Reactでは`@electric-sql/react`の`useShape`が同じ処理をフックにまとめています。

```
import { useShape } from '@electric-sql/react'

export function TodoList() {
  const { data, isLoading } = useShape<Todo>({
    url: new URL('/api/todos', location.origin).toString(),
    params: { table: 'todos' },
  })
  if (isLoading) return null
  return <ul>{data.map((t) => <li key={t.id}>{t.title}</li>)}</ul>
}
```

この例の`url`が同期サービスではなくアプリの`/api/todos`を向いているのは、後述する認可用のプロキシを通すためです。`url`には絶対URLを渡します。1.5.28のクライアントは`/api/todos`のような相対URLをそのまま`new URL()`に渡すため、ブラウザでも`Invalid URL`で同期が始まりません。どちらの例も`@electric-sql/client` 1.5.28と`@electric-sql/react` 1.0.57の型定義に対して型検査が通ることを確認しています。

## 書き込みの設計：4つのパターンとTanStack DBとの組み合わせ

[公式の書き込みガイド](https://electric.ax/docs/sync/guides/writes)は「Electricは読み取り側の同期を行い、書き込み側の同期は行わない」と明記しています。書き込みはアプリのAPIを通してPostgresに入れ、その結果がShape経由でクライアントに戻ってくる、という一方向の流れで設計します。ガイドは実装の重さの順に4つのパターンを示しています。

| パターン            | オフライン書き込み   | 向く用途             |
| --------------- | ----------- | ---------------- |
| 1\. オンライン書き込み   | 不可          | 閲覧中心のアプリ、ダッシュボード |
| 2\. 楽観的状態       | 可（リロードで消える） | 回線が不安定なモバイル      |
| 3\. 共有・永続の楽観的状態 | 可           | SaaS、共同作業ツール     |
| 4\. ローカルDB経由の同期 | 可           | ローカルファースト、デスクトップ |

4番目はPGliteなどの組み込みDBに読み書きし、変更をバックグラウンドで送る方式です。アプリのコードはネットワークを意識しなくて済みますが、公式ガイド自身が、依存が重いこと、クライアント側のスキーマ定義が複雑になること、ロールバックの扱いが難しくなることを欠点に挙げています。まず1か2で始め、オフライン書き込みが要件になった時点で3に進むのが無理のない順序です。

2と3を自前で組む代わりに、Electricと共同開発されている[TanStack DB](/tech/details/8738/)を使う方法があります。`@tanstack/electric-db-collection`の`electricCollectionOptions`でShapeを読み込み、書き込みハンドラーの中で、APIが返したトランザクションIDの同期を待ちます。次の例は1件の挿入を想定し、`Todo`型には前の例の定義を使います。`api.create`は、行を保存して同じトランザクションのIDを返すアプリ側の関数として別途実装します。

```
import { createCollection } from '@tanstack/db'
import { electricCollectionOptions } from '@tanstack/electric-db-collection'

export const todos = createCollection(
  electricCollectionOptions({
    id: 'todos',
    getKey: (item: Todo) => item.id,
    shapeOptions: { url: new URL('/api/todos', location.origin).toString(), params: { table: 'todos' } },
    onInsert: async ({ transaction, collection }) => {
      const res = await api.create(transaction.mutations[0].modified)
      await collection.utils.awaitTxId(res.txid)
    },
  })
)
```

待っていたトランザクションIDの変更がShapeで届いた時点で、楽観的に表示していた行が同期済みの行に置き換わります。この書き方は2026年10月に変わりました。9月14日公開の0.4.10までは、ハンドラーから`{ txid: res.txid }`を返す書き方が標準でしたが、10月15日公開の0.6.1の型定義では「`{ txid }`を返す書き方は非推奨で、v1.0で削除する」と注記され、ハンドラー内で`collection.utils.awaitTxId()`を待つ書き方が推奨になっています。古い書き方も型検査は通りますが、新しく書くなら`awaitTxId`を使います。上の例は`@tanstack/db` 0.15.0と`@tanstack/electric-db-collection` 0.6.1で型検査が通ることを確認しています。

ここで失敗しやすいのがトランザクションIDの取得場所です。TanStack DBのドキュメントによると、`pg_current_xact_id()`を書き込みと同じトランザクションの**内側**で取得しないとIDが一致せず、確定待ちが既定の15秒でタイムアウトします。また、APIが返すIDは、公式例の`pg_current_xact_id()::xid::text`のように32ビットのxidへ変換し、数値として返します。

## 認証とセキュリティ：Electricを直接公開しない構成

[公式のセキュリティガイド](https://electric.ax/docs/sync/guides/security)はデータの公開範囲に注意を促しています。設定リファレンスでは、`ELECTRIC_INSECURE=true`を指定しない限り`ELECTRIC_SECRET`が必須です。ただし、この共通シークレットだけでは利用者ごとのアクセス範囲を制限できません。ブラウザから同期サービスへ直接つながせる構成は取らず、アプリのAPIを前段に置きます。公式が推奨する方式は2つです。

- プロキシ認可：Shapeのリクエストをアプリのプロキシで受け、ユーザーを認証し、`table`と`where`をサーバー側で決めてから同期サービスへ転送する。
- ゲートキーパー認可：先にアプリのAPIでShape専用のトークンを発行し、以降のShapeリクエストではプロキシがそのトークンだけを検証する。認可の判定にDB検索が要る場合に向く。

### プロキシ認可の実装例

プロキシ認可の要点を、公式サンプルをもとにWeb標準の`Request`／`Response`で書くと次のようになります。

```
import { ELECTRIC_PROTOCOL_QUERY_PARAMS } from '@electric-sql/client'

export async function GET(request: Request) {
  const url = new URL(request.url)
  const origin = new URL('/v1/shape', process.env.ELECTRIC_URL ?? 'http://localhost:3000')

  // クライアントからは同期プロトコル用のパラメータだけを通す
  url.searchParams.forEach((value, key) => {
    if (ELECTRIC_PROTOCOL_QUERY_PARAMS.includes(key)) origin.searchParams.set(key, value)
  })

  const user = await authenticate(request) // 自前の認証処理
  if (!user) return new Response('unauthorized', { status: 401 })

  // テーブルと絞り込み条件、シークレットはサーバー側で付ける
  origin.searchParams.set('table', 'todos')
  origin.searchParams.set('where', '"org_id" = $1')
  origin.searchParams.set('params[1]', user.orgId)
  origin.searchParams.set('secret', process.env.ELECTRIC_SECRET ?? '')

  const res = await fetch(origin, { signal: request.signal })
  const headers = new Headers(res.headers)
  headers.delete('content-encoding')
  headers.delete('content-length')
  headers.append('Vary', 'Authorization, Cookie')
  return new Response(res.body, { status: res.status, headers })
}
```

`ELECTRIC_PROTOCOL_QUERY_PARAMS`の中身は、1.5.28では`live`、`live_sse`、`handle`、`offset`、`cursor`、`log`と、部分スナップショット用の`subset__where`などを合わせた16個で、`table`や`where`は含まれません。クライアントが別のテーブル名を送ってきても転送されないため、見せてよい範囲をサーバー側で固定できます。`content-encoding`と`content-length`を消しているのは、`fetch`が本文を展開した後もこれらのヘッダーが残り、ブラウザ側で解凍に失敗するのを防ぐためです。

### プロキシを置くなら1.8.1以上にする理由

プロキシやロードバランサーが多数のクライアントを少数のHTTP/2接続にまとめて同期サービスへ送る構成では、1.8.0と1.8.1でそれぞれ修正された別の不具合がありました。[1.8.1のリリースノート](https://github.com/electric-sql/electric/releases/tag/%40core%2Fsync-service%401.8.1)によると、同期サービスは「1つの接続で10秒間に500回を超えるストリームのリセット」を検知すると接続ごと切っていたため、ブラウザがライブ要求を取り消すだけでこの上限に達し、同じ接続に乗っていた無関係のクライアントのロングポーリングまで切れていました。1.8.1はこの制限を既定で無効にし、必要な場合だけ`ELECTRIC_TWEAKS_HTTP2_MAX_RESET_STREAM_RATE`で有効にする形に改めています。1.8.0でも、HTTP/2接続にHTTP/1向けの要求数上限（既定50）が適用されて接続が切れる不具合が直っています。前章の構成でElectricをプロキシの裏に置くなら、1.8.1未満は選ばないでください。

## PowerSync・Zero・Supabase Realtimeとの方式の違い

旧版のElectricに期待されていた「端末のSQLiteで読み書きし、裏で同期する」構成を今から作るなら、Electric以外の同期エンジンが候補に入ります。名前が並べて語られる3つを、同期の向きと書き込みの経路で比べると次のとおりです（2026年10月18日時点）。

| 項目          | Electric（Postgres Sync） | PowerSync                    | Zero                   | Supabase Realtime |
| ----------- | ----------------------- | ---------------------------- | ---------------------- | ----------------- |
| 端末側に持つもの    | Shapeの行（保存先は任意）         | SQLite                       | クエリ結果のキャッシュ            | 受け取った変更イベント       |
| 書き込みの経路     | アプリのAPI（自前）             | アップロードキュー→uploadData()→自前API | mutator（端末とサーバーの両方で実行） | 対象外（DBへ直接）        |
| 元のDB        | Postgres 14以上           | Postgres、MongoDBほか           | Postgres 15以上          | SupabaseのPostgres |
| サーバー側のライセンス | Apache-2.0              | FSL-1.1-ALv2                 | Apache-2.0             | Apache-2.0        |
| 版（10月18日時点） | 1.8.1                   | Service 1.27.0               | 1.11.0                 | Supabaseに内蔵       |

[PowerSyncのクライアント設計](https://docs.powersync.com/architecture/client-architecture)は、端末のSQLiteへの変更をアップロードキューに積み、開発者が実装する`uploadData()`から自分のバックエンドAPIを呼んで元のDBへ保存する方式です。オフライン中の書き込みを端末に溜めておく仕組みがSDKに入っている点が、Electricとの一番の違いです。元のDBはPostgresとMongoDBのほか、MySQLとSQL Server（いずれもBeta）にも広がっています。サーバー側のPowerSync ServiceはFSL-1.1-ALv2（一定期間後にApache 2.0へ移る条件付きのライセンス）なので、Apache 2.0のElectricと同じ感覚で商用利用を判断しないでください。

[Zero](https://zero.rocicorp.dev/docs/connecting-to-postgres)はReplicacheの開発元Rocicorpの同期エンジンで、2026年3月に正式版（GA）になりました。書き込みはmutatorという関数で行い、同じmutatorを端末側とアプリのサーバー側の両方に置いて、端末では即座に反映し、サーバーで確定させます。PostgreSQLは15以上を要求し、Electricより1世代上です。

[Supabase Realtime](/tech/details/17058/)のPostgres Changesは、`wal2json`を使う一時的なレプリケーションスロットをポーリングし、購読中のクライアントへ変更イベントを配る仕組みです。RLSを有効にしたテーブルでは読み取り権限に応じて配信されますが、DELETEイベントにはRLSポリシーが適用されません。届くのは変更そのもので、初回のデータは別にクエリして取ります。

選び方を一言でいえば、**Postgresを正本に読み取りを高速化したいだけならElectric、端末のSQLiteでオフライン書き込みまで完結させたいならPowerSync、書き込みの楽観的反映をフレームワークに任せたいならZero**です。Electricで書き込みまで楽観的に扱いたい場合は、前章のTanStack DBを組み合わせます。

## 採用判断：ElectricSQLが向く構成と向かない構成

Electricが力を発揮するのは、**Postgresが正本で、読み取りが書き込みより圧倒的に多く、画面を常に最新に保ちたいアプリ**です。管理画面、ダッシュボード、チームで共有するタスクや案件の一覧が典型で、APIを都度呼ぶ代わりにローカルのShapeから描画するため、画面遷移のたびに通信を待つ必要がなくなります。HTTPで配信するのでCDNやキャッシュ用プロキシを前に置けるのも、WebSocket型の仕組みにない利点です。

次の条件に当てはまる場合は採用を見送るか、別の選択肢を先に検討してください。

- オフライン中の書き込みをPostgresとの間で自動マージしたい：現行のElectricは書き込み側を担わず、競合解決は自分で設計することになります。旧版の双方向同期を期待して選ぶと、要件を満たせません。
- ホスティングに任せたい：Electric Cloudは停止済みです。同期サービスと永続ストレージを自前で運用する体制が無ければ、運用の負担がそのまま残ります。
- 論理レプリケーション非対応の接続プーラー経由でしかPostgresにつなげない：直接接続など、論理レプリケーションに対応する接続経路を用意できなければ動きません。
- 通知やチャットのように、変更イベントを受け取れば十分：行の集合をクライアントに保持する必要がないなら、[Supabase Realtime](/tech/details/17058/)のようなイベント配信の仕組みで足ります。

既存のPostgresに同期の層を足すときは、論理レプリケーションの設定、publicationに載せるテーブル、Shapeの条件に使う列の索引までを含めてデータベース側の設計を見直すことになります。設計や移行の進め方に迷う場合は、[データベース設計・移行支援](/service/system/database/)で相談を受け付けています。

## よくある質問

### ElectricSQLとSupabaseは一緒に使えますか？

使えます。SupabaseのPostgresは論理レプリケーションが有効で、Electricに必要な権限もそろっています。同期サービスはSupabaseの外（自前のサーバーやコンテナ基盤）で動かし、接続にはプール経由ではなく直接接続のURLを使います。直接接続URLはIPv6専用なので、`ELECTRIC_DATABASE_USE_IPV6=true`を設定するか、ProまたはTeamプランのIPv4アドオンを使います。行の同期はElectric、認証は[Supabase Auth](/tech/details/17245/)という分担も可能ですが、その場合もShapeのリクエストは自前のプロキシで認可します。

### ElectricSQLはSQLiteと同期できますか？

SQLiteとの同期は2024年7月に廃止された旧版の機能で、現行版のクライアントはSQLiteを前提にしていません。Shapeで受け取った行をどこに保持するかはアプリ側で選びます。ブラウザ内でSQLを使いたい場合は、同じ開発元のWASM版Postgresである[PGlite](/tech/details/6351/)と、Shapeを取り込むための`@electric-sql/pglite-sync`パッケージを組み合わせる構成が公式に用意されています。なお、同期サービスはサーバー側でShapeの管理情報をSQLiteに保存していますが、これは内部の保存先で、クライアントのSQLiteと同期する機能ではありません。

### ElectricSQLはCRDTで競合を解決しますか？

現行版は解決しません。CRDTによる競合解決は旧版の機能です。現行のElectricは読み取り側の同期だけを行い、書き込みはアプリのAPIを経由してPostgresに入るため、同じ行への同時更新をどう扱うかはAPIとPostgresのトランザクションで決めます。共同編集のテキストのようにCRDTが必要なデータには、Yjsと組み合わせるための`@electric-sql/y-electric`パッケージが別に公開されています。

### ElectricSQLは無料で使えますか？ライセンスは？

同期エンジンはApache License 2.0のオープンソースで、セルフホストすればライセンス費用はかかりません。2026年8月11日の発表でも、Postgres Sync、PGlite、TanStack DB、Durable Streamsは既存のライセンスのまま公開を続けるとしています。有料だったのはホスティングのElectric Cloudで、2026年9月下旬までに停止しました。公式サイトに料金ページが残っていても申し込めるサービスではないので、新規の採用ではセルフホストの運用費（同期サービスのサーバーと永続ストレージ）を見積もってください。

### ElectricSQLのGitHubリポジトリと公式ドキュメントはどこですか？

ソースコードは[GitHubのelectric-sql/electric](https://github.com/electric-sql/electric)で、同期サービス、TypeScriptクライアント、Reactフック、サンプル、Electric Agentsのパッケージが同じリポジトリにあります。2026年10月18日時点のスター数は、GitHub APIの値で10,400です。[公式ドキュメント](https://electric.ax/docs/sync/)は`electric.ax`に移っており、旧ドメインの`electric-sql.com`からは転送されます。`legacy.electric-sql.com`は廃止された旧版の資料なので、現行版の実装には使わないでください。

## 関連記事

- [TanStack DBとは？TanStack Queryとの違い・使い方とv0.9系の注意](/tech/details/8738/)
- [pgliteとpgvectorでDocker不要のローカル類似度検索を実装する](/tech/details/6351/)
- [Neonとは？サーバーレスPostgresの構成・料金と採用判断を実装目線で解説](/tech/details/16444/)
- [Supabase Realtimeの実装｜3方式の使い分けとRLS併用・同時接続の上限](/tech/details/17058/)
- [CDC（Change Data Capture）とは？3方式の仕組み・実装設定と採用判断を実装者目線で解説](/tech/details/15871/)

---

出典: [ElectricSQLとは？Postgres同期エンジンの仕組み・導入手順と2026年の変化](<https://www.issoh.co.jp/tech/details/7220/>)（株式会社一創）
