PRODPlataforma BaaS europeia soberanaAbra o painel →

Desempenho · 15 minutos de leitura

Como comparamos um back-end: uma metodologia repetível

Affane Daylami · Fondateur · 8 de julho de 2026

Voltar ao blog

Um valor de referência sem método não prova nada. “p95 abaixo de X ms”, “inicialização a frio menor que Y ms” – qualquer um pode escrever isso em uma página de marketing. O que comprova algo é o método: o equipamento utilizado, a duração do teste, o protocolo de medição e a possibilidade de um terceiro reproduzi-lo de forma idêntica.

Este texto em inglês foi gerado automaticamente a partir do original em francês e ainda não foi revisado.
Esta página foi traduzida automaticamente. A versão em inglês é oficial.

Este artigo responde a uma pergunta específica – como avaliar uma API de backend de forma reproduzível – documentando o protocolo que aplicaremos na Aurabase antes de publicar quaisquer números de desempenho. Não resultados: um método. Qualquer medição já publicada em outro lugar neste site (principalmente em nossa página Desempenho) que ainda não dependa deste protocolo deve ser tratada como não verificada até novo aviso.

O essencial

Até o momento, não existem resultados de desempenho do Aurabase seguindo um protocolo publicado e reproduzível - este artigo documenta a metodologia que aplicaremos para produzi-los, e não os resultados já obtidos. O repositório já contém um conjunto de testes de 3 níveis: micro-benchmarks Criterion.rs em 3 caixas, testes de carga k6 em 8 cenários HTTP/WebSocket e um script Python para comparação direta entre Postgres e API com cálculo de percentil. O protocolo completo — duração da medição, percentis em vez de médias, isolamento do ambiente, divulgação de versão e data — é baseado em fontes externas verificadas: PostgreSQL, Criterion.rs, k6 (Grafana), HdrHistogram, PlanetScale e Convex. Quaisquer declarações de desempenho já publicadas em outro lugar deste site sem serem rastreadas até este protocolo devem ser consideradas não verificadas.

#
Postura editorial

Por que não publicamos números simples

A Convex, editora de um back-end responsivo concorrente, distanciou-se publicamente do que sua equipe técnica chama de “guerra de gráficos de barras” entre provedores de banco de dados. Sua fórmula é direta: “É escalar teatro, não escalar” — escalar teatro, não escalar real (stack.convex.dev/on-competitive-benchmarks, Stack Technical Blog, acessado em 23 de agosto de 2026).

Seu argumento central: um benchmark que compara dois sistemas com diferentes garantias de consistência, topologia ou modelo de precificação muitas vezes não testa a mesma coisa, mesmo quando afirma fazê-lo — “o benchmark não está realmente testando a mesma coisa”. Este reflexo tem um nome na indústria: benchmarketing, publicando uma figura escolhida pelo seu efeito mercadológico e não pelo seu rigor metodológico.

A nossa resposta não é recusar medir – recusar publicar um número indefinidamente seria tão desonesto como publicar um número sem fundamento. É primeiro documentar como mediríamos, com que ferramentas e sob que condições, antes de afirmarmos ter medido alguma coisa. Isso também é o que distingue uma comparação útil (como nossa comparação Aurabase vs Appwrite, que documenta diferenças arquiteturais verificáveis) de uma comparação de números de desempenho sem um protocolo comum.

Isto é particularmente importante para um líder técnico ou um CTO que deve defender uma escolha de back-end num comité técnico: um número que não pode ser atribuído a um método não sobrevive à primeira pergunta, um tanto insistente. Um protocolo documentado é autodefensivo – você pode mostrar o script, a versão testada, e executar o teste novamente na frente de alguém, se necessário.

#
Diagnóstico

O que torna a maioria dos benchmarks de back-end enganosos

Duas armadilhas surgem sistematicamente: comparar diferentes topologias sem relatá-las e medir a latência de uma forma que oculte exatamente as pausas que mais importam para o usuário.

