Logo
Nuevos usuarios de RPC: 35% de descuento el primer mesVer oferta
OnFinality Learn
Solución de problemas de RPC12 min de lectura

Límites de tasa de RPC de Solana y errores 429: cómo funcionan y cómo solucionarlos

Comprende los límites de tasa de RPC de Solana, los costos de unidades de solicitud y los errores 429. Aprende soluciones prácticas usando Web3.js, caché y endpoints dedicados.

TL;DR

Los límites de tasa de RPC de Solana se basan en unidades de solicitud (CU) en lugar de simples conteos de solicitudes HTTP. Cada método tiene un costo diferente, y exceder tu presupuesto devuelve HTTP 429. Este artículo explica los mecanismos, muestra cómo observar los límites de tasa con curl y proporciona soluciones prácticas que incluyen lógica de reintento de Web3.js, caché y migración a un endpoint dedicado.

Respuesta directa: ¿Qué causa los errores 429 de RPC de Solana?

Los errores 429 de RPC de Solana ocurren cuando excedes el límite de tasa establecido por el proveedor de RPC. A diferencia del simple conteo de solicitudes HTTP, Solana utiliza un sistema de presupuesto de unidades de solicitud (RU): cada método JSON-RPC tiene un costo diferente, y tu consumo total se mide en un período de tiempo. Cuando excedes el presupuesto, el servidor responde con HTTP 429 Too Many Requests. La solución es reducir tu consumo de RU, implementar reintentos con backoff, almacenar en caché las respuestas o migrar a un endpoint dedicado con límites más altos.

Este artículo explica los mecanismos de limitación de tasa de Solana, muestra cómo observarlos con un simple comando curl y proporciona ejemplos de código para manejar 429 en Solana Web3.js. También discutiremos cuándo es momento de actualizar de un endpoint público a uno dedicado.

Cómo funciona la limitación de tasa de RPC de Solana: unidades de solicitud vs. conteos HTTP

La API JSON-RPC de Solana está documentada en la documentación JSON-RPC de Solana. El concepto clave es que cada método tiene un costo en unidades de solicitud (CU). Por ejemplo, getBalance es barato (1 CU), mientras que getProgramAccounts puede costar hasta 10,000 CU dependiendo del tamaño de los datos. Proveedores como OnFinality aplican un presupuesto de CU por segundo o por minuto. Cuando lo excedes, obtienes un 429.

Este diseño evita que un solo cliente monopolice los recursos con llamadas costosas. También significa que unas pocas llamadas pesadas pueden agotar tu presupuesto más rápido que muchas llamadas ligeras. Por ejemplo, llamar a getBlock con detalles de transacciones es mucho más costoso que getBalance.

Los costos exactos de CU no siempre son publicados por Solana Labs, pero están documentados en recursos de la comunidad y documentación de proveedores. La tabla a continuación enumera costos aproximados basados en la documentación de RPC de Solana y análisis de la comunidad. Estos son aproximados y pueden variar según el proveedor; siempre consulta la documentación de tu proveedor.

  • getBalance – 1 CU
  • getLatestBlockhash – 1 CU
  • getBlock (con detalles de transacciones) – 100-200 CU
  • getSignaturesForAddress – 100-200 CU por página
  • getProgramAccounts – hasta 10,000 CU dependiendo del tamaño de los datos

Límites predeterminados de endpoints públicos y descarga de carga del clúster

Los endpoints públicos de RPC de Solana (como api.mainnet-beta.solana.com) están fuertemente limitados en tasa. Están destinados para pruebas ligeras, no para producción. El endpoint público de OnFinality también tiene límites, pero son más generosos. Sin embargo, incluso con un endpoint público, puedes encontrar 429 durante la congestión de la red.

Los clústeres de Solana también implementan descarga de carga (load-shedding): cuando el nodo está sobrecargado, puede descartar solicitudes o devolver errores incluso si no has alcanzado tu límite de tasa. Esto es separado del límite de tasa de tu proveedor. La descarga de carga es más probable durante alta actividad de red o cuando envías solicitudes costosas.

Para verificar tu límite de tasa actual, puedes revisar los encabezados de respuesta de tu proveedor. Muchos proveedores incluyen x-ratelimit-remaining o encabezados similares. El servicio de API de OnFinality proporciona métricas de uso detalladas.

Observando los límites de tasa con curl: una prueba reproducible

Puedes observar el comportamiento de limitación de tasa con un simple comando curl contra un RPC público de Solana. El siguiente comando envía una solicitud ligera getBalance. Ejecútalo en un bucle para ver cuándo comienzas a recibir respuestas 429.

Nota: El límite de tasa exacto depende del proveedor y la carga actual. Esta prueba es para observación, no un benchmark. Ejecútala varias veces para ver el patrón.

curl -s -X POST https://api.mainnet-beta.solana.com -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1,"method":"getBalance","params":["So11111111111111111111111111111111111111112"]}'

