PushMesh
Entrar Solicitar acesso
Abrir navegação das seções

Índice

Limites

Todos os tetos da API em um lugar — requisições por segundo, por minuto, tamanho de corpo, limites de produto e a franquia comercial do plano gratuito, com o que você vê quando estoura cada um.

Limites

Nenhum limite aqui é surpresa: os números publicados estão travados por teste de contrato, justamente para que quem integrou pelo número publicado não comece a tomar 429 sem explicação. Esta página é a lista completa.

1. Requisições por segundo, por aplicativo

Cada classe de rota tem o próprio balde. Estourar o balde da consulta não afeta o do envio.

ClasseRotasTeto
EnvioPOST /api/v1/notifications6.000 req/s por aplicativo
ConsultaGET /api/v1/notifications/{id}1.000 req/s por aplicativo
ExportaçãoPOST /api/v1/players/csv_export1 req/s por aplicativo

As rotas de aparelho não têm teto por segundo por aplicativo. Registro, atualização, recibos, In-App e parâmetros do Firebase são limitados por outro caminho: o teto por endereço de origem da seção 2 e o teto de 50.000 registros por hora por aplicativo da seção 4. Se você está dimensionando uma carga em massa de registro, é contra esses dois números que a conta precisa ser feita.

A consulta repetida não custa cota

Antes de cobrar o teto, a consulta é servida de um cache de 1 segundo. Se a sua integração pergunta duas vezes pelo mesmo disparo no mesmo segundo, a segunda resposta vem do cache, não conta no balde e não toca o banco.

Isso é deliberado: uma integração que acompanha milhares de disparos por ciclo tem todo o direito de perguntar muito, e o dado tem 1 segundo de idade — não mudou nada. O teto passa a proteger o que realmente custa, que é a ida ao banco. Quem cai no 429 é quem pede coisas diferentes rápido demais.

O balde sobrevive à queda do cache compartilhado

Com o cache compartilhado no ar, a conta é global do aplicativo. Se ele cair, o teto continua existindo, só que por processo do serviço — degradado, nunca desligado.


2. Requisições por minuto, por endereço de origem

As rotas públicas chamadas pelo aparelho são limitadas por origem:

CamadaTetoResposta
Serviço120 req/min por IP429 + Retry-After: 60
Borda240 req/min por IP, com rajada de 60429

A borda é propositalmente mais frouxa que o serviço: ninguém que passa pelo serviço é barrado pela borda. Ela existe como segunda linha, para o caso de o tráfego crescer mais rápido do que o processo consegue recusar.

Requisições recusadas também contam — martelar não ganha tentativas.

{
  "errors": ["limite de requisições excedido"],
  "explain": {
    "causa": "mais de 120 req/min a partir do mesmo IP (203.0.113.10)",
    "como_corrigir": "aguarde a janela de 60 s e honre o Retry-After",
    "request_id": "0198f0b2-6e31-7a4c-9f10-2c9a1d4e7b55"
  }
}

Sobre o cabeçalho Retry-After

Seja preciso ao programar o seu backoff, porque os dois 429 não são iguais:

  • o 429 por origem (rotas do aparelho) emite Retry-After: 60;
  • o 429 por classe (envio, consulta, exportação) traz o tempo de espera no texto de explain.como_corrigir (“aguarde 1s e tente de novo”) e, nesta versão, não acrescenta o cabeçalho.

A regra segura para o seu cliente: leia Retry-After quando ele existir; na ausência dele, respeite o valor citado em explain.como_corrigir. Nunca repita em laço apertado.


3. Tamanho do corpo

RotaTeto no serviçoTeto na borda
POST /api/v1/notifications256 KB256 KB
Rotas do aparelho (players, receipts, inapp)16 KB16 KB
Demais rotas /api/v164 KB

Os dois tetos são diferentes de propósito. 16 KB é o corpo que um aparelho manda (registro, recibo) e não tem por que crescer. A rota de envio carrega lista de destinatários: com o máximo de 2.000 identificadores, o pedido tem cerca de 80 KB, e 256 KB dá folga de três vezes sobre o maior lote válido.

O teto é aplicado em duas etapas: se o Content-Length declarado já passa, a resposta sai sem ler o corpo; se o corpo real passar (chunked, ou Content-Length mentiroso), ele é interrompido ao bufferizar. Nos dois casos a resposta é o 413 no envelope padrão, com o limite nomeado — nunca um 413 cru sem explicação.

{
  "errors": ["corpo acima do limite da rota"],
  "explain": {
    "causa": "corpo excede o limite da rota (256 KB)",
    "como_corrigir": "reduza o corpo da requisição e reenvie",
    "request_id": "0198f0b2-6e31-7a4c-9f10-2c9a1d4e7b55"
  }
}

4. Limites de produto

Tudo abaixo devolve um 400 ou 422 nomeado, nunca um truncamento silencioso.

Envio

LimiteValor
Identificadores por chamada (include_player_ids / include_external_user_ids)2.000
Segmentos por chamada (included_segments)10
Alvos por chamadaexatamente 1 dos três
ttl0 a 2.419.200 s (28 dias); padrão 259.200 s (3 dias)
collapse_id64 bytes
send_afterno máximo 28 dias à frente
Payload renderizado (o que chega ao aparelho)3.891 bytes