No primeiro ponto, PlanetScale documenta explicitamente sua restrição de paridade de hardware: cada ambiente comparado deve ser executado em recursos computacionais (vCPU, RAM) iguais ou superiores à instância de referência, na mesma região de nuvem (planetscale.com/benchmarks, metodologia “Telescope”, acessado em 23 de agosto de 2026). Sem essa disciplina, uma lacuna de latência pode simplesmente refletir uma máquina maior — e não uma arquitetura mais rápida.

O mesmo princípio se aplica ao estado do cache e à topologia da rede. Uma instância que acabou de ser iniciada (cache frio do Postgres, pool de conexões vazio, plano de consulta ainda não armazenado em cache) responde estruturalmente mais lentamente do que uma instância que está em execução há uma hora sob carga estável. Uma consulta da mesma região do banco de dados responde estruturalmente mais rápido do que uma consulta entre regiões. Dois benchmarks que não especificam nenhum deles simplesmente não são comparáveis, mesmo que exibam unidades idênticas.

No segundo ponto, a armadilha é chamada de omissão coordenada. HdrHistogram, o projeto de referência em medição de latência criado por Gil Tene, explica desta forma: quando um gerador de carga espera pela resposta de uma solicitação antes de enviar a próxima (loop fechado), uma pausa de serviço reduz automaticamente o número de solicitações enviadas durante a pausa - e, portanto, o número de medições de alta latência registradas (github.com/HdrHistogram/HdrHistogram, acessado em agosto 23, 2026). O projeto dá um exemplo concreto e quantificado: em um sistema hipotético que amostra sua latência a cada 10 ms durante 200 segundos, uma única pausa de 100 segundos no meio do teste é suficiente para produzir, sem correção, um histograma onde aproximadamente 99,99% das respostas parecem caber abaixo de 1 ms - mesmo que metade do tempo real tenha decorrido nesta única pausa.

Armadilha clássica

Um teste de carga de circuito fechado que só envia uma solicitação após receber a resposta anterior subrepresenta sistematicamente pausas longas. O p99 exibido pode ser melhor do que a realidade vivenciada por um usuário real — não porque o sistema seja rápido, mas porque o protocolo de medição “esqueceu” de enviar as consultas durante a pausa.

#
Estatísticas

Por que a média está: p50, p95, p99

Uma latência média pode parecer excelente quando uma em cada vinte solicitações leva cinco vezes mais tempo. Isto é precisamente o que os percentis revelam e o que a média esconde estruturalmente.

Mecanicamente, não há nada de misterioso em um percentil: classifique todas as latências medidas em ordem crescente e, em seguida, tome o valor na posição correspondente. De 1.000 consultas classificadas, p50 é o 500º valor, p95 o 950º, p99 o 990º. Uma única solicitação anormalmente lenta entre 1000 é suficiente para fazer o p99 se mover – é justamente sua sensibilidade a casos raros que o torna útil, onde essa mesma solicitação isolada quase não tem efeito na média.

Sinal revelador: o relatório de texto que pgbench - a ferramenta oficial de benchmark do PostgreSQL - exibe por padrão fornece uma média e um desvio padrão, não percentis (postgresql.org/docs/current/pgbench.html, acessado em 23 de agosto de 2026). Sua documentação oficial também alerta: “Nunca acredite em nenhum teste que rode apenas alguns segundos” – nunca acredite em um teste que rode apenas alguns segundos, o que se aplica tanto à duração quanto à métrica escolhida.

k6, a ferramenta de carregamento que usamos para o nível 2 de nossa suíte, resolve isso com limites expressos em percentil: a sintaxe p(95)<500 define um critério de aprovação/reprovação — 95% das solicitações devem responder dentro de 500 ms — diretamente na configuração de teste (grafana.com/docs/k6, consultado em 23 de agosto de 2026).

p50 (mediana)Metade das consultas são mais rápidas que esse valorEsconde completamente a cauda de distribuição
p951 em cada 20 consultas é mais lentaÁrea onde aparecem os primeiros usuários insatisfeitos
p991 em cada 100 consultas é mais lentaMais sensível à omissão coordenada se o protocolo for mal projetado
#
Verificado no código

