El 8 de julio de 2026 SIG etcd publicó etcd v3.7.0, y la novedad que se llevó todos los titulares tiene nombre propio: RangeStream. No es una feature cosmética. Ataca uno de los dolores más viejos de operar Kubernetes a escala: qué pasa cuando el kube-apiserver le pide a etcd una lista enorme —todos los Pods, todos los Secrets, todos los Events de un namespace cargado— y etcd tiene que armar toda esa respuesta en memoria antes de mandar el primer byte. En clusters grandes eso se traducía en picos de RAM impredecibles y, en el peor caso, OOM.
etcd v3.7 es la última versión mayor del almacén de clave-valor distribuido que funciona como base de datos de estado de Kubernetes. Su cambio central, RangeStream, es un RPC de server-streaming que entrega el resultado de una consulta de rango en fragmentos (chunks) en lugar de bufferear la respuesta completa. Con eso, el consumo de memoria del servidor se vuelve acotado y predecible, y la latencia de las lecturas grandes deja de depender del tamaño total del resultado. Salió el 8 de julio de 2026.
¿Por qué un LIST grande de Kubernetes reventaba la memoria de etcd?

Porque el RPC clásico Range es unario: arma la respuesta entera y recién ahí la manda. Según el KEP 5966 de Kubernetes, en una sola consulta grande tienen que coexistir en memoria tres copias del resultado al mismo tiempo: el slice de key-values en Go, su serialización protobuf y el buffer de envío de gRPC. Cuanto más grande el rango, más chances de que el pico de memoria termine en un out-of-memory del proceso.
El problema tiene dos caras, y las dos escalan mal:
- Picos de memoria por bufferear todo de una. No hay backpressure: el servidor no puede empezar a soltar datos hasta tener el resultado completo formado. En un cluster con decenas de miles de objetos, un solo LIST puede rozar límites incómodos (protobuf tiene un techo práctico de 2 GB por mensaje).
- Paginar no salía gratis. La forma habitual de esquivar el problema era pedir de a páginas con
limit. Pero cada página recalculaba el total recorriendo todo el índice B-tree de nuevo, convirtiendo una operación que debería ser O(limit) en O(total_keys) repetida por cada página. Paginabas para ahorrar memoria y pagabas el costo en CPU.
¿Qué hace RangeStream y en qué se diferencia de paginar?
RangeStream toma el mismo RangeRequest de siempre pero devuelve los resultados en chunks por un stream, sin que el cliente tenga que orquestar páginas ni recalcular nada. La diferencia con la paginación manual está en tres decisiones de diseño que describe el KEP 5966:
- Fija una única revisión MVCC tras el primer chunk. Así todos los fragmentos son consistentes entre sí —ves una foto coherente del estado— sin mantener una transacción larga abierta que bloquearía las escrituras. Es lo que te da consistencia sin frenar el resto del cluster.
- Chunking adaptativo. El primer chunk arranca con un límite chico de claves; después de cada envío el límite se duplica o se reduce a la mitad según cuánto pesó la respuesta frente a un objetivo derivado de
MaxRequestBytes. En criollo: el servidor va calibrando solo el tamaño de chunk según cómo son de gordos tus values reales. - El conteo total llega gratis en el último chunk. Como el stream ya recorrió todo, el
countviene como subproducto en el fragmento final, sin necesidad de un recorrido O(total_keys) por adelantado. Adiós al recálculo caro de la paginación.
En cuanto al formato: los chunks intermedios llevan solo pares clave-valor; el chunk final incluye el header completo (ClusterId, MemberId, RaftTerm, Revision), los kvs, el count y el flag de "hay más". El cliente reensambla concatenando en orden. Simple de consumir, barato de servir.
¿Cuándo lo voy a poder usar desde Kubernetes?
En Kubernetes v1.37, detrás de un feature gate. Según el anuncio oficial de etcd v3.7 en el blog de Kubernetes, "la feature RangeStream estará disponible para quienes corran la próxima v1.37 de Kubernetes habilitando el feature gate EtcdRangeStream". Es decir: el kube-apiserver tiene que optar explícitamente por hablarle a etcd con el nuevo RPC.
Esto importa por dos razones prácticas:
- Es opt-in y arranca como feature gate. No cambia el comportamiento de tus clusters actuales al actualizar etcd; el apiserver sigue usando el
Rangeunario hasta que vos habilites el gate en 1.37. Podés adoptarlo cuando estés listo, no de prepo. - El beneficio real aparece en el plano de control. El apiserver es el gran emisor de LISTs pesados contra etcd. Que ese camino pase a streaming es lo que mueve la aguja en clusters con mucho objeto, no una app cualquiera que hace un get puntual.
¿Qué más trae etcd v3.7 además de RangeStream?
Bastante, y varias cosas apuntan a la misma dirección —memoria y latencia bajo control—. Del anuncio oficial en etcd.io, lo más relevante para quien opera clusters:
- Optimización de rangos keys-only. Cuando pedís solo las claves (sin values), etcd ahora lee del índice en memoria y evita cargar los values serializados desde bbolt. La excepción es si ordenás por
SortTarget=VALUE, donde sí necesita bbolt. Menos lecturas de backend, menos memoria. - Leases más rápidas y confiables. Incorpora
LeaseRevokepriorizado yFastLeaseKeepAlivepara renovar y expirar leases con menos demora —clave para la salud de watches y elecciones de líder. - Adiós al v2store legacy. etcd ahora bootea enteramente desde el v3store, eliminando una dependencia histórica del viejo almacén v2. Menos superficie, menos deuda.
- Overhaul de protobuf. Reemplazó librerías protobuf desactualizadas por
google.golang.org/protobuf, plenamente soportada. Mantenimiento a largo plazo más sano. - Dependencias core al día. Viene con bbolt v1.5.x y raft v3.7.0, además de soporte de sockets Unix para comunicación local y nuevas métricas de watch para observabilidad.
¿Qué podés hacer con esto hoy?
Depende de dónde estés parado, pero hay pasos concretos. Si operás etcd (con o sin Kubernetes), ya podés bajar la rama v3.7 y probar RangeStream vía etcdctl o gRPC contra un cluster de prueba; la sintaxis exacta está en la doc de la v3.7. Si tu foco es Kubernetes en producción, el trabajo de hoy es prepararte para 1.37.
- No corras la .0 en serio: apuntá al último patch. El 23 de julio de 2026 salió etcd v3.7.1 (junto con v3.6.14 y v3.5.33), que corrige dos vulnerabilidades de seguridad y varios problemas de confiabilidad en servidor, cliente y stack TLS. Para cualquier despliegue nuevo, empezá por el patch más reciente.
- Probá RangeStream en un entorno aislado. Levantá un cluster etcd v3.7 de laboratorio —un cloud server Linux modesto alcanza para experimentar— y medí el comportamiento de memoria de un rango grande con y sin streaming antes de tocar producción.
- Planificá el feature gate para 1.37. Cuando actualices a Kubernetes v1.37, evaluá habilitar
EtcdRangeStreamen elkube-apiserveren un cluster de staging con muchos objetos, que es donde vas a ver la diferencia. Como toda feature gate nueva, entra gradualmente: verificá su nivel de madurez (alpha/beta) en las release notes de tu versión. - Revisá tus consumidores de LIST. Controllers y operators que hacen LISTs sin paginar sobre recursos numerosos son los primeros candidatos a beneficiarse. Es buen momento para auditar quién pide qué contra el apiserver.
Preguntas frecuentes
¿Cuándo salió etcd v3.7.0?
etcd v3.7.0 salió el 8 de julio de 2026, anunciada por SIG etcd. El primer patch, v3.7.1, se publicó el 23 de julio de 2026 con correcciones de seguridad y confiabilidad.
¿Qué es RangeStream en etcd?
Es un RPC de server-streaming que devuelve el resultado de una consulta de rango en chunks en lugar de bufferear toda la respuesta antes de enviarla. Reduce los picos de memoria y hace predecible la latencia de las lecturas grandes.
¿RangeStream funciona automáticamente al actualizar etcd?
No. En etcd está disponible como RPC, pero para que el kube-apiserver lo use hay que habilitar el feature gate EtcdRangeStream, que llega con Kubernetes v1.37. Sin habilitarlo, el apiserver sigue usando el RPC Range unario de siempre.
¿En qué se diferencia de paginar con limit?
Paginar con limit recalcula el conteo total recorriendo todo el índice en cada página (O(total_keys) por página). RangeStream fija una revisión, adapta el tamaño de chunk solo y entrega el conteo total gratis en el último fragmento, sin ese recálculo repetido.
¿Necesito Kubernetes para aprovechar RangeStream?
No. Cualquier aplicación que consuma etcd por gRPC o etcdctl puede usar RangeStream directamente contra un cluster v3.7. Kubernetes es solo el consumidor más visible del beneficio por el volumen de LISTs que hace su plano de control.
¿Con qué versiones de bbolt y raft viene?
etcd v3.7 incorpora bbolt v1.5.x y raft v3.7.0, además de un overhaul completo de protobuf hacia google.golang.org/protobuf.
El panorama para clusters grandes
RangeStream no es un cambio que vayas a notar en un cluster chico: ahí un LIST entra holgado en memoria y listo. Donde cambia el juego es en el plano de control de clusters densos, con miles de objetos por tipo, donde el apiserver era el que sufría los picos de RAM de etcd. Encaja además con la tendencia reciente de Kubernetes de podar y endurecer sus cimientos —en la misma línea que el recorte de componentes legacy que ya vimos en Kubernetes 1.35—. La lectura de fondo: etcd sigue madurando como base de datos de estado pensada para escalar, y v3.7 saca de encima una limitación estructural que arrastraba desde hace años. Si operás Kubernetes serio, vale tenerlo en el radar para cuando llegue la 1.37.