免費版資料庫的生存危機:Supabase 閒置暫停機制

作為愛好折騰的開發者,Supabase Free Tier 是部署側邊專案(Side Projects)的絕佳選擇。然而官方有明文規定:若專案連續 7 天沒有活動(Activity),將會自動進入暫停(Pause)狀態。一旦專案被暫停,API 將會回傳 500 系列錯誤,此時必須由開發者登入 Supabase 控制台手動點擊「Resume」,需要等待數分鐘才能恢復運作。

這對於流量不大但需要隨時保持反應的個人工具、電報機器人(Telegram Bot)或 AI 助理來說,簡直是災難。因此,我們需要一套自動化機制,每天幫我們對 Supabase 進行「心跳探測」與「活動模擬」,確保專案永遠維持活躍。

核心策略:主動寫入(Active Writes) vs. 唯讀 Ping

許多常見的保活方案,是寫一個指令碼每天對資料庫執行 SELECT 1 或唯讀查詢。然而,這種做法在實務上有兩個隱憂:

  1. 活動定義不明確:雲端平台對於「活動」的判定基準可能隨時調整,唯讀的 API 查詢有時不會被認定為「有效的資料庫使用」。
  2. 不產生實際指標:單純的讀取對雲端計費和統計報表上的「Write Operations」毫無貢獻。

因此,我的設計哲學是「主動同步、真實寫入」。我們不要無聊的 SELECT,而是讓 n8n 真的去做資料搬移與 AI 處理:每天將真實的外部資料(Notion 筆記、GDrive 文件),經過 Gemini AI 處理後,在 Supabase 向量資料庫(pgvector)中進行「先刪除、後寫入」的同步流程。這不僅創造了無可爭議的寫入活動,還順便幫我們保持了 RAG 知識庫的最新狀態!

如何避免資料膨脹?

主動寫入最大的風險是資料量無限增長,最終爆掉 Supabase Free 的 500MB 儲存限制。因此,我們在寫入前必須先透過 metadata 篩選器精準定位,將前一次寫入的保活資料全部刪除,再寫入新資料。如此一來,資料庫的大小永遠維持在固定範圍,卻能創造出源源不絕的「活動證據」。

實戰工作流一:Notion AI 知識同步保活 (Notion_2_Supabase)

這是我在生產環境運作的工作流之一。它每天定時將 Notion 中的學習卡片、英文單字或 FAQ,透過 Gemini 整理成結構化 Markdown,再同步到 Supabase 的向量資料表中。而且,一條 n8n 工作流可以同時保活 3 個不同的 Supabase 專案

Schedule
03:00台北時間

每天凌晨三點自動啟動,避開流量高峰。

Data Source
Notion Database

讀取名為 EnglishVocabulary 的 Notion 資料表,每次限制 10 筆。

AI Engine
Gemini 2.5 Flash Lite

利用輕量、極速的低成本 Gemini 模型將內容整理成多層級結構的 Markdown。

Targets
3 Supabase Instances

並行同步至 三個獨立的 Supabase 專案,三個願望一次滿足。

Notion_2_Supabase 工作流邏輯拆解

  1. Notion 讀取:使用 Get many database pages 節點拉取最新卡片。
  2. AI 格式化:透過 Basic LLM Chain 呼叫 gemini-2.5-flash-lite,搭配 System Prompt 扮演醫療資訊系統產品經理,將混雜的問答對轉化為標準的 Markdown FAQ,並在結尾插入分隔線。
  3. 防禦性刪除:在 Supabase 節點設定 Operation 為 Delete,並使用篩選字串 =metadata->>embeddingKey=like.faq,將昨天的 FAQ 向量清空。
  4. 向量化寫入:透過 Vector Store Supabase 節點,使用 gemini-embedding-001 生成嵌入,並寫入目標向量表 gemini001 中。

實戰工作流二:GDrive PDF 條例向量同步 (renewSupabase)

如果沒有 Notion 資料來源,也可以使用靜態文件保活。此工作流使用 Google Drive 上的政府法規 PDF(例如:管制藥品管理條例.pdf),定期重新切割、向量化,並同步至 4 個 Supabase 實例

Schedule
每週二、四、六 04:30

