Supabaseの無料プランは非常に便利ですが、一定期間アクセスやAPIリクエストが発生しないと「inactive」と判断され、プロジェクトが一時停止(ポーズ)される仕様があります。小規模な会員サイトや検証環境、特典サイトなどでは、利用頻度が低いタイミングもあるため、気づかないうちに停止してしまうケースも少なくありません。
今回の記事では、Supabase無料プランの一時停止を防ぐために、GitHub Actionsを活用して定期的に自動アクセス(Heartbeat)を行う方法を解説します。シンプルな設定で、手動復旧の手間を減らし、安定した運用を実現するための具体的な手順をご紹介します。
実際、私も小規模の会員サイトやResendと連携してフォーム送信データの保存として supabase を使うことが多いです。しかし、APIリクエストが少ないと一時停止されることがあるので、それを防ぐための施策となります。(自分への備忘録も兼ねて記事に整理しています)
Supabase 側で “軽いSELECT先” を用意
まず、Supabase側でテーブルを作成します。最低限のテーブルを以下の方法で作成します。 以下のAとBを順番に行います
A. healthcheck テーブルを作る(SQLでOK)
Supabase SQL Editor で以下を実行します
create table if not exists public.healthcheck (
id bigint generated always as identity primary key,
created_at timestamptz not null default now()
);
insert into public.healthcheck default values;B. RLS を有効化&匿名(anon)でSELECTだけ許可
Aでテーブルができたら、以下を実行します。
alter table public.healthcheck enable row level security;
create policy "allow anon select healthcheck"
on public.healthcheck
for select
to anon
using (true);
メモ
これで anon key で SELECT だけできるようになります(安全ですね)。
GitHub Secrets を追加
GitHubに進み、空のリポジトリを1つ新規作成します。visibility はプライベートで良いです。 Initialize with README:ON にしておきます。

次に 環境変数を入れる必要があります。
リポジトリの Settings > Actions secrets and variables > Repository secrets に進みます。

以下のデータをSupabaseから取得して挿入します。
| Name | Value |
|---|---|
| SUPABASE_URL | https://xxxx.supabase.co |
| SUPABASE_ANON_KEY | anon key |
SupabaseのAPIは 各 Projects の API設定から確認できます。
動作ファイルの作成
リポジトリトップで
Add file → Create new file
ファイル名に そのまま これを入力します。
.github/workflows/supabase-heartbeat.yml を入力します
そうすると、以下のように自動的に階層のフォルダが作成されます。素晴らしいですね。

そして、作成された 中身に、以下の workflow YAML を貼り付けます。
name: Supabase Heartbeat
on:
schedule:
# 毎週 月・木 に実行(UTC)
# 例: 03:15 UTC = 12:15 JST
- cron: "15 3 * * 1,4"
workflow_dispatch: {}
jobs:
ping:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Ping Supabase (REST select)
env:
SUPABASE_URL: ${{ secrets.SUPABASE_URL }}
SUPABASE_ANON_KEY: ${{ secrets.SUPABASE_ANON_KEY }}
run: |
set -euo pipefail
if [ -z "${SUPABASE_URL:-}" ] || [ -z "${SUPABASE_ANON_KEY:-}" ]; then
echo "Missing SUPABASE_URL or SUPABASE_ANON_KEY secrets."
exit 1
fi
ENDPOINT="${SUPABASE_URL}/rest/v1/healthcheck?select=id&limit=1"
echo "Requesting: ${ENDPOINT}"
# curl with retry
http_code=$(curl -sS -o /tmp/resp.json \
-w "%{http_code}" \
--retry 3 --retry-delay 2 --retry-all-errors \
-H "apikey: ${SUPABASE_ANON_KEY}" \
-H "Authorization: Bearer ${SUPABASE_ANON_KEY}" \
-H "Accept: application/json" \
"${ENDPOINT}")
echo "HTTP: ${http_code}"
cat /tmp/resp.json || true
if [ "${http_code}" -lt 200 ] || [ "${http_code}" -ge 300 ]; then
echo "Supabase heartbeat failed."
exit 1
fi
echo "Supabase heartbeat OK."貼り付けたら コミット変更を保存します。 以下のようなファイル構成になっていればOKです

Actionの設定
次に、 Actionのタブに進みます。そうすると、先ほど作成した Supabase Heartbeat というアクションが表示されていると思います

そしたら、 右側に表示されいている Run workflow をクリックして実行します
メモ
押して緑チェックマークが表示する → Supabaseへのアクセスも成功
これで設定は完了です。
これで何が保証されるか
週2回(cron)で Supabase にアクセスしてくれます。 SUpabaseのテーブルに自分でアクセスしなくても スクリプトが自動的にアクセスしてくれますので、無料枠の一時停止を避けることができます。
まとめ
Supabaseの無料プランは非常に使いやすく、小規模なアプリや会員サイト、検証環境などには最適な選択肢です。しかし「一定期間アクティビティがないと一時停止される」という仕様を理解していないと、ある日突然ログインできなくなったり、APIが動かなくなったりといったトラブルにつながる可能性があります。
今回ご紹介したように、GitHub Actionsを使って定期的に軽いリクエストを送る仕組みを作っておけば、手動で確認する必要もなく、安定した状態を保つことができます。設定も一度行えば基本的に放置で問題ありません。
無料プランを安心して長く使い続けるためにも、こうした「小さな自動化」を取り入れておくことは非常に有効です。Supabaseを本番運用や会員サイトで活用している皆さんは、ぜひ早めに対策をしておきましょう。




