Guia
Leituras demais no Firestore? Como descobrir o que está lendo
3 de novembro de 2026 · 6 min de leitura
Suas leituras do Firestore dispararam e você não sabe por quê. Onde ver, como saber que tipo de leitura é e os padrões de código que multiplicam leituras sem ninguém perceber.
1. Veja quando começou
Abra a página de Uso do seu banco de dados, no console do Firebase (Firestore > Uso) ou no do Google Cloud. Ela mostra leituras, gravações e exclusões ao longo do tempo. Encontre o dia, e se puder a hora, em que a curva mudou, e compare com seus deploys: a maioria dos picos de leitura começa com uma versão nova.
Duas coisas sobre esse painel. É uma estimativa: o Google diz "the dashboard is not an exact view of billed operations. Billed usage is likely higher." (o painel não é uma visão exata das operações faturadas; o uso faturado provavelmente é maior) (Monitorar o uso do Firestore). E ele fica um pouco atrasado: "updates may take up to 4 minutes to show up in your dashboards." (as atualizações podem levar até 4 minutos para aparecer nos painéis).
2. Separe lookups de consultas
No Cloud Monitoring, abra o Metrics Explorer e faça o gráfico da métrica do Firestore Document Reads. Dá para dividir por tipo: LOOKUP para documentos lidos um a um pelo caminho, QUERY para documentos retornados por consultas e listeners. Mais duas métricas ajudam: Snapshot Listeners e Active Connections.
- Quase tudo QUERY: uma consulta lê documentos demais, ou um listener relê seus resultados sem parar.
- Quase tudo LOOKUP: algo busca documentos um a um, muitas vezes num loop ou dentro das suas Security Rules.
- Listeners crescendo mais rápido que os usuários: seu app abre listeners e nunca os fecha, ou abre um novo a cada render.
3. As causas de sempre
- Consultas sem limite. Uma página que carrega uma coleção inteira para mostrar os 20 primeiros lê todos os documentos dela, a cada visita. Adicione
limit()e pagine com cursores. Foi assim que aconteceram US$ 30.356 em 72 horas. - Listeners que se inscrevem de novo. No React, um
onSnapshotdentro de umuseEffectcujas dependências mudam a cada render abre um listener novo toda vez, e cada listener novo lê de novo todo o resultado. Na web, a persistência offline vem desativada por padrão, e a página de preços do Firestore é clara sobre o custo disso: "If offline persistence is disabled, you will be charged for documents and index entries read as if you had issued a brand-new query whenever the listener disconnects and reconnects." (sem persistência offline, você paga pelos documentos e entradas de índice lidos como se fizesse uma consulta nova sempre que o listener desconecta e reconecta). - Leituras dentro das Security Rules. Cada
get()ouexists()nas suas regras lê um documento. "You are charged for reads that are necessary to evaluate your Cloud Firestore Security Rules" (você paga pelas leituras necessárias para avaliar suas Security Rules do Cloud Firestore) (preços do Firestore). Uma regra que consulta o perfil do usuário a cada requisição dobra as leituras de uma tela movimentada. - Contar lendo. Carregar uma coleção para mostrar quantos itens ela tem lê todos os documentos. Uma agregação
count()é cobrada por entradas de índice: "count() operations that read between 0 and 1000 index entries are billed for one document read." (operações count() que leem entre 0 e 1000 entradas de índice são cobradas como uma leitura de documento). - Polling. Um timer que roda uma consulta a cada poucos segundos paga por ela toda vez, com ou sem resultados, porque o Firestore cobra "a minimum charge of one document read for each query that you perform, even if the query returns no results" (no mínimo uma leitura de documento por consulta, mesmo que ela não retorne resultados). Use um listener, ou consulte bem menos.
- Funções que leem a cada gravação. Uma Cloud Function disparada a cada gravação que depois lê uma coleção multiplica seu tráfego. Se ela também grava nos documentos que a disparam, pode entrar em loop.
- Alguém de fora. Se suas regras deixam qualquer pessoa, ou qualquer usuário logado, ler uma coleção, um script com sua configuração pública pode lê-la o dia todo. O console do Firebase mostra quantas requisições suas regras avaliam, o Cloud Monitoring pode avisar quando as negadas disparam e o App Check barra as requisições que não vêm do seu app.
O caso do React, em código
O primeiro efeito se inscreve de novo sempre que filters é um objeto novo, o que em muitos componentes acontece a cada render. O segundo depende de um valor simples e limita o resultado:
// Subscribes again every time `filters` is a new object
useEffect(() => {
const q = query(collection(db, "orders"), where("status", "==", filters.status));
return onSnapshot(q, (snap) => setOrders(snap.docs));
}, [filters]);
// Subscribes once per status, and reads at most 50 documents
const status = filters.status;
useEffect(() => {
const q = query(collection(db, "orders"), where("status", "==", status), limit(50));
return onSnapshot(q, (snap) => setOrders(snap.docs));
}, [status]);4. Confira uma consulta com o Query Explain
Quando suspeitar de uma consulta, rode-a com o Query Explain. Ele informa as operações de leitura cobradas e o índice usado, então você pode conferir uma correção antes do deploy (Query Explain).
5. Seja avisado da próxima vez
Um alerta de orçamento chega horas depois das leituras, então vigie as leituras em si. No Cloud Monitoring, crie uma política de alerta sobre Document Reads com um limite um pouco acima do seu pico normal.
Ou deixe o FireShield fazer isso. No Pro ele lê o uso de cada serviço a cada poucos minutos, compara a última hora com a hora normal desse serviço na última semana e avisa você, ou desliga a parte cara, quando as leituras do Firestore disparam.
