{"schemaVersion":1,"id":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks","url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks","title":"Kafka vs Redpanda: Benchmarks de Event Streaming y Análisis de Migración","description":"Una comparación head-to-head entre Apache Kafka y Redpanda. Raft vs ZooKeeper, C++ vs overhead del JVM, tail latency en p99, schema registry, y un análisis detallado de migrar 2TB/día de event streams.","language":"es","datePublished":"2026-01-22","dateModified":null,"contentFormat":"text/markdown","content":"Infrastructure\n\n# Kafka vs Redpanda: Benchmarks de Event Streaming y Análisis de Migración\n\n2026-01-229 min lectura\n\nLucio Durán\nEngineering Manager & AI Solutions Architect\n\nTambién disponible en: [English](<https://lucioduran.com/blog/kafka-vs-redpanda-event-streaming-benchmarks>)\n\n## La Diferencia Arquitectónica Que Importa\n\nLas diferencias arquitectónicas fundamentales son el punto de partida, ya que todas las características de rendimiento se derivan de ellas.\n\n**[Apache Kafka](<https://kafka.apache.org/>)** es una aplicación JVM. Está escrito en Scala y Java, corre en el JVM con su garbage collector asociado, y hasta hace poco requería ZooKeeper como servicio de coordinación separado. El modo KRaft (el consenso Raft built-in de Kafka) está production-ready desde Kafka 3.5, y ZooKeeper está oficialmente deprecado desde la 3.7.\n\n**[Redpanda](<https://redpanda.com/>)** es una aplicación C++ construida sobre el framework Seastar, el mismo framework de I/O asíncrono que utiliza ScyllaDB. Sin JVM, sin garbage collector, sin ZooKeeper. Usa Raft para consenso nativamente, con cada partición teniendo su propio grupo Raft.\n\nEsto no es solo una diferencia de lenguaje. Es una diferencia fundamental en cómo interactúan con el hardware.\n\n### Thread-Per-Core vs Thread Pool\n\nEl modelo thread-per-core de Seastar significa que cada core de CPU corre un único thread que es dueño de su memoria, sus conexiones de red y su I/O de disco. Sin locks, sin context switches entre threads, sin memoria compartida entre cores.\n\n```\nRedpanda (Seastar/thread-per-core):\n┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐\n│ Core 0 │ │ Core 1 │ │ Core 2 │ │ Core 3 │\n│ Shard 0 │ │ Shard 1 │ │ Shard 2 │ │ Shard 3 │\n│ Mem prop │ │ Mem prop │ │ Mem prop │ │ Mem prop │\n│ I/O prop │ │ I/O prop │ │ I/O prop │ │ I/O prop │\n└──────────┘ └──────────┘ └──────────┘ └──────────┘\n ↕ message passing (sin estado compartido)\n\nKafka (JVM/thread pool):\n┌───────────────────────────────────────────────────┐\n│ JVM Heap (compartido) │\n│ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ │\n│ │Thread 1│ │Thread 2│ │Thread 3│ │Thread N│ │\n│ └────┬───┘ └────┬───┘ └────┬───┘ └────┬───┘ │\n│ └──────────┴──────────┴──────────┘ │\n│ Acceso sincronizado │\n│ Las pausas de GC afectan a TODOS │\n└───────────────────────────────────────────────────┘\n```\n\nLos threads de Kafka comparten memoria del heap y coordinan a través de locks y el modelo de memoria del JVM. Cuando el collector G1 o ZGC arranca, todos los threads pausan (o al menos se ralentizan durante las fases concurrentes). Redpanda simplemente no tiene este problema, no hay GC porque no hay managed heap.\n\n## Los Benchmarks\n\nLas siguientes pruebas se corrieron en hardware idéntico: clusters de 3 nodos, cada nodo con 16 cores (AMD EPYC 7313), 64GB RAM, 2x NVMe SSDs en RAID 0, red de 25Gbps. Esto representa un setup \"serio pero no extravagante\".\n\n### Test de Throughput\n\nConfiguración de producer: mensajes de 1KB, batching habilitado (` linger.ms=5 `, ` batch.size=65536 `), ` acks=all `, 6 particiones, factor de replicación 3.\n\n```bash\n# Benchmark Kafka\nbin/kafka-producer-perf-test.sh \\\n --topic bench-topic \\\n --num-records 10000000 \\\n --record-size 1024 \\\n --throughput -1 \\\n --producer-props \\\n bootstrap.servers=kafka1:9092,kafka2:9092,kafka3:9092 \\\n acks=all \\\n linger.ms=5 \\\n batch.size=65536\n\n# Benchmark Redpanda (la misma herramienta funciona, API compatible)\nbin/kafka-producer-perf-test.sh \\\n --topic bench-topic \\\n --num-records 10000000 \\\n --record-size 1024 \\\n --throughput -1 \\\n --producer-props \\\n bootstrap.servers=redpanda1:9092,redpanda2:9092,redpanda3:9092 \\\n acks=all \\\n linger.ms=5 \\\n batch.size=65536\n```\n\nResultados (10M mensajes, 1KB cada uno):\n\n| Métrica | Kafka 3.7 (KRaft) | Redpanda 24.3 |\n| --- | --- | --- |\n| Throughput (MB/s) | 850 | 920 |\n| Latencia avg | 3.2ms | 1.8ms |\n| Latencia p50 | 2.1ms | 1.4ms |\n| Latencia p99 | 28ms | 4.2ms |\n| Latencia p99.9 | 145ms | 8.1ms |\n\nNotemos el número de p99.9. **145ms vs 8.1ms**. Eso no es un error de redondeo, es el G1GC del JVM haciendo una mixed collection. Y esto fue después de un extenso tuning de flags del JVM:\n\n```bash\n# Tuning de JVM para Kafka (KAFKA_HEAP_OPTS)\n-Xms12g -Xmx12g\n-XX:+UseG1GC\n-XX:MaxGCPauseMillis=20\n-XX:G1HeapRegionSize=16M\n-XX:InitiatingHeapOccupancyPercent=35\n-XX:G1ReservePercent=25\n-XX:+ParallelRefProcEnabled\n-XX:+ExplicitGCInvokesConcurrent\n```\n\nSin ese tuning, el p99.9 de Kafka pasaba los 400ms. El JVM es poderoso, pero lo pagás en la cola.\n\n### Throughput de Consumer\n\nPara consumo, se testeó un grupo de 3 consumers leyendo del mismo topic:\n\n| Métrica | Kafka 3.7 | Redpanda 24.3 |\n| --- | --- | --- |\n| Throughput consumer (MB/s) | 1,100 | 1,250 |\n| Tiempo de rebalanceo (3→4 consumers) | 12s | 3s |\n| Latencia end-to-end (produce→consume) | 8ms avg | 3ms avg |\n\nLa diferencia en tiempo de rebalanceo es significativa en la práctica. Cada rebalanceo significa un período donde las particiones no están asignadas y no se procesan mensajes. El cooperative sticky assignor de Kafka mejoró las cosas, pero la asignación de particiones de Redpanda es directamente más rápida porque no hay coordinación con un servicio de metadata separado.\n\n## La Migración: Un Caso de Estudio\n\nConsideremos un cluster de 5 nodos de Kafka manejando unos 2TB de eventos por día, analytics de usuarios, eventos de órdenes, updates de inventario, todo el paquete. La decisión de probar Redpanda vino de dos cosas: el equipo de on-call pasaba el 30% del tiempo de incidentes en problemas de ZooKeeper o tuning de JVM, y el SLO de latencia p99 se estaba poniendo cada vez más difícil de cumplir.\n\n### Paso 1: Cluster Shadow\n\nPrimero se levantó un cluster Redpanda de 3 nodos y usamos MirrorMaker 2 para replicar todos los topics:\n\n```properties\n# mm2.properties\nclusters = kafka, redpanda\nkafka.bootstrap.servers = kafka1:9092,kafka2:9092,kafka3:9092\nredpanda.bootstrap.servers = rp1:9092,rp2:9092,rp3:9092\n\nkafka->redpanda.enabled = true\nkafka->redpanda.topics = .*\n\nsync.topic.configs.enabled = true\nsync.topic.acls.enabled = false\nreplication.factor = 3\n\n# Crítico: configurar esto para evitar que manee los nombres de topic\nreplication.policy.class = org.apache.kafka.connect.mirror.IdentityReplicationPolicy\n```\n\nEsto funcionó out of the box. MirrorMaker 2 no sabe ni le importa que el target es Redpanda, simplemente habla el protocolo Kafka.\n\n### Paso 2: Validación de Consumers\n\nSe corrieron consumers shadow en el cluster Redpanda y comparamos conteos de mensajes, orden y contenido contra los consumers de Kafka. Esto detectó dos problemas:\n\n1. **Manejo de timestamps**: El ` LogAppendTime ` de Redpanda tenía diferencias de precisión en microsegundos respecto a Kafka. La lógica de deduplicación que usaba comparaciones de timestamp se rompió.\n2. **Marcadores de transacción**: Algunos producers estaban usando transacciones (` enable.idempotence=true ` + ` transactional.id `). Los marcadores de commit de transacción aparecían distinto en la representación interna de Redpanda. Los consumers usando aislamiento ` read_committed ` funcionaban bien, pero una herramienta custom de tracking de offsets que parseaba los datos crudos de la partición se rompió.\n\n### Paso 3: El Switchover\n\nSe realizó una migración rolling, moviendo un consumer group a la vez:\n\n```python\n# Script de migración simplificado\nimport confluent_kafka\n\ndef migrate_consumer_group(group_id, kafka_brokers, redpanda_brokers, topics):\n # 1. Obtener offsets committed actuales de Kafka\n admin = confluent_kafka.admin.AdminClient({\n 'bootstrap.servers': kafka_brokers\n })\n\n committed = admin.list_consumer_group_offsets([\n confluent_kafka.admin.ConsumerGroupTopicPartitions(group_id)\n ])\n\n # 2. Mapear offsets a Redpanda (MM2 preserva offsets con IdentityReplicationPolicy)\n rp_admin = confluent_kafka.admin.AdminClient({\n 'bootstrap.servers': redpanda_brokers\n })\n\n # 3. Pre-commitear offsets a Redpanda antes de arrancar consumers\n offsets = []\n for tp, offset_meta in committed[group_id].result().topic_partitions:\n offsets.append(confluent_kafka.TopicPartition(\n tp.topic, tp.partition, offset_meta.offset\n ))\n\n rp_admin.alter_consumer_group_offsets([\n confluent_kafka.admin.ConsumerGroupTopicPartitions(group_id, offsets)\n ])\n\n print(f\"Migrado {group_id}: {len(offsets)} offsets de partición committeados a Redpanda\")\n```\n\n### Paso 4: Switchover de Producers\n\nSe cambiaron los bootstrap servers de los producers durante una ventana de bajo tráfico:\n\n```yaml\n# Antes\nkafka:\n bootstrap-servers: kafka1:9092,kafka2:9092,kafka3:9092\n\n# Después\nkafka: # mantuvimos el nombre del config key para minimizar cambios de código\n bootstrap-servers: rp1:9092,rp2:9092,rp3:9092\n```\n\nFuncionó sin problemas. Sin cambios de código necesarios. La librería cliente de Kafka se conectó a Redpanda y empezó a producir. Producers idempotentes, producers transaccionales, producers con particiones, todos.\n\n## Schema Registry: La Historia de Compatibilidad\n\nRedpanda incluye su propio schema registry que es API-compatible con el de Confluent. La migración cubrió ~200 schemas Avro:\n\n```bash\n# Exportar schemas del Confluent Schema Registry\nfor subject in $(curl -s http://kafka-sr:8081/subjects | jq -r '.[]'); do\n schema=$(curl -s \"http://kafka-sr:8081/subjects/${subject}/versions/latest\")\n echo \"$schema\" > \"schemas/${subject}.json\"\ndone\n\n# Importar en el schema registry de Redpanda\nfor file in schemas/*.json; do\n subject=$(basename \"$file\" .json)\n schema=$(cat \"$file\" | jq -c '{schema: .schema, schemaType: .schemaType}')\n curl -X POST \"http://rp1:8081/subjects/${subject}/versions\" \\\n -H \"Content-Type: application/vnd.schemaregistry.v1+json\" \\\n -d \"$schema\"\ndone\n```\n\nLos modos de compatibilidad (BACKWARD, FORWARD, FULL) funcionaron todos. El único gotcha fue que el schema registry de Redpanda guarda datos internamente en un topic ` _schemas `, mientras que Confluent usa ` _schemas ` también, pero el formato de los mensajes difiere. No es posible simplemente replicar el topic, teners que re-registrar.\n\n## Diferencias Operacionales Que Importan Día a Día\n\n### Monitoreo\n\nRedpanda expone métricas Prometheus en el puerto 9644 por defecto. Sin JMX, sin exporters JMX-to-Prometheus, sin andar peleando con autenticación de JMX remoto:\n\n```yaml\n# prometheus.yml\nscrape_configs:\n - job_name: redpanda\n static_configs:\n - targets:\n - rp1:9644\n - rp2:9644\n - rp3:9644\n metrics_path: /public_metrics\n```\n\nCon Kafka, obtener buenas métricas requiere un sidecar de JMX exporter, que en sí consume recurse es y agrega complejidad. Ese setup no se extraña.\n\n### Uso de Disco\n\nRedpanda usa alrededor de 20-30% menos de disco para los mismos datos, principalmente porque no tiene el overhead de archivos de índice y timeindex que Kafka crea por segmento. Redpanda mantiene su índice en memoria usando su propio motor de storage.\n\n### Memoria\n\nAcá resulta interesante. Kafka necesita tuning del heap del JVM, muy poco y las pausas de GC te matan, demasiado y las pausas de GC también te matan (pero de otra forma). Con Redpanda, le decís cuánta memoria usar y la maneja solo:\n\n```bash\nrpk redpanda config set --set redpanda.memory=48G\nrpk redpanda config set --set redpanda.reserve_memory=4G\n```\n\nSin tuning de heap, sin tuning de GC, sin flags ` -XX: `. El allocator de Seastar maneja todo.\n\n## Donde Kafka todavía gana\n\nKafka sigue siendo una opción sólida, y existen razones sustanciales para continuar utilizándolo:\n\n1. **Kafka Streams y ksqlDB**: El ecosistema de procesamiento de streams no tiene rival. Redpanda no tiene equivalente, lo combinarías con Flink o tus propios consumers.\n2. **Kafka Connect**: Si bien Redpanda puede correr Kafka Connect (es solo el protocolo Kafka), el ecosistema de conectores testeados en producción es más profundo con Kafka.\n3. **Madurez de KRaft**: El modo KRaft elimina ZooKeeper, y está estable desde la 3.5. La brecha operacional se está achicando.\n4. **Comunidad y contratación**: Encontrar ingenieros de Kafka es más fácil. La experiencia en Redpanda es más rara.\n5. **Tiered storage**: El tiered storage de Kafka (escribir segmentos fríos a S3) está más maduro que la implementación de Redpanda.\n\n## Los Números Después de 8 Meses\n\nDespués de migrar a Redpanda:\n\n- **Latencia p99 de producción**: Bajó de 28ms a 4ms (consistente, no solo al principio)\n- **Incidentes on-call relacionados a streaming**: Bajaron 70%\n- **Costo de infraestructura**: Bajó 40% (3 nodos Redpanda reemplazaron 5 Kafka + 3 ZooKeeper)\n- **Tiempo dedicado a tuning de JVM**: Cero, porque no hay JVM\n\nLa migración valió la pena para este caso de uso. Sin embargo, no es universalmente recomendable. Si un cluster de Kafka está estable, la latencia es aceptable, y se usa Kafka Streams a fondo, quedarse con Kafka puede ser la mejor opción. La migración tiene costos reales y riesgos reales.\n\nPara proyectos greenfield, sin embargo, Redpanda merece fuerte consideración. La simplicidad operacional sola justifica la elección.\n\n## Preguntas frecuentes\n\n### ¿Redpanda es un reemplazo directo de Kafka?\n\nA nivel de API, mayormente sí. Redpanda implementa el protocolo wire de Kafka, así que la mayoría de los clientes, conectores y herramientas de Kafka funcionan sin cambios. Sin embargo, comportamientos internos como timing de replicación, compactación y semántica de transacciones tienen diferencias sutiles.\n\n### ¿Redpanda realmente no necesita JVM?\n\nCorrecto. Redpanda está escrito en C++ usando el framework Seastar, lo que significa que no hay JVM, no hay pausas de GC, y no hay tuning de JVM. Esta es su mayor ventaja arquitectónica para workloads sensibles a la latencia.\n\n### ¿Debería migrar de Kafka a Redpanda?\n\nDepende. Si tus puntos de dolor son la complejidad operacional (ZooKeeper, tuning de JVM, pausas de GC) y la tail latency, Redpanda es tentador. Si se está profundamente metido en el ecosistema de Kafka Streams o se necesita features específicas de KRaft, quedarte en Kafka puede tener más sentido.\n\n### ¿Cómo maneja Redpanda el schema registry?\n\nRedpanda incluye un schema registry que es compatible con la API del Confluent Schema Registry. Soporta Avro, Protobuf y JSON Schema con los mismos endpoints REST API.\n\n## Tips\n\n1. **Tip:** Al comparar Kafka vs Redpanda, medir siempre la latencia de *cola* (p99/p99.9), no solo el throughput. Las pausas del GC del JVM de Kafka crean picos de latencia que los promedios ocultan completamente. Utilizar ` kafka-producer-perf-test.sh --print-metrics ` para obtener datos de percentiles.\n2. **Tip:** El CLI ` rpk ` de Redpanda es un reemplazo directo para la mayoría de los comandos ` kafka-topics.sh `. Iniciar con ` rpk topic list ` y ` rpk cluster info `, son más rápidos y la salida es legible.\n3. **Tip:** Si se está migrando de Kafka a Redpanda, utilizar MirrorMaker 2 con ` sync.topic.configs.enabled=true `. La compatibilidad de API Kafka de Redpanda es lo suficientemente buena como para que MM2 funcione sin modificaciones, pero conviene probar los producers ` exactly_once `, la semántica de transacciones tiene diferencias sutiles.\n4. **Tip:** El flag ` --smp ` de Redpanda controla cuántos cores de CPU utiliza. En una máquina de 16 cores, iniciar con ` --smp 14 ` y dejar 2 cores para el sistema operativo y el monitoreo con ` rpk `. Si se sobresuscriben CPUs, la latencia p99 se degrada significativamente.\n\n- kafka\n- redpanda\n- event-streaming\n- benchmarks\n- infraestructura\n- raft\n- zookeeper\n- p99-latency\n\n[Volver al Blog](<https://lucioduran.com/es/blog>)","headings":[{"level":1,"text":"Kafka vs Redpanda: Benchmarks de Event Streaming y Análisis de Migración","url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#title"},{"level":2,"text":"La Diferencia Arquitectónica Que Importa","url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#la-diferencia-arquitectnica-que-importa"},{"level":3,"text":"Thread-Per-Core vs Thread Pool","url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#thread-per-core-vs-thread-pool"},{"level":2,"text":"Los Benchmarks","url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#los-benchmarks"},{"level":3,"text":"Test de Throughput","url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#test-de-throughput"},{"level":3,"text":"Throughput de Consumer","url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#throughput-de-consumer"},{"level":2,"text":"La Migración: Un Caso de Estudio","url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#la-migracin-un-caso-de-estudio"},{"level":3,"text":"Paso 1: Cluster Shadow","url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#paso-1-cluster-shadow"},{"level":3,"text":"Paso 2: Validación de Consumers","url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#paso-2-validacin-de-consumers"},{"level":3,"text":"Paso 3: El Switchover","url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#paso-3-el-switchover"},{"level":3,"text":"Paso 4: Switchover de Producers","url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#paso-4-switchover-de-producers"},{"level":2,"text":"Schema Registry: La Historia de Compatibilidad","url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#schema-registry-la-historia-de-compatibilidad"},{"level":2,"text":"Diferencias Operacionales Que Importan Día a Día","url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#diferencias-operacionales-que-importan-da-a-da"},{"level":3,"text":"Monitoreo","url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#monitoreo"},{"level":3,"text":"Uso de Disco","url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#uso-de-disco"},{"level":3,"text":"Memoria","url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#memoria"},{"level":2,"text":"Donde Kafka todavía gana","url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#donde-kafka-todava-gana"},{"level":2,"text":"Los Números Después de 8 Meses","url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#los-nmeros-despus-de-8-meses"},{"level":2,"text":"Preguntas frecuentes","url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#questions"},{"level":3,"text":"¿Redpanda es un reemplazo directo de Kafka?","url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#question-1"},{"level":3,"text":"¿Redpanda realmente no necesita JVM?","url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#question-2"},{"level":3,"text":"¿Debería migrar de Kafka a Redpanda?","url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#question-3"},{"level":3,"text":"¿Cómo maneja Redpanda el schema registry?","url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#question-4"},{"level":2,"text":"Tips","url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#article-tips"}],"sections":[{"heading":"Kafka vs Redpanda: Benchmarks de Event Streaming y Análisis de Migración","level":1,"url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks","content":"Infrastructure"},{"heading":"Kafka vs Redpanda: Benchmarks de Event Streaming y Análisis de Migración","level":1,"url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#title","content":"2026-01-229 min lectura\n\nLucio Durán\nEngineering Manager & AI Solutions Architect\n\nTambién disponible en: [English](<https://lucioduran.com/blog/kafka-vs-redpanda-event-streaming-benchmarks>)"},{"heading":"La Diferencia Arquitectónica Que Importa","level":2,"url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#la-diferencia-arquitectnica-que-importa","content":"Las diferencias arquitectónicas fundamentales son el punto de partida, ya que todas las características de rendimiento se derivan de ellas.\n\n**[Apache Kafka](<https://kafka.apache.org/>)** es una aplicación JVM. Está escrito en Scala y Java, corre en el JVM con su garbage collector asociado, y hasta hace poco requería ZooKeeper como servicio de coordinación separado. El modo KRaft (el consenso Raft built-in de Kafka) está production-ready desde Kafka 3.5, y ZooKeeper está oficialmente deprecado desde la 3.7.\n\n**[Redpanda](<https://redpanda.com/>)** es una aplicación C++ construida sobre el framework Seastar, el mismo framework de I/O asíncrono que utiliza ScyllaDB. Sin JVM, sin garbage collector, sin ZooKeeper. Usa Raft para consenso nativamente, con cada partición teniendo su propio grupo Raft.\n\nEsto no es solo una diferencia de lenguaje. Es una diferencia fundamental en cómo interactúan con el hardware."},{"heading":"Thread-Per-Core vs Thread Pool","level":3,"url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#thread-per-core-vs-thread-pool","content":"El modelo thread-per-core de Seastar significa que cada core de CPU corre un único thread que es dueño de su memoria, sus conexiones de red y su I/O de disco. Sin locks, sin context switches entre threads, sin memoria compartida entre cores.\n\n```\nRedpanda (Seastar/thread-per-core):\n┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐\n│ Core 0 │ │ Core 1 │ │ Core 2 │ │ Core 3 │\n│ Shard 0 │ │ Shard 1 │ │ Shard 2 │ │ Shard 3 │\n│ Mem prop │ │ Mem prop │ │ Mem prop │ │ Mem prop │\n│ I/O prop │ │ I/O prop │ │ I/O prop │ │ I/O prop │\n└──────────┘ └──────────┘ └──────────┘ └──────────┘\n ↕ message passing (sin estado compartido)\n\nKafka (JVM/thread pool):\n┌───────────────────────────────────────────────────┐\n│ JVM Heap (compartido) │\n│ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ │\n│ │Thread 1│ │Thread 2│ │Thread 3│ │Thread N│ │\n│ └────┬───┘ └────┬───┘ └────┬───┘ └────┬───┘ │\n│ └──────────┴──────────┴──────────┘ │\n│ Acceso sincronizado │\n│ Las pausas de GC afectan a TODOS │\n└───────────────────────────────────────────────────┘\n```\n\nLos threads de Kafka comparten memoria del heap y coordinan a través de locks y el modelo de memoria del JVM. Cuando el collector G1 o ZGC arranca, todos los threads pausan (o al menos se ralentizan durante las fases concurrentes). Redpanda simplemente no tiene este problema, no hay GC porque no hay managed heap."},{"heading":"Los Benchmarks","level":2,"url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#los-benchmarks","content":"Las siguientes pruebas se corrieron en hardware idéntico: clusters de 3 nodos, cada nodo con 16 cores (AMD EPYC 7313), 64GB RAM, 2x NVMe SSDs en RAID 0, red de 25Gbps. Esto representa un setup \"serio pero no extravagante\"."},{"heading":"Test de Throughput","level":3,"url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#test-de-throughput","content":"Configuración de producer: mensajes de 1KB, batching habilitado (` linger.ms=5 `, ` batch.size=65536 `), ` acks=all `, 6 particiones, factor de replicación 3.\n\n```bash\n# Benchmark Kafka\nbin/kafka-producer-perf-test.sh \\\n --topic bench-topic \\\n --num-records 10000000 \\\n --record-size 1024 \\\n --throughput -1 \\\n --producer-props \\\n bootstrap.servers=kafka1:9092,kafka2:9092,kafka3:9092 \\\n acks=all \\\n linger.ms=5 \\\n batch.size=65536\n\n# Benchmark Redpanda (la misma herramienta funciona, API compatible)\nbin/kafka-producer-perf-test.sh \\\n --topic bench-topic \\\n --num-records 10000000 \\\n --record-size 1024 \\\n --throughput -1 \\\n --producer-props \\\n bootstrap.servers=redpanda1:9092,redpanda2:9092,redpanda3:9092 \\\n acks=all \\\n linger.ms=5 \\\n batch.size=65536\n```\n\nResultados (10M mensajes, 1KB cada uno):\n\n| Métrica | Kafka 3.7 (KRaft) | Redpanda 24.3 |\n| --- | --- | --- |\n| Throughput (MB/s) | 850 | 920 |\n| Latencia avg | 3.2ms | 1.8ms |\n| Latencia p50 | 2.1ms | 1.4ms |\n| Latencia p99 | 28ms | 4.2ms |\n| Latencia p99.9 | 145ms | 8.1ms |\n\nNotemos el número de p99.9. **145ms vs 8.1ms**. Eso no es un error de redondeo, es el G1GC del JVM haciendo una mixed collection. Y esto fue después de un extenso tuning de flags del JVM:\n\n```bash\n# Tuning de JVM para Kafka (KAFKA_HEAP_OPTS)\n-Xms12g -Xmx12g\n-XX:+UseG1GC\n-XX:MaxGCPauseMillis=20\n-XX:G1HeapRegionSize=16M\n-XX:InitiatingHeapOccupancyPercent=35\n-XX:G1ReservePercent=25\n-XX:+ParallelRefProcEnabled\n-XX:+ExplicitGCInvokesConcurrent\n```\n\nSin ese tuning, el p99.9 de Kafka pasaba los 400ms. El JVM es poderoso, pero lo pagás en la cola."},{"heading":"Throughput de Consumer","level":3,"url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#throughput-de-consumer","content":"Para consumo, se testeó un grupo de 3 consumers leyendo del mismo topic:\n\n| Métrica | Kafka 3.7 | Redpanda 24.3 |\n| --- | --- | --- |\n| Throughput consumer (MB/s) | 1,100 | 1,250 |\n| Tiempo de rebalanceo (3→4 consumers) | 12s | 3s |\n| Latencia end-to-end (produce→consume) | 8ms avg | 3ms avg |\n\nLa diferencia en tiempo de rebalanceo es significativa en la práctica. Cada rebalanceo significa un período donde las particiones no están asignadas y no se procesan mensajes. El cooperative sticky assignor de Kafka mejoró las cosas, pero la asignación de particiones de Redpanda es directamente más rápida porque no hay coordinación con un servicio de metadata separado."},{"heading":"La Migración: Un Caso de Estudio","level":2,"url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#la-migracin-un-caso-de-estudio","content":"Consideremos un cluster de 5 nodos de Kafka manejando unos 2TB de eventos por día, analytics de usuarios, eventos de órdenes, updates de inventario, todo el paquete. La decisión de probar Redpanda vino de dos cosas: el equipo de on-call pasaba el 30% del tiempo de incidentes en problemas de ZooKeeper o tuning de JVM, y el SLO de latencia p99 se estaba poniendo cada vez más difícil de cumplir."},{"heading":"Paso 1: Cluster Shadow","level":3,"url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#paso-1-cluster-shadow","content":"Primero se levantó un cluster Redpanda de 3 nodos y usamos MirrorMaker 2 para replicar todos los topics:\n\n```properties\n# mm2.properties\nclusters = kafka, redpanda\nkafka.bootstrap.servers = kafka1:9092,kafka2:9092,kafka3:9092\nredpanda.bootstrap.servers = rp1:9092,rp2:9092,rp3:9092\n\nkafka->redpanda.enabled = true\nkafka->redpanda.topics = .*\n\nsync.topic.configs.enabled = true\nsync.topic.acls.enabled = false\nreplication.factor = 3\n\n# Crítico: configurar esto para evitar que manee los nombres de topic\nreplication.policy.class = org.apache.kafka.connect.mirror.IdentityReplicationPolicy\n```\n\nEsto funcionó out of the box. MirrorMaker 2 no sabe ni le importa que el target es Redpanda, simplemente habla el protocolo Kafka."},{"heading":"Paso 2: Validación de Consumers","level":3,"url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#paso-2-validacin-de-consumers","content":"Se corrieron consumers shadow en el cluster Redpanda y comparamos conteos de mensajes, orden y contenido contra los consumers de Kafka. Esto detectó dos problemas:\n\n1. **Manejo de timestamps**: El ` LogAppendTime ` de Redpanda tenía diferencias de precisión en microsegundos respecto a Kafka. La lógica de deduplicación que usaba comparaciones de timestamp se rompió.\n2. **Marcadores de transacción**: Algunos producers estaban usando transacciones (` enable.idempotence=true ` + ` transactional.id `). Los marcadores de commit de transacción aparecían distinto en la representación interna de Redpanda. Los consumers usando aislamiento ` read_committed ` funcionaban bien, pero una herramienta custom de tracking de offsets que parseaba los datos crudos de la partición se rompió."},{"heading":"Paso 3: El Switchover","level":3,"url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#paso-3-el-switchover","content":"Se realizó una migración rolling, moviendo un consumer group a la vez:\n\n```python\n# Script de migración simplificado\nimport confluent_kafka\n\ndef migrate_consumer_group(group_id, kafka_brokers, redpanda_brokers, topics):\n # 1. Obtener offsets committed actuales de Kafka\n admin = confluent_kafka.admin.AdminClient({\n 'bootstrap.servers': kafka_brokers\n })\n\n committed = admin.list_consumer_group_offsets([\n confluent_kafka.admin.ConsumerGroupTopicPartitions(group_id)\n ])\n\n # 2. Mapear offsets a Redpanda (MM2 preserva offsets con IdentityReplicationPolicy)\n rp_admin = confluent_kafka.admin.AdminClient({\n 'bootstrap.servers': redpanda_brokers\n })\n\n # 3. Pre-commitear offsets a Redpanda antes de arrancar consumers\n offsets = []\n for tp, offset_meta in committed[group_id].result().topic_partitions:\n offsets.append(confluent_kafka.TopicPartition(\n tp.topic, tp.partition, offset_meta.offset\n ))\n\n rp_admin.alter_consumer_group_offsets([\n confluent_kafka.admin.ConsumerGroupTopicPartitions(group_id, offsets)\n ])\n\n print(f\"Migrado {group_id}: {len(offsets)} offsets de partición committeados a Redpanda\")\n```"},{"heading":"Paso 4: Switchover de Producers","level":3,"url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#paso-4-switchover-de-producers","content":"Se cambiaron los bootstrap servers de los producers durante una ventana de bajo tráfico:\n\n```yaml\n# Antes\nkafka:\n bootstrap-servers: kafka1:9092,kafka2:9092,kafka3:9092\n\n# Después\nkafka: # mantuvimos el nombre del config key para minimizar cambios de código\n bootstrap-servers: rp1:9092,rp2:9092,rp3:9092\n```\n\nFuncionó sin problemas. Sin cambios de código necesarios. La librería cliente de Kafka se conectó a Redpanda y empezó a producir. Producers idempotentes, producers transaccionales, producers con particiones, todos."},{"heading":"Schema Registry: La Historia de Compatibilidad","level":2,"url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#schema-registry-la-historia-de-compatibilidad","content":"Redpanda incluye su propio schema registry que es API-compatible con el de Confluent. La migración cubrió ~200 schemas Avro:\n\n```bash\n# Exportar schemas del Confluent Schema Registry\nfor subject in $(curl -s http://kafka-sr:8081/subjects | jq -r '.[]'); do\n schema=$(curl -s \"http://kafka-sr:8081/subjects/${subject}/versions/latest\")\n echo \"$schema\" > \"schemas/${subject}.json\"\ndone\n\n# Importar en el schema registry de Redpanda\nfor file in schemas/*.json; do\n subject=$(basename \"$file\" .json)\n schema=$(cat \"$file\" | jq -c '{schema: .schema, schemaType: .schemaType}')\n curl -X POST \"http://rp1:8081/subjects/${subject}/versions\" \\\n -H \"Content-Type: application/vnd.schemaregistry.v1+json\" \\\n -d \"$schema\"\ndone\n```\n\nLos modos de compatibilidad (BACKWARD, FORWARD, FULL) funcionaron todos. El único gotcha fue que el schema registry de Redpanda guarda datos internamente en un topic ` _schemas `, mientras que Confluent usa ` _schemas ` también, pero el formato de los mensajes difiere. No es posible simplemente replicar el topic, teners que re-registrar."},{"heading":"Diferencias Operacionales Que Importan Día a Día","level":2,"url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#diferencias-operacionales-que-importan-da-a-da","content":""},{"heading":"Monitoreo","level":3,"url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#monitoreo","content":"Redpanda expone métricas Prometheus en el puerto 9644 por defecto. Sin JMX, sin exporters JMX-to-Prometheus, sin andar peleando con autenticación de JMX remoto:\n\n```yaml\n# prometheus.yml\nscrape_configs:\n - job_name: redpanda\n static_configs:\n - targets:\n - rp1:9644\n - rp2:9644\n - rp3:9644\n metrics_path: /public_metrics\n```\n\nCon Kafka, obtener buenas métricas requiere un sidecar de JMX exporter, que en sí consume recurse es y agrega complejidad. Ese setup no se extraña."},{"heading":"Uso de Disco","level":3,"url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#uso-de-disco","content":"Redpanda usa alrededor de 20-30% menos de disco para los mismos datos, principalmente porque no tiene el overhead de archivos de índice y timeindex que Kafka crea por segmento. Redpanda mantiene su índice en memoria usando su propio motor de storage."},{"heading":"Memoria","level":3,"url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#memoria","content":"Acá resulta interesante. Kafka necesita tuning del heap del JVM, muy poco y las pausas de GC te matan, demasiado y las pausas de GC también te matan (pero de otra forma). Con Redpanda, le decís cuánta memoria usar y la maneja solo:\n\n```bash\nrpk redpanda config set --set redpanda.memory=48G\nrpk redpanda config set --set redpanda.reserve_memory=4G\n```\n\nSin tuning de heap, sin tuning de GC, sin flags ` -XX: `. El allocator de Seastar maneja todo."},{"heading":"Donde Kafka todavía gana","level":2,"url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#donde-kafka-todava-gana","content":"Kafka sigue siendo una opción sólida, y existen razones sustanciales para continuar utilizándolo:\n\n1. **Kafka Streams y ksqlDB**: El ecosistema de procesamiento de streams no tiene rival. Redpanda no tiene equivalente, lo combinarías con Flink o tus propios consumers.\n2. **Kafka Connect**: Si bien Redpanda puede correr Kafka Connect (es solo el protocolo Kafka), el ecosistema de conectores testeados en producción es más profundo con Kafka.\n3. **Madurez de KRaft**: El modo KRaft elimina ZooKeeper, y está estable desde la 3.5. La brecha operacional se está achicando.\n4. **Comunidad y contratación**: Encontrar ingenieros de Kafka es más fácil. La experiencia en Redpanda es más rara.\n5. **Tiered storage**: El tiered storage de Kafka (escribir segmentos fríos a S3) está más maduro que la implementación de Redpanda."},{"heading":"Los Números Después de 8 Meses","level":2,"url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#los-nmeros-despus-de-8-meses","content":"Después de migrar a Redpanda:\n\n- **Latencia p99 de producción**: Bajó de 28ms a 4ms (consistente, no solo al principio)\n- **Incidentes on-call relacionados a streaming**: Bajaron 70%\n- **Costo de infraestructura**: Bajó 40% (3 nodos Redpanda reemplazaron 5 Kafka + 3 ZooKeeper)\n- **Tiempo dedicado a tuning de JVM**: Cero, porque no hay JVM\n\nLa migración valió la pena para este caso de uso. Sin embargo, no es universalmente recomendable. Si un cluster de Kafka está estable, la latencia es aceptable, y se usa Kafka Streams a fondo, quedarse con Kafka puede ser la mejor opción. La migración tiene costos reales y riesgos reales.\n\nPara proyectos greenfield, sin embargo, Redpanda merece fuerte consideración. La simplicidad operacional sola justifica la elección."},{"heading":"Preguntas frecuentes","level":2,"url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#questions","content":""},{"heading":"¿Redpanda es un reemplazo directo de Kafka?","level":3,"url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#question-1","content":"A nivel de API, mayormente sí. Redpanda implementa el protocolo wire de Kafka, así que la mayoría de los clientes, conectores y herramientas de Kafka funcionan sin cambios. Sin embargo, comportamientos internos como timing de replicación, compactación y semántica de transacciones tienen diferencias sutiles."},{"heading":"¿Redpanda realmente no necesita JVM?","level":3,"url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#question-2","content":"Correcto. Redpanda está escrito en C++ usando el framework Seastar, lo que significa que no hay JVM, no hay pausas de GC, y no hay tuning de JVM. Esta es su mayor ventaja arquitectónica para workloads sensibles a la latencia."},{"heading":"¿Debería migrar de Kafka a Redpanda?","level":3,"url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#question-3","content":"Depende. Si tus puntos de dolor son la complejidad operacional (ZooKeeper, tuning de JVM, pausas de GC) y la tail latency, Redpanda es tentador. Si se está profundamente metido en el ecosistema de Kafka Streams o se necesita features específicas de KRaft, quedarte en Kafka puede tener más sentido."},{"heading":"¿Cómo maneja Redpanda el schema registry?","level":3,"url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#question-4","content":"Redpanda incluye un schema registry que es compatible con la API del Confluent Schema Registry. Soporta Avro, Protobuf y JSON Schema con los mismos endpoints REST API."},{"heading":"Tips","level":2,"url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#article-tips","content":"1. **Tip:** Al comparar Kafka vs Redpanda, medir siempre la latencia de *cola* (p99/p99.9), no solo el throughput. Las pausas del GC del JVM de Kafka crean picos de latencia que los promedios ocultan completamente. Utilizar ` kafka-producer-perf-test.sh --print-metrics ` para obtener datos de percentiles.\n2. **Tip:** El CLI ` rpk ` de Redpanda es un reemplazo directo para la mayoría de los comandos ` kafka-topics.sh `. Iniciar con ` rpk topic list ` y ` rpk cluster info `, son más rápidos y la salida es legible.\n3. **Tip:** Si se está migrando de Kafka a Redpanda, utilizar MirrorMaker 2 con ` sync.topic.configs.enabled=true `. La compatibilidad de API Kafka de Redpanda es lo suficientemente buena como para que MM2 funcione sin modificaciones, pero conviene probar los producers ` exactly_once `, la semántica de transacciones tiene diferencias sutiles.\n4. **Tip:** El flag ` --smp ` de Redpanda controla cuántos cores de CPU utiliza. En una máquina de 16 cores, iniciar con ` --smp 14 ` y dejar 2 cores para el sistema operativo y el monitoreo con ` rpk `. Si se sobresuscriben CPUs, la latencia p99 se degrada significativamente.\n\n- kafka\n- redpanda\n- event-streaming\n- benchmarks\n- infraestructura\n- raft\n- zookeeper\n- p99-latency\n\n[Volver al Blog](<https://lucioduran.com/es/blog>)"}],"links":[{"text":"English","url":"https://lucioduran.com/blog/kafka-vs-redpanda-event-streaming-benchmarks"},{"text":"Apache Kafka","url":"https://kafka.apache.org/"},{"text":"Redpanda","url":"https://redpanda.com/"},{"text":"Volver al Blog","url":"https://lucioduran.com/es/blog"}],"structuredData":[{"@context":"https://schema.org","@graph":[{"@type":"BlogPosting","@id":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks#article","mainEntityOfPage":{"@type":"WebPage","@id":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks"},"headline":"Kafka vs Redpanda: Benchmarks de Event Streaming y Análisis de Migración","description":"Una comparación head-to-head entre Apache Kafka y Redpanda. Raft vs ZooKeeper, C++ vs overhead del JVM, tail latency en p99, schema registry, y un análisis detallado de migrar 2TB/día de event streams.","datePublished":"2026-01-22","author":{"@type":"Person","@id":"https://lucioduran.com/#person","name":"Lucio Durán","url":"https://lucioduran.com"},"publisher":{"@type":"Person","@id":"https://lucioduran.com/#person","name":"Lucio Durán","url":"https://lucioduran.com"},"image":"https://statics.lucioduran.com/images/lucioduran-social-card.jpg","url":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks","inLanguage":"es","isPartOf":{"@id":"https://lucioduran.com/blog#blog"},"articleSection":"Infrastructure","keywords":"kafka, redpanda, event-streaming, benchmarks, infraestructura, raft, zookeeper, p99-latency","wordCount":1701,"timeRequired":"PT9M","workTranslation":[{"@type":"BlogPosting","inLanguage":"en","url":"https://lucioduran.com/blog/kafka-vs-redpanda-event-streaming-benchmarks"}]},{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Inicio","item":"https://lucioduran.com/"},{"@type":"ListItem","position":2,"name":"Blog","item":"https://lucioduran.com/es/blog"},{"@type":"ListItem","position":3,"name":"Kafka vs Redpanda: Benchmarks de Event Streaming y Análisis de Migración","item":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks"}]},{"@type":"FAQPage","mainEntity":[{"@type":"Question","name":"¿Redpanda es un reemplazo directo de Kafka?","acceptedAnswer":{"@type":"Answer","text":"A nivel de API, mayormente sí. Redpanda implementa el protocolo wire de Kafka, así que la mayoría de los clientes, conectores y herramientas de Kafka funcionan sin cambios. Sin embargo, comportamientos internos como timing de replicación, compactación y semántica de transacciones tienen diferencias sutiles."}},{"@type":"Question","name":"¿Redpanda realmente no necesita JVM?","acceptedAnswer":{"@type":"Answer","text":"Correcto. Redpanda está escrito en C++ usando el framework Seastar, lo que significa que no hay JVM, no hay pausas de GC, y no hay tuning de JVM. Esta es su mayor ventaja arquitectónica para workloads sensibles a la latencia."}},{"@type":"Question","name":"¿Debería migrar de Kafka a Redpanda?","acceptedAnswer":{"@type":"Answer","text":"Depende. Si tus puntos de dolor son la complejidad operacional (ZooKeeper, tuning de JVM, pausas de GC) y la tail latency, Redpanda es tentador. Si se está profundamente metido en el ecosistema de Kafka Streams o se necesita features específicas de KRaft, quedarte en Kafka puede tener más sentido."}},{"@type":"Question","name":"¿Cómo maneja Redpanda el schema registry?","acceptedAnswer":{"@type":"Answer","text":"Redpanda incluye un schema registry que es compatible con la API del Confluent Schema Registry. Soporta Avro, Protobuf y JSON Schema con los mismos endpoints REST API."}}]}]}],"contentHash":"5a0413d7dff95a37df61c598f5667b8ff3f6a55b986438cdbf7656466193acb9","provenance":{"method":"Deterministic serialization of the server-rendered main element","source":"https://lucioduran.com/es/blog/kafka-vs-redpanda-event-streaming-benchmarks","hashAlgorithm":"sha256","hashScope":"JSON document fields before contentHash and provenance","sourceHTMLBytes":77979,"contentBytes":16340}}