Os 3 níveis de benchmark já presentes em nosso repositório

Publicar uma metodologia sem ferramentas reais seria apenas mais uma forma de teatro. A pasta benchmarks/ no repositório Aurabase já contém um conjunto de 3 níveis, inspirado em sua estrutura na metodologia pública Supabase - as ferramentas existem, os resultados medidos e datados ainda não existem.

3
NÍVEIS DE TESTE
Micro, carga HTTP, comparação
3
CAIXAS BENCHMARKADAS
aura-crypto, adaptadores aura-db, aura-core
8
SCRIPTOS K6
7 conectados ao Makefile, 1 esperando

Nível 1 - Critério de micro-benchmarks.rs

Três caixas do espaço de trabalho Cargo têm benchmarks dedicados vinculados à CPU: aura-crypto (hash Argon2, JWT HS256 — geração, validação e assinatura para PostgREST, criptografia AES-GCM), aura-db-adapters (filtros de análise e select no formato PostgREST — eq., gte., in.(), incorporações de relacionamento) e aura-core (serialização JSON, resolução schema_name, validação UUID).

libs/aura-crypto/benches/crypto_bench.rsrust
// Extrato real do repositório
let mut group = c.benchmark_group("jwt/hs256");

group.bench_function("generate", |b| {
    b.iter(|| jwt::generate_access_token(
        black_box(user_id), black_box(project_id),
        black_box("authenticated"), black_box(SECRET),
    ))
});

group.bench_function("validate", |b| {
    b.iter(|| jwt::validate_token(black_box(&token), black_box(SECRET)))
});

aura-db-adapters mede especificamente o custo de análise de consultas no formato PostgREST - quatro casos para filtros (simple_4, complex_10, or_group, in_large_50 com 50 valores) e quatro para select (colunas únicas, *, uma relação incorporada, cinco incorporações). Este é o tipo de custo invisível em um teste de carga global: uma regressão na análise de um filtro or.(...) complexo não mudaria quase nada no p95 de um endpoint pouco utilizado, mas se tornaria mensurável em um endpoint com alto tráfego - daí o interesse em isolá-lo em um micro-benchmark em vez de depender apenas do nível 2.

aura-core adota uma abordagem diferente: em vez de medir o tempo bruto, ele mede a taxa de transferência (Throughput::Bytes) na serialização JSON e desserialização de mensagens NatsRequest/NatsResponse internas trocadas entre o gateway e os serviços - com três tamanhos de carga úteis realistas (uma solicitação mínima, uma solicitação com um corpo JSON aninhado, uma resposta de lista de 50 linhas).

libs/aura-core/benches/core_bench.rsrust
group.throughput(Throughput::Bytes(
    serde_json::to_vec(&small).unwrap().len() as u64
));
group.bench_function("NatsRequest/small", |b| {
    b.iter(|| serde_json::to_vec(black_box(&small)).unwrap())
});

Criterion.rs não apenas cronometra um loop. Ele primeiro executa uma fase de aquecimento para preencher os caches da CPU/SO, detecta outliers com uma versão modificada do método de Tukey (sem excluí-los do conjunto de dados), calcula intervalos de confiança inicializando um grande número de amostras reamostradas e detecta regressões de desempenho entre duas execuções pelo teste estatístico de Student, com um limite de ruído configurável - normalmente ± 1% - para ignorar variações que não são estatisticamente significativas (bheisler.github.io/criterion.rs/book/análise.html, acessado em 23 de agosto de 2026).

Reproduzível localmente

Cada execução do Criterion gera um relatório HTML detalhado em target/criterion/ — distribuições, gráficos de regressão, comparação com a execução anterior. É esta relação, e não apenas uma linha terminal, que uma metodologia séria deve permitir regenerar.

Nível 2 – teste de carga k6

Oito scripts k6 cobrem o gateway no lado do plano de dados: health (linha de base de latência), auth-flow (registro → login → atualização → logout), crud-read e crud-write, storage (upload/download), realtime-ws, breakpoint (aumento de carga até falha) e supabase-compare. Sete estão conectados a um alvo Makefile dedicado — supabase-compare.js existe no repositório, mas ainda não tem um alvo, um estado de coisas que este artigo documenta como está, em vez de disfarçá-lo.