每週執行三次,預留充足的暫停緩衝期。

Data Source
Google Drive PDF

自動下載指定的法規 PDF 檔案並提取純文字內容。

Document Loader
Recursive Character Splitter

設定 chunk size 與 overlap,將 PDF 切割成適當大小的語意區塊。

Targets
4 Supabase Instances

一次運作,同時喚醒 多個不同的 Supabase 資料庫專案。

renewSupabase 工作流邏輯拆解

  1. 排程與參數設定:設定每週定時啟動,並透過 Set 節點將目標向量表名稱統一指定為 renew_supabase_768
  2. 下載與解析 PDF:使用 Google Drive 節點下載 PDF 檔案,並透過 Extract from File 提取為純文字。
  3. 多資料庫防禦性刪除:對 4 個 Supabase 連線,同時發起 Delete 請求,利用篩選器 =metadata->>testKey=like.abc123 刪除前次保活產生的向量。
  4. 向量嵌入插入:使用 Embeddings Google Gemini 節點,結合 models/gemini-embedding-001,將切分後的 PDF 文件重新 Insert 到 4 個資料庫中。

進階軟體工程思維:防禦性設計與狀態一致性

在 n8n 畫布上拉出流程很簡單,但在生產環境中保持穩定且不搞砸資料庫,需要嚴謹的工程設計。這兩個工作流融入了以下防禦性設計理念:

1. 競態條件與順序控制(Order Control)

n8n 預設會盡可能並行執行節點。如果我們在刪除舊資料的同時寫入新資料,可能會發生「新資料先寫入,舊資料後刪除」的競態條件(Race Condition),導致資料庫最後空無一物,或者資料重複累積。為了實現絕對的狀態一致性:

  • Aggregate 節點阻擋:我們在 Delete 節點後方放置了 Aggregate 節點。它扮演了「柵欄(Barrier)」的角色,會強行等待所有 Delete 請求完全響應並合併資料後,才允許工作流往下游走。
  • Wait 節點緩衝:在進入 Insert 寫入節點前,加入 3 秒的 Wait 節點,確保 Supabase 內部索引更新完畢,避免瞬時的高頻存取被 Supabase 的 rate-limit 拒絕。

2. 告警邊界與防禦性分支(Error Output Handling)

當我們用單一工作流管理多個資料庫時,最怕其中一個資料庫暫停或憑證過期,導致整條工作流中斷,進而讓其他健康的資料庫也無法保活。我們的對策是:

  • 開啟 Supabase 節點的 onError: "continueErrorOutput" 設定。
  • AS-Jira 執行 Delete 失敗時,它不會讓工作流崩潰,裝作什麼都沒發生,而是會將錯誤資訊導向 Error 輸出分支,觸發 Telegram Node 發送警報(例如:Ping Supabase AICS error),同時主線流程依然可以順利走完其他三個資料庫的保活。
設定項目 設定值 / 策略 工程考量
Delete Filter metadata->>testKey = abc123 (或 faq) 防止誤刪生產環境中的真實業務資料。
Credentials n8n Encrypted Credentials API Key 絕不寫死在代碼或 node parameters,避免隨 JSON 匯出外洩。
Error Mode Continue Write (Error Output) 避免單一資料庫停機引發連鎖崩潰。
Control Flow Aggregate + Wait (3s) 確保「先刪除、後寫入」的嚴格順序,並防止 Rate Limit。

測試、告警與維護計畫

保活系統必須是「可觀測的(Observable)」。我們不希望它默默死掉,等到 Supabase 被暫停了才發現。

1. 製造一次防禦性失敗

在設定好 Telegram 告警後,你可以手動將 Delete 節點的表名修改為不存在的表,執行一次工作流,確認 Telegram 群組能夠即時收到帶有錯誤原因與時間戳記的告警訊息。確認無誤後,立刻將表名還原。

2. 設定 n8n 執行歷史保留期

請確保你的自託管(Self-hosted)n8n 實例或雲端版,將 Execution History 的保留期設定為至少 7 天(建議 14 天)。如此一來,你可以隨時點開歷史紀錄,確認最近一週內每天都有綠色的成功勾勾,作為 Supabase 確實有被活動保活的歷史證據。