
Si salgo a producción sin revisar límites de API, me expongo a 429, colas trabadas, stock viejo y mensajes fuera de orden.
La idea central de esta nota es simple: antes del go-live, yo tengo que revisar Shopify, VTEX y Tiendanube, definir prioridades, preparar retries, medir 429, y probar qué pasa cuando el sistema baja funciones para no cortar ventas ni soporte.
En una pasada, esto es lo que me llevo:
Retry-After.| Plataforma | Cómo limita | Qué miro primero | Qué hago antes del 429 |
|---|---|---|---|
| Shopify | REST por bucket, GraphQL por puntos | Headers REST y costo GraphQL | Separar tráfico, encolar webhooks, pausar tareas livianas |
| VTEX | Por ruta, cuenta e IP | 429 y Retry-After | Priorizar pedidos y soporte, aplicar backoff con jitter |
| Tiendanube | Bucket por tienda y app |
x-rate-limit-limit, remaining, reset |
| Bajar ritmo, reservar cuota para stock, pedidos y precios |
Yo resumiría el checklist así: medir, priorizar, encolar, degradar y validar formato local antes de lanzar.

Rate Limits por Plataforma: Shopify, VTEX y Tiendanube
Cada plataforma pone sus propios topes. Antes de salir a producción, conviene chequear que la integración respete esas reglas en lecturas, escrituras y sincronización. No alcanza con que “funcione”: también tiene que aguantar carga sin chocar contra límites. En Shopify, por ejemplo, REST, GraphQL y webhooks no consumen igual.
Shopify REST usa un modelo de leaky bucket o “balde con fuga”: 40 solicitudes por app y tienda, con recarga de 2 por segundo. En Shopify Plus, ese límite se multiplica más o menos por 10. El header X-Shopify-Shop-Api-Call-Limit muestra el uso en formato usados/total.
GraphQL va por otro camino. En vez de contar pedidos de API uno por uno, limita por costo de consulta: 1.000 puntos con recarga de 50 por segundo. Por eso hay que seguir de cerca extensions.cost.currentlyAvailable.
| Modelo | Límite | Recarga | Métrica clave |
|---|---|---|---|
| Admin REST | 40 solicitudes/bucket | 2 sol/s | X-Shopify-Shop-Api-Call-Limit |
| Admin GraphQL | 1.000 puntos | 50 puntos/s | extensions.cost.currentlyAvailable |
| Shopify Plus (REST) | ~10x el estándar | Tasa proporcional al estándar | Mismo header |
Separar el tráfico de Admin y Storefront API ayuda a que el chatbot, las automatizaciones y la sincronización no peleen por la misma cuota. Si no hacés esa separación, una punta puede ahogar a la otra.
Con los webhooks pasa algo parecido. Los eventos entrantes no traen un límite de entrega explícito, pero cada evento que termina en llamadas al Admin sí consume cuota. Entonces, la jugada sana es esta: verificar el HMAC, mandar el trabajo a una cola durable y procesarlo de forma asíncrona. Así evitás que una ola de eventos frene las lecturas y escrituras del chatbot.
VTEX limita por IP, cuenta y ruta, pero varios topes no están publicados. Cuando te pasás, responde con 429 y Retry-After. Algunas APIs sí muestran números concretos. Pricing API publica límites de PUT/POST cerca de 40 sol/s con 1.000 de cupo de ráfaga, y DELETE en 16 sol/s con 300 de cupo de ráfaga. Catalog API llega a 45.000 solicitudes por minuto por cuenta y 15.000 por minuto por endpoint.
| API de VTEX | Límite documentado | Acción |
|---|---|---|
| Pricing (PUT/POST) | ~40 sol/s, 1.000 cupo de ráfaga | Alertar antes del máximo |
| Pricing (DELETE) | ~16 sol/s, 300 cupo de ráfaga | Alertar antes del máximo |
| Catalog | 45.000 sol/min por cuenta | Monitoreo preventivo |
| Orders / OMS | No publicado | Monitorear 429 + Retry-After |
| Master Data | No publicado | Monitorear 429 + Retry-After |
Acá conviene poner prioridades claras. Las lecturas de soporte y las operaciones críticas deberían ir antes que los jobs masivos. Si llega un 429, aplicá backoff exponencial con jitter y respetá Retry-After.
En Tiendanube, además, hay otro detalle: el plan de la tienda cambia la capacidad disponible.
Tiendanube sí documenta su modelo con bastante detalle: un bucket de 40 solicitudes por tienda y por app, con una tasa de fuga de 2 solicitudes por segundo. En la práctica, eso sostiene hasta 120 solicitudes por minuto sin ráfagas. En los planes Next/Evolution, los límites se multiplican por 10. Por eso la integración tiene que detectar el plan de cada tienda y mover sus umbrales internos en base a eso.
Cada respuesta incluye tres headers que vale la pena leer y mandar al monitoreo:
x-rate-limit-limit: indica la capacidad total del bucket. Sirve para configurar el cliente con ese valor por tienda.x-rate-limit-remaining: muestra cuántas solicitudes quedan. Cuando se acerca a cero, hay que bajar el ritmo.x-rate-limit-reset: marca los milisegundos hasta que el bucket se recupere. Con ese dato podés calcular cuánto esperar antes del próximo intento.En Burbuxa, conviene reservar cuota para stock, pedidos y precios. Si sube el volumen de conversaciones, lo primero para pausar son las sincronizaciones de fondo cuando la cuota empieza a caer.
El tráfico de varios canales comparte cuota, y una sola campaña puede trabar soporte y ventas. Con ese presupuesto en mente, el paso siguiente es ordenar canales, prioridades y reglas de degradación.
Tomá el límite más estricto de cada plataforma y repartí la cuota por canal según la demanda, dejando el total por debajo del 70–80% del techo documentado. En VTEX, separar ventanas por ruta evita que las búsquedas de catálogo o las cargas masivas compitan con pedidos y autorizaciones de pago. En Tiendanube, además del ritmo sostenido, conviene mirar el tamaño del bucket y la velocidad de fuga, para no confundir una ráfaga válida con un consumo que más tarde se rompe. Los eventos que entran por webhook tienen que procesarse de forma asíncrona con colas durables, sin gastar cuota en el flujo principal.
Más que el canal, manda la prioridad de la tarea. Un esquema simple usa tres niveles: crítico, importante y oportunista. Las tareas críticas - creación de pedidos, confirmación de pago, cancelaciones y reservas de stock - necesitan colas dedicadas con SLOs de latencia estrictos. Las tareas oportunistas - recomendaciones de producto, enriquecimiento de catálogo y descargas masivas de reseñas - tienen que poder pausarse de forma explícita: cuando el consumo global llega al 60–70% de la cuota, se frenan o pasan a lotes. En Burbuxa, cada llamada a la API puede llevar una etiqueta de prioridad para que el middleware decida si ejecuta, encola o degrada la acción.
Una implementación práctica es usar token buckets por plataforma, canal y prioridad. Así, un pico en WhatsApp no vacía el presupuesto de Instagram ni bloquea un flujo crítico de soporte.
El piso de observabilidad incluye conteo de 429 por plataforma y endpoint, RPS por ruta, longitud de cola por nivel de prioridad, demora de workers y latencia del chatbot por canal. Un dashboard útil superpone el RPS de WhatsApp e Instagram sobre los límites de cada plataforma y separa el estado del leaky bucket de Tiendanube, la cuota restante por ruta en VTEX y los errores limitados por cuota en GraphQL de Shopify. Los headers de rate limit de Tiendanube sirven como señal de monitoreo para autorregular el tráfico antes de que aparezcan rechazos.
Las alertas conviene dividirlas en tres niveles: aviso temprano cuando los 429 superan el 1–2% de las solicitudes en 5–10 minutos, acción cuando pasan el 5%, y crítico cuando superan el 10% o cuando cualquier endpoint de pedidos o pagos empieza a fallar. La idea es intervenir antes de que el usuario vea el problema.
Los logs estructurados te dejan seguir una conversación lenta hasta la llamada API que la frenó. Cada entrada debería incluir estos campos, y cada uno tiene que quedar ligado a una acción de encolado, alerta o degradación.
conversation_id y request_id - para correlacionar la conversación con la llamadaRetry-After - para calcular la espera antes del reintentoCuando la cuota se acerca al techo, conviene activar respuestas más baratas antes del 429.
| Disparador | Acción de degradación |
|---|---|
| Bucket de Shopify REST cerca del techo | Pausar tareas oportunistas |
| Costo de query GraphQL elevado | Servir recomendaciones desde caché |
| Cuota de VTEX Pricing cerca del límite | Diferir actualizaciones de precio y aplicar backoff exponencial |
| 429 en VTEX Orders / OMS | Backoff exponencial + alerta inmediata |
| Bucket de Tiendanube estándar cerca del techo | Pausar sincronizaciones de fondo |
| Bucket de Tiendanube Next/Evolution cerca del techo | Reducir frecuencia de campañas y lotes de sync |
El último escalón - mensajes estáticos - se activa cuando los límites ya se pasaron o están por pasarse en endpoints críticos. En ese punto, el chatbot deja de hacer consultas dinámicas de catálogo y responde con mensajes preparados: Estamos procesando muchos pedidos ahora mismo; tu orden se va a confirmar en breve. Solo siguen corriendo las llamadas de pago, cancelación y stock crítico, con throttling estricto.
Antes del go-live, validá estos umbrales con mensajes, fechas y unidades en modo degradado.
Después de definir cuándo degradar, falta chequear qué ve el usuario y cómo lo lee el equipo de soporte. Antes del go-live, validá la localización de mensajes, fechas, números y unidades. Si el sistema entra en modo degradado, cliente y soporte tienen que ver datos correctos, sin sorpresas.
Todos los mensajes de demora o respaldo tienen que estar en es-AR, con voseo cuando corresponda, un tono empático y sin jerga técnica al pedo.
En lugar de mostrar un mensaje genérico, conviene avisar que hay más consultas de lo normal, que el pedido puede tardar unos minutos y que el cliente puede seguir comprando con tranquilidad. Ese cambio parece chico, pero hace una diferencia: baja la ansiedad y evita malos entendidos.
Guardá UTC para auditoría, pero mostrá a soporte y al cliente la hora en ART (America/Argentina/Buenos_Aires), con formato dd/mm/yyyy y reloj de 24 horas. Los flujos automáticos de WhatsApp e Instagram también tienen que usar locale es-AR para sostener el voseo, el formato local y las 24 horas.
Validalo con una prueba corta: creá un evento a las 13:05 y revisá que todas las herramientas lo muestren igual.
Una vez resuelto el tema horario, cerrá el formato de salida. En modo degradado, el formato no puede cambiar. Para Argentina, el estándar es $ 1.234,56: símbolo antes del monto, punto para miles y coma para decimales. Si en modo normal el sistema muestra $ 1.234,56 y en modo degradado pasa a $1,234.56, el comprador desconfía al instante.
Lo mismo corre para las unidades de medida: kg, g, L, ml, cm, m y °C. Los snapshots de caché tienen que quedar pre-normalizados al sistema métrico antes de guardarse. Si el feed de productos viene con libras o pulgadas, la conversión tiene que pasar en la ingesta, no durante el modo degradado.
Estos son los formatos que no pueden romperse:
| Tipo de dato | Fuente en vivo | Fuente degradada | Verificación es-AR |
|---|---|---|---|
| Precios | API en tiempo real (Shopify / VTEX / Tiendanube) | Caché Redis / snapshot JSON | Formato $ 1.234,56; sin formato estadounidense |
| Fechas y horas | Marcas de tiempo de plataforma (UTC) | String localizado desde caché | dd/mm/yyyy, 24 h, zona horaria America/Argentina/Buenos_Aires |
| Stock | Sincronización en tiempo real | Último valor conocido (TTL corto) | Mensaje tipo Stock limitado (última actualización) |
| Envíos y peso | API de logística | Estimación estática con buffer | Unidades: kg, cm; sin lb ni in |
| Temperatura | Metadata del producto (PIM/CMS) | Snapshot pre-normalizado | Solo °C; nunca °F |
Corré una prueba de regresión con 99, 999.9 y 1234.56 en todos los templates, tanto en modo normal como degradado, y compará la salida contra es-AR.
Antes de lanzar, ir a producción sin revisar los rate limits sube el riesgo de incidentes. El checklist tiene que estar aprobado antes del lanzamiento.
Dejá documentados:
Con eso validado, también tienen que quedar definidas las prioridades por canal y tarea: checkout, soporte y recuperación de carrito con IA primero; sync masivo y analytics, después. Y hay un punto más que no se puede pasar por alto: confirmar cómo responde el sistema cuando degrada.
Por último, probá los caminos de degradación en es-AR: mensajes, fechas, hora local, precios en ARS y unidades métricas. Si falta una validación, el lanzamiento se pospone.
Cuando haya picos de tráfico o señales de degradación, frená primero las tareas no críticas y de fondo que se comen recursos. Ahí entran, por ejemplo, procesos asíncronos, tareas de mantenimiento o comunicaciones que pueden esperar un rato sin pegarle de lleno a la experiencia del cliente.
La prioridad tiene que estar en los endpoints que dan la cara, como /checkout y /payments/process. Seguí de cerca el p99 y los errores 4xx y 5xx para detectar fallas apenas aparecen. Si el sistema entra en estrés, conviene darle paso a lecturas rápidas antes que a escrituras pesadas.
Antes de que aparezca el error 429, configurá alertas para detectar señales tempranas de saturación.
Poné el foco en:
También conviene alertar por picos de solicitudes por IP y por subas de latencia en endpoints críticos, incluso si todavía no se alcanzó el límite.
La idea es simple: no esperar a que el sistema empiece a rechazar tráfico para recién ahí actuar. Si seguís estas métricas de cerca, vas a ver el problema venir unos pasos antes.
Probalo en un entorno de sandbox o controlado para simular fallos sin pegarles a clientes reales. Hacé pruebas de carga con k6 o JMeter para recrear picos de demanda y ver cómo responde el sistema cuando aparecen cuellos de botella o errores.
Verificá que la degradación parcial se active cuando se superen los umbrales configurados. Además, corré pruebas sintéticas sobre flujos críticos, como el checkout, y confirmá que las alertas automáticas se disparen ante comportamientos anómalos.