Home > Blog > Desenvolvimento Web
Desenvolvimento Web
JavaScript
Programação

Cursor Pagination no Node.js: paginação estável

Atualizado em: 22 de outubro de 2026

Estação de trabalho usada no desenvolvimento de aplicações Node.js

Cursor Pagination no Node.js percorre listas usando a posição do último item retornado, em vez de descartar linhas com OFFSET. Essa abordagem mantém desempenho previsível em tabelas grandes e reduz inconsistências quando novos registros são inseridos.

Problema do OFFSET

SELECT id, created_at
FROM orders
ORDER BY created_at DESC
LIMIT 50 OFFSET 500000;

O banco ainda precisa localizar e descartar grande quantidade de linhas. Além disso, inserções entre páginas podem causar itens repetidos ou ausentes.

Keyset pagination

SELECT id, created_at, total
FROM orders
WHERE (created_at, id) < ($1, $2)
ORDER BY created_at DESC, id DESC
LIMIT 51;

O par created_at, id cria ordenação estável. O ID resolve empates de timestamp.

Primeira página

SELECT id, created_at, total
FROM orders
ORDER BY created_at DESC, id DESC
LIMIT 51;

Busque um item extra para descobrir se existe próxima página.

Codificando o cursor

function encodeCursor(row) {
  return Buffer.from(JSON.stringify({
    createdAt: row.created_at,
    id: row.id
  })).toString('base64url');
}

function decodeCursor(cursor) {
  return JSON.parse(Buffer.from(cursor, 'base64url').toString('utf8'));
}

Base64 apenas codifica. Valide estrutura e valores. Para impedir alteração, assine o cursor com HMAC ou use criptografia autenticada quando o conteúdo não deve ser visível.

Resposta da API

{
  "items": [],
  "pageInfo": {
    "hasNextPage": true,
    "endCursor": "..."
  }
}

Índice necessário

CREATE INDEX idx_orders_cursor
ON orders (created_at DESC, id DESC);

Filtros adicionais devem participar do desenho do índice. Consulte Índices PostgreSQL no Node.js.

Filtros

O cursor pertence ao conjunto filtrado. Se usuário mudar status, tenant ou ordenação, descarte o cursor anterior ou inclua uma assinatura dos filtros.

Multi-tenancy

WHERE tenant_id = $1
  AND (created_at, id) < ($2, $3)

Inclua tenant_id no índice e nunca aceite tenant apenas do cursor. A identidade validada continua sendo a fonte.

Página anterior

Para navegar para trás, inverta operador e ordenação na query, depois reverta os itens na aplicação. Mantenha testes para limites e empates.

Ordenação por campo mutável

Cursores funcionam melhor com colunas estáveis. Ordenar por status ou pontuação que muda frequentemente pode deslocar itens entre páginas. Para snapshots rigorosos, registre um limite temporal ou versão do conjunto.

Consistência

A paginação por cursor não congela o banco. Ela oferece travessia estável relativa à chave. Novos itens podem aparecer antes do cursor e serão vistos em uma nova navegação.

Limites

Defina tamanho mínimo e máximo de página. Não permita que o cliente solicite milhões de itens.

const limit = Math.min(Math.max(Number(input.limit) || 20, 1), 100);

Segurança do cursor

  • limite o tamanho;
  • valide tipos;
  • rejeite datas inválidas;
  • não coloque segredo no payload;
  • assine quando alterações forem relevantes;
  • não use cursor para autorização.

GraphQL

O modelo Relay usa edges, nodes e pageInfo. Mesmo em REST, a ideia de cursor opaco e hasNextPage é útil.

Observabilidade

Meça duração, quantidade retornada, uso de índice e erros de cursor. Não use o cursor completo como label ou log em alta escala.

Testes

  • primeira e última página;
  • timestamps iguais;
  • cursor inválido;
  • inserção entre páginas;
  • filtros diferentes;
  • tenant incorreto;
  • página anterior;
  • limite máximo.

Erros comuns

  • usar apenas timestamp;
  • não criar índice compatível;
  • aceitar cursor sem validação;
  • misturar filtros;
  • ordenar por campo muito mutável;
  • expor cursor como autorização;
  • não buscar item extra.

Conclusão

Cursor Pagination no Node.js oferece desempenho estável e navegação consistente em listas extensas. Use uma chave composta única, índice compatível, cursor opaco validado e limites de página.

Consulte a documentação de LIMIT e OFFSET do PostgreSQL, a documentação de ordenação e Query Optimization no Node.js.

10 melhores cursos de programação em 2026

Descubra os melhores cursos de programação. Aprenda a escolher o curso ideal para iniciar ou avançar na carreira de desenvolvedor

POSTS RELACIONADOS

Ver todos

Seta para a direita