# Bucle para provocar el límite de tasa (usar con precaución)
for i in {1..100}; do curl -s -o /dev/null -w "%{http_code}\n" -X POST https://api.mainnet-beta.solana.com -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1,"method":"getBalance","params":["So11111111111111111111111111111111111111112"]}'; done

Manejo de 429 en Solana Web3.js: reintento y Retry-After

Al usar Solana Web3.js, puedes implementar lógica de reintento con backoff exponencial. La clase Connection de la biblioteca tiene una opción fetch que te permite personalizar el cliente HTTP. También puedes usar un httpAgent personalizado o interceptar respuestas.

Aquí hay un ejemplo práctico que reintenta en 429, respetando el encabezado Retry-After si está presente. Este es un patrón común para aplicaciones de producción.

const web3 = require('@solana/web3.js');
const fetch = require('node-fetch');

const endpoint = 'https://api.mainnet-beta.solana.com';

async function customFetch(url, options) {
  let response = await fetch(url, options);
  if (response.status === 429) {
    const retryAfter = response.headers.get('retry-after');
    const delay = retryAfter ? parseInt(retryAfter) * 1000 : 1000;
    await new Promise(resolve => setTimeout(resolve, delay));
    response = await fetch(url, options);
  }
  return response;
}

const connection = new web3.Connection(endpoint, 'confirmed', {
  fetch: customFetch
});

async function main() {
  const balance = await connection.getBalance('So11111111111111111111111111111111111111112');
  console.log('Balance:', balance);
}

main().catch(console.error);

Caché para reducir el consumo de unidades de solicitud

El almacenamiento en caché es una de las formas más efectivas de evitar 429. Muchas respuestas de RPC son estáticas o cambian con poca frecuencia. Por ejemplo, los saldos de cuentas, las firmas de transacciones e incluso los datos de bloques se pueden almacenar en caché por un corto período.

Implementa un caché simple en memoria con un TTL (tiempo de vida). Para producción, considera Redis o un caché distribuido similar. La clave es almacenar en caché las respuestas que son costosas de obtener, como getProgramAccounts o getSignaturesForAddress.

Aquí hay un envoltorio de caché mínimo para métodos de Web3.js.

const NodeCache = require('node-cache');
const cache = new NodeCache({ stdTTL: 10 }); // 10 segundos TTL

async function cachedGetBalance(connection, address) {
  const key = `balance:${address}`;
  const cached = cache.get(key);
  if (cached) return cached;
  const balance = await connection.getBalance(address);
  cache.set(key, balance);
  return balance;
}

// Uso
const balance = await cachedGetBalance(connection, 'So11111111111111111111111111111111111111112');

Fallos comunes y soluciones

Fallo 1: Alcanzar 429 en endpoints públicos. Solución: Implementa reintentos con backoff, reduce la frecuencia de solicitudes o cambia a un endpoint dedicado.

Fallo 2: Métodos costosos como getProgramAccounts. Solución: Usa filtros para reducir el tamaño de los datos, o almacena en caché los resultados. Considera usar getMultipleAccounts en lugar de hacer un bucle de getAccountInfo.

Fallo 3: No respetar Retry-After. Solución: Siempre analiza el encabezado Retry-After y espera en consecuencia.

Fallo 4: Ignorar la descarga de carga. Solución: Monitorea la salud de la red y ajusta tus patrones de solicitud. Si el clúster está sobrecargado, incluso un endpoint dedicado puede devolver errores.

Compensaciones y limitaciones

Reintentar en 429 es esencial, pero puede aumentar la latencia. El almacenamiento en caché reduce la carga pero puede servir datos obsoletos. Los endpoints dedicados cuestan dinero pero proporcionan límites más altos y confiabilidad.

No hay una solución única para todos. Necesitas equilibrar costo, latencia y frescura de los datos. Para producción, un endpoint dedicado a menudo vale la inversión.

También ten en cuenta que los límites de tasa de Solana no están estandarizados entre proveedores. Siempre consulta la documentación de tu proveedor para límites y costos específicos.

Próximos pasos: migrar a un endpoint dedicado

Si estás alcanzando 429 de manera consistente, es hora de migrar a un endpoint dedicado. OnFinality ofrece endpoints de RPC dedicados de Solana con límites de tasa más altos y sin estrangulamiento compartido. También puedes usar el Asistente de RPC para comparar proveedores.

Para necesidades más avanzadas, explora el servicio de API que proporciona características adicionales como soporte de WebSocket y análisis. Consulta nuestros precios para planes que se ajusten a tu uso.

Si eres nuevo en la solución de problemas de RPC, lee nuestra guía sobre cómo solucionar errores genéricos de RPC 429. Y para más consejos específicos de Solana, explora el centro de aprendizaje de OnFinality.

Tabla de costos de unidades de solicitud de Solana: métodos costosos vs. baratos

