Supabase Free: Evite o Pause com Script GAS
Se você usa o plano gratuito do Supabase para algum projeto pessoal, testnet tracker, painel de dados ou qualquer outra aplicação, provavelmente já se deparou com aquele momento clássico: você abre o app depois de alguns dias, a tela carrega, e... nada acontece por quase um minuto. Depois tudo volta ao normal como se nada tivesse ocorrido.
Isso não é bug — é o comportamento oficial do plano free. O Supabase chama de pause automático por inatividade. Após cerca de 7 dias sem nenhuma requisição, o projeto literalmente "dorme". A primeira visita depois disso acorda o banco, mas o delay pode chegar a 60 segundos — o que, dependendo do contexto, parece uma falha grave para qualquer usuário que estiver acessando.
A solução é simples: manter o projeto acordado com um ping automático via Google Apps Script, ligado a uma planilha do Google Sheets. Nenhum servidor extra, nenhum custo, nenhuma dependência nova. Funciona, é leve, e já testei em projetos reais — incluindo um rastreador de ranges do puzzle do Bitcoin.
O Que é o Supabase e Como Funciona o Plano Gratuito
O Supabase é uma plataforma de backend open-source que oferece banco de dados PostgreSQL, autenticação, storage, funções serverless (Edge Functions) e uma API REST automática — tudo a partir de uma tabela que você cria. É frequentemente chamado de "alternativa open-source ao Firebase", mas com PostgreSQL real por baixo.
O plano gratuito é generoso para desenvolvimento e projetos pessoais: 500 MB de banco, 1 GB de storage, 50.000 usuários autenticados por mês e largura de banda razoável. Dá para muita coisa. O problema está em um detalhe operacional que poucos leem no momento do cadastro.
O Comportamento de Pause — O Que Realmente Acontece
Segundo a documentação oficial do Supabase, projetos no plano Free que ficam sem atividade por aproximadamente 7 dias entram em estado de pausa automática. Nesse estado:
- A API REST retorna erros ou fica sem resposta
- Conexões diretas ao banco via PostgreSQL falham
- O dashboard mostra o projeto como "Paused"
- A primeira requisição acorda o projeto automaticamente, mas pode levar de 10 a 60 segundos
- Nenhum dado é perdido — o banco fica intacto, só indisponível temporariamente
Existe ainda um cenário mais crítico: projetos completamente abandonados por meses podem ser marcados como inativos e eventualmente removidos — mas o Supabase envia emails de aviso antes de qualquer remoção. Mesmo assim, não vale arriscar.
💡 Detalhe importante: o pause não é baseado só em dados escritos — qualquer leitura (SELECT) via API REST já conta como atividade e reinicia o contador de inatividade. Ou seja, um ping leve a cada poucos dias é suficiente para manter o projeto sempre acordado.
6 Motivos Para Usar o Google Apps Script Como Solução de Ping
O Google Apps Script roda na sua conta Google sem custo algum. Não precisa de servidor, VPS, conta em serviços de cron pago ou qualquer outra dependência externa.
Você abre a planilha do Google Sheets, vai em Extensões → Apps Script, cola o código, configura o gatilho de tempo e pronto. Sem terminal, sem deploy, sem dependências.
Cada ping faz uma consulta com limit=1, trazendo apenas um registro de uma coluna. São alguns bytes por execução — irrelevante para qualquer cota do Supabase.
Se o projeto já entrou em pause, o ping do GAS também serve para acordar o banco automaticamente antes do primeiro acesso real. Isso reduz ou elimina o delay que o usuário final sentiria.
O Apps Script mantém um registro de execuções acessível pelo menu "Execuções". Se algo der errado, você vê exatamente qual foi o status HTTP retornado pelo Supabase e a mensagem de erro.
Com um array simples de nomes de tabelas, o mesmo script consulta todas de uma vez em um único gatilho. Ideal para projetos com várias tabelas que precisam estar sempre disponíveis.
Como Funciona em 3 Passos
-
O Google Apps Script faz uma requisição GET à API REST do Supabase
Usando o endpoint padrão
/rest/v1/NOME_DA_TABELA?select=id&limit=1, o script consulta exatamente 1 registro de 1 coluna. Isso é suficiente para registrar atividade no projeto. A autenticação é feita pela anon public key, que você pega em Project Settings → API no painel do Supabase. -
O Supabase registra a requisição como atividade e mantém o projeto ativo
Qualquer leitura via API REST reinicia o contador de inatividade do Supabase. Não precisa escrever dados, não precisa chamar funções pesadas. O simples GET com limite 1 já resolve. O servidor responde com
200 OKe um array JSON mínimo — sinal de que o banco está acordado e funcionando. -
O gatilho de tempo executa o script automaticamente no intervalo configurado
No próprio Apps Script você configura um Time-driven trigger para rodar o
pingSupabase()a cada 2 dias (ou a cada 12 horas para projetos mais críticos). O Google executa isso de forma confiável, sem precisar de nenhuma ação sua. Você configura uma vez e esquece.
Para Quem é Esta Solução
Se você tem um side project, portfólio ou experimento rodando no Supabase Free e não quer perder tempo debugando um "problema" que é apenas o banco dormindo.
Projetos como trackers de puzzle, indexadores de endereços ou dashboards de testnet frequentemente ficam dias sem acesso — exatamente o cenário que dispara o pause automático.
Quem integra Google Sheets com Supabase para armazenar dados de formulários, respostas de pesquisas ou dashboards automatizados e precisa que o banco esteja sempre disponível.
Startups e projetos em fase inicial que ainda não justificam pagar pelo plano Pro mas precisam de disponibilidade razoável para apresentar para usuários ou investidores.
Configurando o Script GAS Para Manter o Supabase Ativo
Vou mostrar o script completo que uso em projetos reais, incluindo o tratamento de erros e a versão com múltiplas tabelas. Depois explico linha a linha o que cada parte faz.
Passo 1 — Abrir o Editor do Google Apps Script
Abra qualquer planilha do Google Sheets (ou crie uma nova, eu geralmente crio uma chamada "Automações"). No menu superior, clique em Extensões → Apps Script. Uma aba nova vai abrir com o editor de código. Delete o conteúdo padrão e cole o script abaixo.
Passo 2 — O Script Completo com Múltiplas Tabelas
function pingSupabase() {
// URL base do seu projeto Supabase
var base = "https://SEU_PROJETO.supabase.co/rest/v1/";
// Sua chave pública (anon key) — nunca use a secret key aqui
var key = "SUA_ANON_KEY";
// Tabelas que você quer consultar (troque pelos seus nomes reais)
var tables = [
"encontrados",
"puzzle_progress",
"puzzle_vertical"
];
tables.forEach(function(table) {
// Consulta apenas 1 ID — o mínimo para registrar atividade
var url = base + table + "?select=id&limit=1";
var options = {
method: "get",
headers: {
"apikey": key,
"Authorization": "Bearer " + key
},
muteHttpExceptions: true
};
try {
var response = UrlFetchApp.fetch(url, options);
Logger.log("Tabela: " + table);
Logger.log("Status: " + response.getResponseCode());
Logger.log(response.getContentText());
} catch (err) {
Logger.log("Erro na tabela " + table + ": " + err);
}
});
}
💡 Onde está a anon key? No painel do Supabase, vá em Project Settings → API → Project API keys e copie a chave chamada anon (public). Essa é a chave segura para leitura pública — nunca use a service_role key em scripts externos.
Passo 3 — Configurar o Gatilho de Tempo
Com o script salvo, clique no ícone de relógio no menu lateral do Apps Script (ou vá em Triggers). Clique em Add Trigger e configure assim:
| Campo | Valor |
|---|---|
| Choose which function to run | pingSupabase |
| Which runs at deployment | Head |
| Select event source | Time-driven |
| Select type of time based trigger | Day timer |
| Select time of day | Qualquer horário fixo (ex: 9am–10am) |
| Failure notification settings | Notify me daily (recomendado) |
O campo "Day timer" no Apps Script não permite configurar "a cada 2 dias" diretamente — ele executa diariamente por padrão nessa configuração. Se quiser realmente rodar a cada 2 dias, use a opção Week timer com dias específicos selecionados (segunda, quarta, sexta, por exemplo).
💡 Recomendação prática: para projetos que você acessa com frequência, rodar a cada 2 dias é mais que suficiente. Para projetos que ficam dias sem acesso real (trackers, dashboards internos), prefira o timer diário — o custo de tráfego é zero e você garante que o banco nunca vai dormir.
Como Consultar as Tabelas Corretamente — URL e Formato
Entender a estrutura da URL é importante para não errar na montagem do ping e também para usar a API REST em outros contextos. O formato padrão do Supabase é:
https://SEU_PROJETO.supabase.co/rest/v1/NOME_DA_TABELA?select=COLUNA&limit=N
Exemplos de Consultas Por Caso de Uso
| Objetivo | URL |
|---|---|
| Ping mínimo (só registrar atividade) | /rest/v1/tabela?select=id&limit=1 |
| Ler todos os campos de 1 registro | /rest/v1/tabela?select=*&limit=1 |
| Ler campos específicos | /rest/v1/tabela?select=id,nome,status&limit=5 |
| Filtrar por valor de coluna | /rest/v1/tabela?select=*&status=eq.ativo |
| Ordenar resultado | /rest/v1/tabela?select=*&order=created_at.desc&limit=10 |
Qual Intervalo de Ping é Mais Indicado?
Essa é a pergunta que mais aparece depois que o script está configurado. A resposta depende do tipo de projeto:
| Tipo de Projeto | Intervalo Recomendado | Motivo |
|---|---|---|
| Projeto pessoal acessado frequentemente | A cada 2–3 dias | Seus próprios acessos já geram atividade — o ping é só um backup |
| Tracker ou dashboard interno (acesso esporádico) | Diário | Elimina completamente o risco de pause — custo de tráfego é zero |
| App com usuários reais (MVP) | A cada 12 horas | Garante que o banco está acordado antes do primeiro acesso do dia |
| Projeto em pausa ativa (desenvolvimento pausado) | A cada 5 dias | Mantém o projeto vivo sem necessidade de acesso constante |
🕐 Regra prática simples: o Supabase pausa após ~7 dias. Configure o ping com metade desse intervalo no mínimo — ou seja, a cada 3 dias é o máximo seguro. Para projetos que importam, vá de diário. O GAS aguenta tranquilo.
Habilitando Leitura Pública (RLS) Quando Necessário
Se o seu projeto tem Row Level Security (RLS) ativado sem nenhuma policy de leitura pública, a anon key vai receber um erro 403 ou retornar um array vazio. Não é exatamente um erro — mas indica que o banco não está liberado para leitura anônima.
Para resolver, execute este SQL no SQL Editor do Supabase para a tabela que você quer usar no ping:
-- Habilitar RLS na tabela (se ainda não estiver ativado)
alter table sua_tabela enable row level security;
-- Criar policy que permite leitura anônima
create policy "public read"
on sua_tabela
for select
to anon
using (true);
Repita para cada tabela que aparecer no array do script. Depois teste manualmente rodando a função uma vez no editor do Apps Script — o log deve mostrar Status: 200 para cada tabela.
Erros Comuns e Como Resolver Cada Um
Durante os testes com esse script, passei por todos esses erros. Cada um tem uma causa clara e uma solução direta.
❌ Erro 401 — Unauthorized
Causa: você tentou acessar o endpoint raiz /rest/v1/ em vez de uma tabela específica. Esse endpoint exige a service_role key, que nunca deve ser usada em scripts externos. Também acontece quando a anon key está incorreta ou incompleta.
Solução: aponte sempre para uma tabela específica no formato /rest/v1/nome_da_tabela?select=id&limit=1. Verifique se a anon key foi copiada corretamente — sem espaços extras no início ou fim.
❌ Erro 404 — PGRST205 (Table Not Found)
Causa: a tabela especificada na URL não existe no schema public do banco. Digitou errado o nome, ou a tabela está em outro schema.
Solução: verifique o nome exato da tabela no Table Editor do Supabase. Os nomes são case-sensitive. Se a tabela estiver em outro schema, adicione o header Accept-Profile: nome_do_schema na requisição.
❌ Erro 403 — Forbidden
Causa: a tabela tem RLS ativado mas não tem nenhuma policy permitindo leitura para a role anon. O Supabase bloqueia a consulta por segurança.
Solução: execute o SQL de criação de policy mostrado na seção anterior. Se não quiser abrir leitura pública, crie uma tabela separada só para ping — como a heartbeat sugerida abaixo.
❌ Array vazio [] — Status 200 mas sem dados
Causa: a tabela existe e a permissão está correta, mas a tabela está completamente vazia. O ping tecnicamente funciona (200 OK), mas não retorna nada.
Solução: insira ao menos um registro na tabela de teste. Para a tabela heartbeat, basta um INSERT INTO heartbeat VALUES (1);. Ou use a opção de count na query: ?select=count&limit=1 — retorna 0 mas ainda registra atividade.
❌ Timeout ou exception no GAS
Causa: o projeto já entrou em pause e está acordando durante a requisição do GAS. O Supabase pode levar até 60 segundos para responder, e o Apps Script tem um timeout padrão de 30 segundos.
Solução: adicione o parâmetro deadline nas options do UrlFetchApp: deadline: 60. Isso aumenta o timeout para 60 segundos. Se o problema persistir, considere aumentar a frequência do ping — um banco que está dormindo na hora do ping ainda vai acordar para o próximo acesso.
Tabela Recomendada Para Uso Exclusivo de Ping
Se você não quer abrir leitura pública em nenhuma tabela do seu projeto real, a solução mais limpa é criar uma tabela minúscula só para o ping. Execute no SQL Editor:
-- Tabela minúscula usada apenas para manter o projeto ativo
create table heartbeat (
id int primary key
);
-- Insere o único registro necessário
insert into heartbeat values (1);
-- Habilita RLS
alter table heartbeat enable row level security;
-- Permite leitura anônima apenas nesta tabela
create policy "public read heartbeat"
on heartbeat
for select
to anon
using (true);
Depois, o URL do ping fica simplesmente:
https://SEU_PROJETO.supabase.co/rest/v1/heartbeat?select=id&limit=1
Leve, seguro, sem expor dados reais do projeto.
Recursos Oficiais e Ferramentas Mencionadas
- 📦 Supabase — Documentação de Produção: supabase.com/docs/guides/platform/going-into-prod — inclui informações oficiais sobre pause automático e limites do plano Free.
- 🤖 Google Apps Script — Documentação oficial: developers.google.com/apps-script — tudo sobre triggers, UrlFetchApp, Logger e configuração de automações.
- 📊 Supabase — Dashboard e SQL Editor: supabase.com/dashboard — onde você cria tabelas, configura RLS e busca a anon key do projeto.
- 🔗 Posts relacionados no @CanalQb: Como usar APIs REST com autenticação Bearer | Google Apps Script para automações com planilhas | Scripts de monitoramento de servidores e APIs
ℹ️ Nota Técnica: Os scripts apresentados neste post são para fins educacionais e de automação pessoal. Mantenha sua anon key protegida — nunca a use em contextos onde possa ser exposta publicamente de forma irrestrita. Nunca use a service_role key em scripts externos, frontends ou planilhas compartilhadas. O autor não se responsabiliza por usos indevidos, perda de dados ou consumo excessivo de cota do Supabase. Sempre revise as políticas de uso do plano gratuito diretamente na documentação oficial do Supabase.

Comentários
Comente só assim vamos crescer juntos!