benchmarks/k6/scenarios/crud-read.jsjavascript
export const options = {
  scenarios: {
    crud_read: {
      executor: 'ramping-vus',
      startVUs: 10,
      stages: [
        { duration: '30s', target: 50 },
        { duration: '1m', target: 200 },
        { duration: '30s', target: 0 },
      ],
    },
  },
  thresholds: THRESHOLDS_READ,
}

A configuração compartilhada define limites por tipo de operação. Estes são critérios de aprovação/reprovação que o teste verifica cada vez que é executado – e não resultados já medidos:

Leitura (GET)p95 < 500 ms · p99 < 1000 msConfiguração k6 (benchmarks/k6/lib/config.js)
Escrita (POST/PATCH)p95 < 300 ms · p99 < 1000 msConfiguração k6
Autenticação (login/atualização)p95 < 300 ms · p99 < 1000 msConfiguração k6
Armazenamento (upload/download)p95 < 500 ms · p99 < 2.000 msConfiguração k6
Taxa de erro, todos os cenários< 1 %Configuração k6
Uma inconsistência encontrada ao escrever este artigo

O README.md na pasta benchmarks/ documenta um limite de leitura de p95 em < 200ms ("Supabase SLO"), enquanto o limite realmente aplicado em benchmarks/k6/lib/config.js — aquele que o teste executa — é p(95)<500. Os dois arquivos são derivados um do outro. Este é um exemplo concreto, encontrado durante a leitura do código-fonte deste artigo, de por que um protocolo deve ter uma única fonte de verdade com versão em vez de ser documentado em dois lugares: sem ela, mesmo uma equipe que tenta ser rigorosa acaba publicando limites conflitantes.

Nível 3 – Comparação direta entre PostgreSQL e API

Um script Python (direct_vs_api.py) mede a sobrecarga real da camada gateway + serviço comparando solicitações psycopg2 diretas com chamadas HTTP na mesma operação - lista, leitura única por id, leitura filtrada e classificada. Cada medição segue um aquecimento de 10 iterações antes do loop cronometrado e, em seguida, calcula a média, p50, p95, p99 e um rendimento em operações por segundo.

benchmarks/comparison/direct_vs_api.pypython
def percentile(data, p):
    k = (len(data) - 1) * (p / 100)
    f = int(k)
    c = f + 1
    if c >= len(data):
        return data[f]
    return data[f] + (k - f) * (data[c] - data[f])

Um segundo script (aurabase_vs_supabase.py) aplica a mesma lógica de aquecimento e cálculo de percentil a uma comparação direta com uma instância local do Supabase (Supabase CLI, localhost:54321 por padrão) - mesma máquina, mesma rede local para ambos, exatamente a disciplina de paridade de ambiente que o PlanetScale documenta para suas próprias comparações.

Um script de orquestração (collect_baseline.sh, alvo bench-baseline de Makefile) conecta os três níveis - Critério nas 3 caixas, um subconjunto dos cenários k6 (health e crud-read hoje, nem todos os 8 ainda), então a comparação Python - e grava logs, relatórios JSON e Criterion HTML em uma pasta com carimbo de data / hora exclusivo: benchmarks/results/AAAAMMJJ_HHMMSS/. Este é exatamente o reflexo da divulgação datada, em uma única execução reprodutível, que a seção seguinte formaliza em um protocolo completo.

#
Metodologia

O protocolo que aplicaremos antes de publicar uma figura