Comprender el costo relativo de cada método de RPC es crucial para mantenerse dentro de tu presupuesto de unidades de solicitud. La tabla a continuación proporciona costos aproximados de CU para métodos comunes, basados en análisis de la comunidad y documentación de proveedores. Estos son estimados; siempre verifica con tu proveedor.

Los métodos baratos como getBalance, getLatestBlockhash y getSlot cuestan solo 1 CU cada uno. Son seguros de llamar con frecuencia. Los métodos de costo medio como getBlock (sin detalles de transacciones) y getSignaturesForAddress varían de 100 a 200 CU por llamada. Los métodos costosos como getProgramAccounts pueden costar hasta 10,000 CU, especialmente al obtener cuentas grandes sin filtros.

Para minimizar costos, prefiere métodos baratos cuando sea posible. Por ejemplo, usa getMultipleAccounts en lugar de múltiples llamadas getAccountInfo, y usa getSignaturesForAddress con paginación para limitar el tamaño de los datos.

  • 1 CU: getBalance, getLatestBlockhash, getSlot, getBlockHeight
  • 100-200 CU: getBlock (sin detalles de transacciones), getSignaturesForAddress (por página), getTransaction (con detalles)
  • Hasta 10,000 CU: getProgramAccounts (dependiendo del tamaño de los datos y filtros)

getProgramAccounts: el que más consume y cómo indexar en su lugar

getProgramAccounts es conocido por consumir cantidades masivas de unidades de solicitud. Puede devolver grandes cantidades de datos, y sin filtros adecuados, puede agotar fácilmente tu presupuesto. Muchos desarrolladores lo usan para obtener todas las cuentas propiedad de un programa, pero esto a menudo es innecesario e ineficiente.

En lugar de llamar repetidamente a getProgramAccounts, considera indexar los datos fuera de la cadena. Puedes usar un servicio como Helius o QuickNode para indexar datos de programas, o ejecutar tu propio indexador usando WebSockets para escuchar cambios de cuentas. De esta manera, solo obtienes los datos que necesitas, cuando los necesitas, reduciendo la carga de RPC.

Si debes usar getProgramAccounts, siempre aplica filtros para reducir los resultados. Por ejemplo, usa filtros dataSize o memcmp para reducir el tamaño de la respuesta. Además, almacena en caché los resultados y actualízalos periódicamente en lugar de en cada solicitud.

Programación de tráfico de alto CU fuera de horas pico y uso de paginación de getSignaturesForAddress

Si tu aplicación realiza operaciones de RPC pesadas, como sincronizar datos históricos, considera programarlas durante horas de baja actividad. La congestión de la red y la carga del proveedor son típicamente menores durante estos períodos, reduciendo la probabilidad de alcanzar límites de tasa.

Para obtener el historial de transacciones, usa getSignaturesForAddress con paginación. Este método devuelve una lista de firmas para una dirección dada, y puedes paginar a través de ellas usando el parámetro before. Este enfoque es más eficiente que obtener todas las firmas de una vez, y te permite controlar el volumen de datos.

Aquí hay un ejemplo de paginación a través de firmas usando Web3.js. El bucle obtiene firmas en lotes de 100, procesando cada lote antes de pasar al siguiente. Esto reduce la carga en el RPC y te ayuda a mantenerte dentro de tu presupuesto.

const web3 = require('@solana/web3.js');

const connection = new web3.Connection('https://api.mainnet-beta.solana.com');
const address = 'So11111111111111111111111111111111111111112';

async function getSignaturesPaginated(address, limit = 100) {
  let signatures = [];
  let before = undefined;
  while (true) {
    const batch = await connection.getSignaturesForAddress(address, { limit, before });
    if (batch.length === 0) break;
    signatures = signatures.concat(batch);
    before = batch[batch.length - 1].signature;
    // Procesar lote aquí
  }
  return signatures;
}

getSignaturesPaginated(address).then(sigs => console.log(`Total de firmas: ${sigs.length}`));

Supuestos y límites

Este artículo asume que estás usando un proveedor de RPC estándar de Solana y que los costos de unidades de solicitud son como los documentados por Solana Labs y fuentes de la comunidad. Sin embargo, las cuotas de los proveedores varían significativamente. Algunos proveedores pueden tener límites más bajos o más altos, y pueden aplicar diferentes algoritmos de limitación de tasa.

Antes de implementar en producción, siempre consulta el panel de control o la documentación de tu proveedor para comprender tus límites específicos. OnFinality, por ejemplo, proporciona métricas de uso detalladas en su panel de control. Además, ten en cuenta que los costos de CU enumerados aquí son aproximados y pueden cambiar a medida que Solana evoluciona.

Finalmente, los ejemplos de código están simplificados para ilustración. En producción, debes agregar manejo de errores adecuado, registro y monitoreo para asegurar que tu aplicación se comporte correctamente bajo límites de tasa.

Nunca te preocupes por la infraestructura nuevamente

OnFinality elimina la carga pesada de DevOps para que puedas construir de forma más inteligente y rápida.

Comenzar