O limite de payload merece explicação, porque é o que mais surpreende. O orçamento de 3.891 bytes é medido sobre o payload final, incluindo os 96 bytes que o servidor ainda injeta no envio (pm_msg_id e pm_rcpt — o rastro que permite recibo de entrega e de clique). Se a porta ignorasse esses bytes, uma mensagem no limite passaria aqui e morreria com erro no provedor de push — o push sumiria em silêncio. A medição é feita antes de tocar o banco, e o 422 traz a contagem exata.

Aparelhos

LimiteValor
identifier (token de push)194 bytes
external_user_id128 bytes
tags serializadas2 KB
language32 bytes
timezone±86.400 segundos
Aparelhos por external_user_id10
Registros por hora, por aplicativo50.000

Exportação da base

LimiteValor
Pedidos1 por segundo, por aplicativo
Aparelhos no arquivo5.000.000 (teto de sanidade)
Validade do arquivo publicado72 h

O 429 da exportação ensina o caminho certo: “o arquivo anterior continua valendo por 72h — baixe pela URL que já foi devolvida em vez de pedir outro”.

Idempotência

LimiteValor
Validade da chave de idempotência30 dias
Reserva em processamento antes de virar órfã60 s
Espera por uma reserva concorrente antes do 4093 s

Trinta dias não é enfeite: quem tem fila própria reprocessa dias depois, e a promessa “a mesma chave nunca dispara duas vezes” que valesse só por um dia não seria promessa, seria sorte.

Webhooks

LimiteValor
Tempo de resposta do seu endpoint10 s
Tentativas por evento30 (≈ 24 h)
Falhas seguidas que desligam o destino20

Detalhes em Webhooks.

Mensagens In-App

Os limites do canal In-App (blocos por campanha, tamanho do lote de eventos, campanhas por pacote de sessão, validade do pacote e o intervalo mínimo entre duas mensagens) vivem junto do contrato que os explica, em Mensagens In-App.


5. O limite comercial: a franquia do plano gratuito

Este não é um teto técnico, e é o único da página que recusa o envio inteiro.

O plano gratuito entrega dentro de uma franquia de usuários ativos no mês. Acima dela, o POST /api/v1/notifications responde 422 e nada é enviado — nem para uma parte da lista. Truncar seria pior: você veria “campanha enviada”, e parte da sua base simplesmente não receberia, sem nenhum sinal.

O queComo funciona
Onde vive o númerona configuração de cobrança, não fixo no código. Hoje o valor publicado é de 1.000 usuários ativos por mês, gratuitos em qualquer plano — a página de preços é a fonte da verdade
Quem é medidoa organização, não cada aplicativo. Dois aplicativos do mesmo cliente dividem a mesma franquia
Quando recusaquando o número medido passa da franquia. Exatamente na franquia ainda passa
Quem nunca é recusadoqualquer conta em plano pago. Ela não entra na medição, então não existe caminho de código que a barre

A resposta traz os números para você agir sem abrir um chamado:

{
  "errors": ["plano Free atende até 1000 usuários ativos no mês — sua conta está com 1240"],
  "explain": {
    "causa": "o plano Free entrega dentro da franquia de 1000 usuários ativos no mês, e em 2026-08 a sua conta registrou 1240; acima da franquia o envio é recusado INTEIRO — entregar só para uma parte da base, escolhida por ordem de consulta, seria sumir com o resto em silêncio",
    "como_corrigir": "mude para o Premium (USD 0.005 por usuário ativo acima da franquia, sem mensalidade) e o envio volta na hora — os 1000 primeiros usuários ativos continuam gratuitos nos dois planos",
    "plano": "free",
    "mau": 1240,
    "mau_gratis": 1000,
    "mes": "2026-08",
    "moeda": "USD",
    "preco_por_mau": "0.005",
    "medido_ha_s": 12
  }
}

Três honestidades sobre esse número:

  1. Ele não é tempo real. A contagem varre a base inteira, então ela é refeita periodicamente em segundo plano — no máximo uma vez por minuto — e o campo medido_ha_s diz a idade do número com que você está discutindo.
  2. Ele é freio, não fatura. Entre uma medição e a seguinte, uma conta pode passar da franquia por alguns minutos e continuar entregando. Quem cobra é a fatura, medida pelo mês inteiro.
  3. Falha de infraestrutura nunca barra ninguém. Sem banco, sem medição utilizável, ou com uma medição velha demais (mais de 600 segundos), a conferência libera. Um cliente que para de entregar porque uma consulta interna falhou seria um estrago maior do que uma cobrança a menor — e essa é uma decisão escrita, não um acidente.

E a regra de retry: 422 é da família “corrija o pedido, não repita”. Aqui a correção não é no seu JSON, é no plano — repetir a chamada não muda nada.


Veja também

AssuntoPágina
a tabela de códigos HTTP e a política de retryAutenticação e erros
todos os campos e limites do disparoEnviar push
tetos das rotas de aparelho, na práticaAparelhos
o que é congelado por contrato e o que pode mudarVersionamento