Oito compromissos, cada um ancorado numa prática já documentada por uma ferramenta ou projeto de terceiros reconhecido – não inventado para a ocasião.

  1. Pré-aquecimento separado da medição. Criterion.rs preenche caches de CPU/SO antes do tempo; pgbench recomenda explicitamente nunca acreditar em uma corrida que dura apenas alguns segundos.
  2. Duração fixa, não um número fixo de iterações. Uma carga precisa de tempo para convergir - esta é a função de stages k6 e o ​​sinalizador -T de pgbench.
  3. Percentis, nunca apenas a média — e vigilância ativa na omissão coordenada caso o gerador de carga opere em malha fechada.
  4. Ambiente documentado em detalhes: git commit do serviço testado, versão do PostgreSQL, especificação de hardware, versão da ferramenta de carregamento. O PlanetScale documenta seus parâmetros TPCC exatos (TABLES=20, SCALE=250, ~500 GB) exatamente por esse motivo – sem esses detalhes, ninguém pode reproduzir uma execução.
  5. Resultados com carimbo de data e hora e versão, nunca um único número gravado em uma página de marketing sem data. O ferramental atual já está gravado em um arquivo datado; será necessário alargar este reflexo a qualquer medição publicada publicamente, com a região anfitriã documentada como qualquer outra variável ambiental (ver o nosso guia sobre Soberania anfitriã da UE, relevante assim que um valor depender de uma determinada região).
  6. Scripts e dados brutos publicados junto com o resultado agregado, não apenas uma média final. A PlanetScale convida ainda os leitores a reportarem um erro metodológico num endereço dedicado – uma postura que consideramos saudável e que queremos retomar.
  7. Taxa de transferência anunciada junto com a latência, não apenas uma ou outra. Um sistema pode ter excelente latência em baixa carga e colapso na taxa de transferência à medida que a simultaneidade aumenta - isso é exatamente o que o cenário breakpoint (escala até travar) de nossa suíte k6 foi projetado para revelar e o que a medição de microbenchmark Throughput::Bytes do Criterion captura no nível da função.
  8. Lacuna significativa antes de anunciar uma melhoria. Uma variação de alguns por cento entre duas execuções pode ser um ruído de medição em vez de um ganho real — Criterion.rs calcula a probabilidade de que a diferença observada seja devida ao acaso antes de qualificá-la como regressão ou melhoria. Um número isolado, sem esta verificação, é apenas uma anedota estatística.
#
Compromisso editorial

O que não faremos

Esta lista conta tanto quanto o protocolo positivo acima.

  • Comparar diferentes topologias (instâncias auto-hospedadas versus gerenciadas, frias versus pré-aquecidas) sem reportá-las explicitamente.
  • Retenha a melhor sequência de dez sem mencionar os outros nove.
  • Publicar uma figura sem data, sem versão de serviço, sem roteiro de reprodução.
  • Republicar uma figura de marketing existente, desde que não seja atribuída a este protocolo.
  • Comparar-nos a um concorrente com base num valor bruto de desempenho se esse concorrente não publicar a sua própria metodologia de forma equivalente – um número versus silêncio não é uma comparação, é um slogan.
Um exemplo concreto, já corrigido internamente

Um número como “partida a frio inferior a 1 ms” circulou sem ser apoiado por um benchmark reproduzível. Agora é tratado internamente como sem suporte e não deve ser lido como uma característica medida do produto até que qualquer medição datada, com metodologia publicada, o confirme. Este é precisamente o tipo de afirmação que este protocolo existe para evitar que se repita.

#
Repetível

O protocolo mínimo para benchmarking de qualquer back-end

Este protocolo não depende de nenhuma ferramenta específica do Aurabase — você pode aplicá-lo à sua própria API hoje mesmo.

  1. Defina a carga antes de a ferramenta: somente leitura, gravação, mix realista para seu aplicativo - não uma proporção genérica copiada de outro projeto.
  2. Separe explicitamente a fase de pré-aquecimento da fase de medição.
  3. Execute o teste por tempo suficiente – minutos, não segundos.
  4. Medir em percentis (p50/p95/p99), nunca apenas em média.
  5. Verifique se o seu gerador de carga não está em malha fechada ou corrija a omissão de coordenação na análise.
  6. Isole o ambiente em teste – sem vizinhos barulhentos, sem tarefas concorrentes em segundo plano.
  7. Publique a versão testada, a data, as especificações de hardware e o script – não apenas o resultado final.

Em uma base simples do Postgres, este protocolo recebe um comando pgbench — 20 clientes simultâneos distribuídos em 4 threads, por 5 minutos, com um relatório de progresso a cada 10 segundos:

terminalbash
# Inicialize o conjunto de dados de teste (fator de escala >= número de clientes)
pgbench -i -s 50 ma_base

# -c clientes simultâneos, -j threads, -T duração em segundos, -P intervalo de relatório
pgbench -c 20 -j 4 -T 300 -P 10 ma_base
#
Ferramentas

Ferramentas de referência, por nível

Cinco ferramentas, cada uma adequada a um nível diferente da pilha – nenhuma substitui as outras.

Microfone (função)Critério.rsCPU pura, estatísticas de bootstrap
Consulta SQLbanco de dadosTransação semelhante a TPC-B, tps e latência
Carga HTTP/WSk6 (Grafana)Percentis, limites de aprovação/reprovação
OLTP em escalasysbench + TPCC (metodologia do telescópio)QPS, custo por desempenho
Correção de mediçãoHistograma HDRCompensa a omissão coordenada
#
Perguntas frequentes

Perguntas frequentes

Por que a Aurabase ainda não está publicando números de benchmark?+
Porque até o momento nenhum valor de desempenho foi medido de acordo com um protocolo publicado e reproduzível. Um número como “arranque a frio inferior a 1 ms”, por exemplo, circulou sem ser apoiado por uma referência reproduzível: é hoje tratado como infundado e não deve ser lido como uma característica medida do produto. Este artigo documenta o protocolo que seguiremos antes de publicar um resultado, justamente para evitar a repetição desse tipo de afirmação.
O que é um percentil p95 ou p99 e por que não a média?+
O p95 é o tempo de resposta abaixo do qual 95% das solicitações são encontradas – 1 em cada 20 solicitações é, portanto, mais lento. O p99 aumenta esse limite para 1 solicitação em 100. A média esconde essas solicitações lentas porque as dilui na massa de solicitações rápidas; os percentis isolam a cauda da distribuição que os usuários realmente percebem.
O que é “omissão coordenada”?+
Este é um viés de medição descrito pelo projeto HdrHistogram: quando uma ferramenta de carregamento espera pela resposta a uma solicitação antes de enviar a próxima (loop fechado), uma pausa no serviço reduz mecanicamente o número de solicitações lentas registradas durante essa pausa. O resultado final pode mostrar uma latência muito melhor do que a experimentada por um usuário real.
Podemos reproduzir esses testes nós mesmos?+
O protocolo descrito aqui — percentis, pré-aquecimento separado, ambiente documentado, resultados datados — é aplicável a qualquer API, com ferramentas públicas (k6, pgbench, Criterion.rs, sysbench). As ferramentas internas do Aurabase (a pasta benchmarks/repository) são atualmente usadas para desenvolvimento e ainda não estão empacotadas como um pacote público de um clique. Crie um projeto para testar sua própria carga na API Aurabase com seus próprios scripts k6.
Qual é a diferença entre um percentil medido e um limite de SLA?+
Um percentil (p95, p99) é uma estatística calculada após o fato em medições reais. Um limite de SLA (ou um limite k6 como p(95)<500) é uma meta definida antecipadamente, que o teste verifica no modo aprovado/reprovado. Confundir os dois leva a apresentar um objetivo não alcançado como resultado obtido – esta é precisamente a distinção que este protocolo exige que seja mantida explícita em cada figura publicada.
Por que medir o rendimento além da latência?+
Um sistema pode responder rapidamente com carga baixa e ver sua latência diminuir repentinamente quando um limite de simultaneidade é excedido – a latência por si só não mostra onde está esse limite. Medir a taxa de transferência (solicitações ou bytes por segundo) juntamente com a latência revela esse ponto de inflexão, que é algo que o cenário de ponto de interrupção do nosso pacote k6 foi projetado especificamente para encontrar.

PRONTO PARA IMPLEMENTAR?

Seu back-end em cinco minutos.

Não é necessário cartão de crédito · 500 MB grátis · 50.000 MAU