<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Junior Carrillo]]></title><description><![CDATA[Disfruta del mejor contenido enfocado en arquitectura de software, estrategias Fintech y Open Banking desde mi trinchera. Comparto mi experiencia escalando sistemas críticos en LATAM y optimizando el futuro de los pagos y usando IA en todo el proceso.]]></description><link>https://blog.carrillo.app</link><image><url>https://substackcdn.com/image/fetch/$s_!F3EK!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2ce2670-78fa-4235-9710-6b23923068fa_815x815.jpeg</url><title>Junior Carrillo</title><link>https://blog.carrillo.app</link></image><generator>Substack</generator><lastBuildDate>Mon, 26 Oct 2026 02:30:06 GMT</lastBuildDate><atom:link href="https://blog.carrillo.app/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[José Carrillo]]></copyright><language><![CDATA[es]]></language><webMaster><![CDATA[carrilloapps@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[carrilloapps@substack.com]]></itunes:email><itunes:name><![CDATA[José Carrillo]]></itunes:name></itunes:owner><itunes:author><![CDATA[José Carrillo]]></itunes:author><googleplay:owner><![CDATA[carrilloapps@substack.com]]></googleplay:owner><googleplay:email><![CDATA[carrilloapps@substack.com]]></googleplay:email><googleplay:author><![CDATA[José Carrillo]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Buenas prácticas de ClickHouse: guía de producción]]></title><description><![CDATA[Dise&#241;o, ingesta, Kafka, cl&#250;ster y seguridad. Los 56 bloques de SQL verificados contra ClickHouse 26.9 en ambiente, con mediciones reales.]]></description><link>https://blog.carrillo.app/p/buenas-practicas-clickhouse-produccion</link><guid isPermaLink="false">https://blog.carrillo.app/p/buenas-practicas-clickhouse-produccion</guid><dc:creator><![CDATA[José Carrillo]]></dc:creator><pubDate>Wed, 14 Oct 2026 15:00:36 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Axo5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21f6800d-1b79-467b-af51-ff3328c6ac08_1456x816.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Axo5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21f6800d-1b79-467b-af51-ff3328c6ac08_1456x816.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Axo5!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21f6800d-1b79-467b-af51-ff3328c6ac08_1456x816.png 424w, https://substackcdn.com/image/fetch/$s_!Axo5!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21f6800d-1b79-467b-af51-ff3328c6ac08_1456x816.png 848w, https://substackcdn.com/image/fetch/$s_!Axo5!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21f6800d-1b79-467b-af51-ff3328c6ac08_1456x816.png 1272w, https://substackcdn.com/image/fetch/$s_!Axo5!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21f6800d-1b79-467b-af51-ff3328c6ac08_1456x816.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Axo5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21f6800d-1b79-467b-af51-ff3328c6ac08_1456x816.png" width="1456" height="816" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/21f6800d-1b79-467b-af51-ff3328c6ac08_1456x816.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:816,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:227309,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/219626269?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21f6800d-1b79-467b-af51-ff3328c6ac08_1456x816.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Axo5!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21f6800d-1b79-467b-af51-ff3328c6ac08_1456x816.png 424w, https://substackcdn.com/image/fetch/$s_!Axo5!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21f6800d-1b79-467b-af51-ff3328c6ac08_1456x816.png 848w, https://substackcdn.com/image/fetch/$s_!Axo5!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21f6800d-1b79-467b-af51-ff3328c6ac08_1456x816.png 1272w, https://substackcdn.com/image/fetch/$s_!Axo5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21f6800d-1b79-467b-af51-ff3328c6ac08_1456x816.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Dise&#241;o, ingesta, Kafka, consultas, cl&#250;ster, seguridad y operaci&#243;n. Los 56 bloques de SQL de este art&#237;culo se ejecutaron contra ClickHouse 26.9 en Docker antes de publicarlo, y las cifras son mediciones reales, no estimaciones.</em></figcaption></figure></div><p>Las buenas pr&#225;cticas de ClickHouse se reducen a una idea inc&#243;moda: el motor casi nunca es el problema. ClickHouse es brutalmente r&#225;pido cuando lo usas como fue dise&#241;ado, y sorprendentemente lento cuando lo tratas como un PostgreSQL con esteroides.</p><p>Casi todos los problemas de rendimiento en producci&#243;n son autoinfligidos: una <code>ORDER BY</code> mal elegida, inserciones fila por fila, un <code>FINAL</code> en el camino caliente, un <code>JOIN</code> al rev&#233;s. No son l&#237;mites del motor. Son decisiones tuyas, y casi todas se toman el d&#237;a que escribes el <code>CREATE TABLE</code>.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Esta gu&#237;a recoge las reglas que s&#237; o s&#237; debes cumplir para optimizar ClickHouse en producci&#243;n, con el porqu&#233; de cada una y, cuando se puede medir, con la medici&#243;n delante.</p><blockquote><p><strong>En una frase:</strong> elige la <code>ORDER BY</code> por tus filtros reales, inserta en lotes grandes, no uses <code>SELECT *</code> ni <code>FINAL</code>, pon la tabla peque&#241;a a la derecha del <code>JOIN</code>, protege cada consumidor con perfil y cuota, y mide con <code>EXPLAIN indexes = 1</code> y <code>system.query_log</code> en vez de adivinar.</p></blockquote><p>Lo que cubre esta gu&#237;a:</p><ul><li><p>C&#243;mo elegir la <code>ORDER BY</code> y por qu&#233; la <code>PRIMARY KEY</code> deber&#237;a ser m&#225;s corta</p></li><li><p>Particionado, tipos, zonas horarias y c&#243;decs de compresi&#243;n</p></li><li><p>Ingesta por lotes, <code>async_insert</code>, deduplicaci&#243;n y <code>TOO_MANY_PARTS</code></p></li><li><p>Ingesta desde Kafka sin perder eventos</p></li><li><p>Consultas: poda del &#237;ndice, <code>FINAL</code>, <code>JOIN</code> y memoria</p></li><li><p>Cu&#225;ndo usar un &#237;ndice de salto, una proyecci&#243;n o una vista materializada</p></li><li><p>Replicaci&#243;n, Keeper, sharding y consultas distribuidas</p></li><li><p>Seguridad, cuotas y multi-tenancy</p></li><li><p>Migraciones de esquema y backups que de verdad restauran</p></li><li><p>Observabilidad, antipatrones, preguntas frecuentes y checklist</p></li></ul><p>Al final tienes el entorno Docker para reproducirlo todo en tu m&#225;quina en cinco minutos.</p><div><hr></div><h2><strong>1. C&#243;mo elegir la ORDER BY en ClickHouse</strong></h2><p>En <code>MergeTree</code>, la clave de ordenamiento define el &#237;ndice primario, que es <strong>disperso</strong>: una marca cada 8.192 filas (<code>index_granularity</code>). ClickHouse no busca filas, descarta bloques de 8.192. Todo lo dem&#225;s &#8212;c&#243;decs, proyecciones, &#237;ndices de salto&#8212; es secundario frente a esta decisi&#243;n.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!vsG6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc20ae1a3-aaf2-4e8d-bb18-35d0369bd08a_1456x712.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vsG6!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc20ae1a3-aaf2-4e8d-bb18-35d0369bd08a_1456x712.png 424w, https://substackcdn.com/image/fetch/$s_!vsG6!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc20ae1a3-aaf2-4e8d-bb18-35d0369bd08a_1456x712.png 848w, https://substackcdn.com/image/fetch/$s_!vsG6!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc20ae1a3-aaf2-4e8d-bb18-35d0369bd08a_1456x712.png 1272w, https://substackcdn.com/image/fetch/$s_!vsG6!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc20ae1a3-aaf2-4e8d-bb18-35d0369bd08a_1456x712.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!vsG6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc20ae1a3-aaf2-4e8d-bb18-35d0369bd08a_1456x712.png" width="1456" height="712" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c20ae1a3-aaf2-4e8d-bb18-35d0369bd08a_1456x712.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:712,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:111191,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/219626269?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc20ae1a3-aaf2-4e8d-bb18-35d0369bd08a_1456x712.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!vsG6!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc20ae1a3-aaf2-4e8d-bb18-35d0369bd08a_1456x712.png 424w, https://substackcdn.com/image/fetch/$s_!vsG6!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc20ae1a3-aaf2-4e8d-bb18-35d0369bd08a_1456x712.png 848w, https://substackcdn.com/image/fetch/$s_!vsG6!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc20ae1a3-aaf2-4e8d-bb18-35d0369bd08a_1456x712.png 1272w, https://substackcdn.com/image/fetch/$s_!vsG6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc20ae1a3-aaf2-4e8d-bb18-35d0369bd08a_1456x712.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Una marca por granule de 8.192 filas: ese es todo el &#237;ndice de ClickHouse.</figcaption></figure></div><p>Las reglas:</p><ul><li><p>Ordena las columnas <strong>de menor a mayor cardinalidad</strong>.</p></li><li><p>Pon primero las columnas por las que <strong>siempre</strong> filtras.</p></li><li><p>Mantenla corta: de 2 a 4 columnas. M&#225;s columnas rara vez ayudan y encarecen los merges.</p></li><li><p>La marca de tiempo casi nunca va primero: suele ser la columna de mayor cardinalidad.</p></li></ul><pre><code><code>-- Mal: el timestamp primero mata la poda por tenant
CREATE TABLE events (...)
ENGINE = MergeTree
ORDER BY (event_time, tenant_id, user_id);

-- Bien: filtras por tenant, luego acotas por tiempo
CREATE TABLE events
(
    tenant_id   UInt32,
    event_type  LowCardinality(String),
    user_id     UInt64,
    event_time  DateTime('UTC') CODEC(Delta, ZSTD(1)),
    duration_ms UInt32          CODEC(T64, ZSTD(1)),
    revenue     Decimal(18,4),
    payload     String          CODEC(ZSTD(3))
)
ENGINE = MergeTree
PARTITION BY toYYYYMM(event_time)
PRIMARY KEY (tenant_id, event_type)
ORDER BY (tenant_id, event_type, event_time, user_id)
SETTINGS index_granularity = 8192;</code></code></pre><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!SBve!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F465d97e5-604c-4ab5-82c8-b06193d90e27_1456x792.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!SBve!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F465d97e5-604c-4ab5-82c8-b06193d90e27_1456x792.png 424w, https://substackcdn.com/image/fetch/$s_!SBve!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F465d97e5-604c-4ab5-82c8-b06193d90e27_1456x792.png 848w, https://substackcdn.com/image/fetch/$s_!SBve!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F465d97e5-604c-4ab5-82c8-b06193d90e27_1456x792.png 1272w, https://substackcdn.com/image/fetch/$s_!SBve!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F465d97e5-604c-4ab5-82c8-b06193d90e27_1456x792.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!SBve!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F465d97e5-604c-4ab5-82c8-b06193d90e27_1456x792.png" width="1456" height="792" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/465d97e5-604c-4ab5-82c8-b06193d90e27_1456x792.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:792,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:148775,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/219626269?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F465d97e5-604c-4ab5-82c8-b06193d90e27_1456x792.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!SBve!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F465d97e5-604c-4ab5-82c8-b06193d90e27_1456x792.png 424w, https://substackcdn.com/image/fetch/$s_!SBve!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F465d97e5-604c-4ab5-82c8-b06193d90e27_1456x792.png 848w, https://substackcdn.com/image/fetch/$s_!SBve!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F465d97e5-604c-4ab5-82c8-b06193d90e27_1456x792.png 1272w, https://substackcdn.com/image/fetch/$s_!SBve!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F465d97e5-604c-4ab5-82c8-b06193d90e27_1456x792.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Los mismos datos y la misma consulta. Solo cambia el orden de la ORDER BY.</figcaption></figure></div><h3><strong>La diferencia, medida</strong></h3><p>Sobre una tabla de dos millones de filas, la misma consulta con y sin el prefijo de la <code>ORDER BY</code>:</p><pre><code><code>consulta                       marcas  filas le&#237;das   bytes le&#237;dos
con prefijo de la ORDER BY          3      24.580         192 KiB
sin prefijo                        93     757.150        2,89 MiB</code></code></pre><p>Treinta veces menos filas, quince veces menos bytes, y el mismo resultado. En una tabla de mil millones de filas esa proporci&#243;n es la diferencia entre un dashboard y un incidente.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>No lo supongas: m&#237;ralo.</p><pre><code><code>EXPLAIN indexes = 1
SELECT count()
FROM events
WHERE tenant_id = 5 AND event_time &gt;= now() - INTERVAL 1 DAY;</code></code></pre><p>Si el plan muestra que lee todas las partes y todos los granules, tu <code>WHERE</code> no est&#225; tocando el prefijo de la clave. Y no envuelvas la columna indexada en funciones: <code>WHERE toDate(event_time) = today()</code> dificulta la poda, <code>WHERE event_time &gt;= today() AND event_time &lt; today() + 1</code> no.</p><h3><strong>La PRIMARY KEY puede ser m&#225;s corta que la ORDER BY</strong></h3><p>Esta es la optimizaci&#243;n avanzada que casi nadie aplica. <code>PRIMARY KEY</code> debe ser un prefijo de <code>ORDER BY</code>, pero <strong>no tiene por qu&#233; ser igual de larga</strong>. Las marcas del &#237;ndice primario viven en RAM: si tu <code>ORDER BY</code> termina en una columna de alt&#237;sima cardinalidad que solo necesitas para ordenar dentro del granule, d&#233;jala fuera de la <code>PRIMARY KEY</code> y te ahorras memoria en cada r&#233;plica.</p><pre><code><code>SELECT
    t.primary_key AS clave_primaria,
    t.sorting_key AS clave_de_orden,
    formatReadableSize(sum(p.primary_key_bytes_in_memory)) AS marcas_en_ram
FROM system.tables AS t
INNER JOIN system.parts AS p
    ON p.database = t.database AND p.table = t.name
WHERE t.database = currentDatabase() AND t.name = 'events' AND p.active
GROUP BY clave_primaria, clave_de_orden;</code></code></pre><p>No existe una <code>ORDER BY</code> buena para todos los patrones de consulta. Si tienes dos patrones muy distintos, la respuesta es una proyecci&#243;n o una tabla aparte, nunca una clave de compromiso que sirve mal a ambos.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2><strong>2. Particionado: cu&#225;ntas particiones aguanta una tabla</strong></h2><p>La partici&#243;n es una unidad de <strong>gesti&#243;n de datos</strong> (borrado, TTL, mover a almacenamiento fr&#237;o), no un mecanismo de aceleraci&#243;n. Eso lo hace la <code>ORDER BY</code>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!AlH1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febbd4c85-7699-4046-912c-d72aa3daca18_1456x572.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!AlH1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febbd4c85-7699-4046-912c-d72aa3daca18_1456x572.png 424w, https://substackcdn.com/image/fetch/$s_!AlH1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febbd4c85-7699-4046-912c-d72aa3daca18_1456x572.png 848w, https://substackcdn.com/image/fetch/$s_!AlH1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febbd4c85-7699-4046-912c-d72aa3daca18_1456x572.png 1272w, https://substackcdn.com/image/fetch/$s_!AlH1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febbd4c85-7699-4046-912c-d72aa3daca18_1456x572.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!AlH1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febbd4c85-7699-4046-912c-d72aa3daca18_1456x572.png" width="1456" height="572" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ebbd4c85-7699-4046-912c-d72aa3daca18_1456x572.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:572,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:117858,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/219626269?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febbd4c85-7699-4046-912c-d72aa3daca18_1456x572.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!AlH1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febbd4c85-7699-4046-912c-d72aa3daca18_1456x572.png 424w, https://substackcdn.com/image/fetch/$s_!AlH1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febbd4c85-7699-4046-912c-d72aa3daca18_1456x572.png 848w, https://substackcdn.com/image/fetch/$s_!AlH1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febbd4c85-7699-4046-912c-d72aa3daca18_1456x572.png 1272w, https://substackcdn.com/image/fetch/$s_!AlH1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febbd4c85-7699-4046-912c-d72aa3daca18_1456x572.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">La partici&#243;n sirve para borrar datos, no para acelerar consultas.</figcaption></figure></div><p>Objetivo: decenas o pocos cientos de particiones por tabla, nunca miles. Y si no necesitas borrar por rango, <strong>puedes no particionar</strong>: es una opci&#243;n perfectamente v&#225;lida y a menudo la correcta.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Para expirar datos, <code>TTL</code> y nunca un cron con <code>DELETE</code>:</p><pre><code><code>ALTER TABLE events MODIFY TTL event_time + INTERVAL 365 DAY DELETE;</code></code></pre><p>Si adem&#225;s quieres enfriar antes de borrar (<code>TO VOLUME 'cold'</code>), necesitas una <code>storage_policy</code> configurada en el servidor con ese volumen definido; sin ella el <code>ALTER</code> falla. Ese es el camino habitual para mover datos antiguos a S3 y pagar almacenamiento de objetos en vez de NVMe.</p><div><hr></div><h2><strong>3. Tipos y c&#243;decs: la compresi&#243;n es velocidad</strong></h2><p>El tipo de dato no es una cuesti&#243;n de pulcritud. Menos bytes en disco son menos bytes que descomprimir, y la descompresi&#243;n es tiempo de CPU en cada consulta.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!In0x!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4858ceb-dfa3-48ac-b79e-c9ca70532f5d_1456x724.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!In0x!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4858ceb-dfa3-48ac-b79e-c9ca70532f5d_1456x724.png 424w, https://substackcdn.com/image/fetch/$s_!In0x!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4858ceb-dfa3-48ac-b79e-c9ca70532f5d_1456x724.png 848w, https://substackcdn.com/image/fetch/$s_!In0x!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4858ceb-dfa3-48ac-b79e-c9ca70532f5d_1456x724.png 1272w, https://substackcdn.com/image/fetch/$s_!In0x!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4858ceb-dfa3-48ac-b79e-c9ca70532f5d_1456x724.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!In0x!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4858ceb-dfa3-48ac-b79e-c9ca70532f5d_1456x724.png" width="1456" height="724" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b4858ceb-dfa3-48ac-b79e-c9ca70532f5d_1456x724.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:724,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:120902,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/219626269?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4858ceb-dfa3-48ac-b79e-c9ca70532f5d_1456x724.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!In0x!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4858ceb-dfa3-48ac-b79e-c9ca70532f5d_1456x724.png 424w, https://substackcdn.com/image/fetch/$s_!In0x!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4858ceb-dfa3-48ac-b79e-c9ca70532f5d_1456x724.png 848w, https://substackcdn.com/image/fetch/$s_!In0x!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4858ceb-dfa3-48ac-b79e-c9ca70532f5d_1456x724.png 1272w, https://substackcdn.com/image/fetch/$s_!In0x!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4858ceb-dfa3-48ac-b79e-c9ca70532f5d_1456x724.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Se decide una vez al crear la tabla y se cobra en todas las consultas.</figcaption></figure></div><p><code>LowCardinality</code> es la victoria m&#225;s barata de toda la lista. Dos tablas con exactamente los mismos dos millones de valores, una con <code>String</code> y otra con <code>LowCardinality(String)</code>:</p><pre><code><code>tabla        comprimido    sin comprimir
t_lowcard     30,50 KiB        1,92 MiB
t_string     126,68 KiB       26,32 MiB</code></code></pre><p>Cuatro veces menos en disco y, sobre todo, catorce veces menos trabajo de descompresi&#243;n. Apl&#237;calo a cualquier <code>String</code> con menos de unos 10.000 valores distintos; por encima de esa cifra empieza a ser contraproducente.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Sobre <code>Nullable</code>: a&#241;ade una columna de m&#225;scara aparte, con m&#225;s I/O, peor compresi&#243;n y menos optimizaciones. Usa un valor centinela o <code>DEFAULT</code>, salvo que la diferencia entre &#8220;cero&#8221; y &#8220;desconocido&#8221; sea sem&#225;nticamente necesaria. Y nunca pongas una columna <code>Nullable</code> en la <code>ORDER BY</code>.</p><h3><strong>Pon la zona horaria en el tipo, no en la cabeza</strong></h3><p>Esta es la bomba de relojer&#237;a m&#225;s barata de desactivar. Un <code>DateTime</code> sin zona horaria usa la del servidor, y el d&#237;a que migras de m&#225;quina o cambias el <code>timezone</code> del contenedor, todos tus informes se desplazan una hora sin que nadie se entere.</p><pre><code><code>CREATE TABLE eventos_utc
(
    id       UInt64,
    ocurrido DateTime('UTC') CODEC(Delta, ZSTD(1))
)
ENGINE = MergeTree ORDER BY (ocurrido, id);</code></code></pre><p>Guarda siempre en UTC y convierte en la capa de presentaci&#243;n. No al rev&#233;s.</p><h3><strong>C&#243;decs</strong></h3><p>Los c&#243;decs se eligen por la forma del dato, no por gusto:</p><ul><li><p><code>Delta</code> y <code>DoubleDelta</code> para secuencias mon&#243;tonas: timestamps, contadores, identificadores incrementales.</p></li><li><p><code>Gorilla</code> o <code>T64</code> para flotantes y enteros de m&#233;tricas.</p></li><li><p><code>ZSTD(1..3)</code> para texto y datos fr&#237;os, cuando el disco pesa m&#225;s que la CPU.</p></li><li><p><code>LZ4</code> (el default) cuando la CPU pesa m&#225;s que el disco.</p></li></ul><p>Audita lo que de verdad est&#225; ocupando espacio, columna por columna:</p><pre><code><code>SELECT
    column,
    formatReadableSize(sum(column_data_compressed_bytes))   AS comprimido,
    formatReadableSize(sum(column_data_uncompressed_bytes)) AS crudo,
    round(sum(column_data_uncompressed_bytes)
        / sum(column_data_compressed_bytes), 1)             AS ratio
FROM system.parts_columns
WHERE active AND table = 'events' AND database = currentDatabase()
GROUP BY column
ORDER BY sum(column_data_compressed_bytes) DESC;</code></code></pre><p>La columna con peor ratio y m&#225;s peso es siempre la primera candidata a un c&#243;dec distinto o a un tipo m&#225;s estrecho.</p><h3><strong>Y si el esquema no lo controlas t&#250;</strong></h3><p>Para payloads semiestructurados que cambian sin avisar, ClickHouse tiene un tipo <code>JSON</code> nativo que crea subcolumnas sobre la marcha, en vez de obligarte a guardar un <code>String</code> y parsearlo en cada consulta:</p><pre><code><code>CREATE TABLE eventos_json (id UInt64, payload JSON)
ENGINE = MergeTree ORDER BY id;

INSERT INTO eventos_json VALUES (1, '{"a": 1, "b": {"c": "x"}}');

SELECT id, payload.a, payload.b.c FROM eventos_json;</code></code></pre><p>&#218;salo para lo que de verdad es variable. Las columnas que consultas siempre merecen ser columnas de verdad, con su tipo y su c&#243;dec.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2><strong>4. Ingesta: por qu&#233; fila a fila rompe el cl&#250;ster</strong></h2><p>Cada <code>INSERT</code> crea una parte en disco. Las partes se fusionan en segundo plano. Si insertas fila por fila, generas miles de partes, el merge no da abasto y recibes <code>TOO_MANY_PARTS</code>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!gAQP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc35caa6-028f-4efb-8830-d61b68a1f31c_1456x724.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!gAQP!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc35caa6-028f-4efb-8830-d61b68a1f31c_1456x724.png 424w, https://substackcdn.com/image/fetch/$s_!gAQP!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc35caa6-028f-4efb-8830-d61b68a1f31c_1456x724.png 848w, https://substackcdn.com/image/fetch/$s_!gAQP!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc35caa6-028f-4efb-8830-d61b68a1f31c_1456x724.png 1272w, https://substackcdn.com/image/fetch/$s_!gAQP!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc35caa6-028f-4efb-8830-d61b68a1f31c_1456x724.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!gAQP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc35caa6-028f-4efb-8830-d61b68a1f31c_1456x724.png" width="1456" height="724" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bc35caa6-028f-4efb-8830-d61b68a1f31c_1456x724.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:724,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:138313,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/219626269?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc35caa6-028f-4efb-8830-d61b68a1f31c_1456x724.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!gAQP!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc35caa6-028f-4efb-8830-d61b68a1f31c_1456x724.png 424w, https://substackcdn.com/image/fetch/$s_!gAQP!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc35caa6-028f-4efb-8830-d61b68a1f31c_1456x724.png 848w, https://substackcdn.com/image/fetch/$s_!gAQP!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc35caa6-028f-4efb-8830-d61b68a1f31c_1456x724.png 1272w, https://substackcdn.com/image/fetch/$s_!gAQP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc35caa6-028f-4efb-8830-d61b68a1f31c_1456x724.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">El merge tiene un presupuesto fijo. Fila a fila se le agota.</figcaption></figure></div><p>Los umbrales no son misteriosos, est&#225;n en una tabla del sistema:</p><pre><code><code>SELECT name, value
FROM system.merge_tree_settings
WHERE name IN ('parts_to_delay_insert', 'parts_to_throw_insert',
               'replicated_deduplication_window',
               'replicated_deduplication_window_seconds');</code></code></pre><p>En ClickHouse 26.9 los valores por defecto son 1.000 partes activas por partici&#243;n para empezar a <strong>retrasar</strong> los <code>INSERT</code> y 3.000 para <strong>rechazarlos</strong>. Si est&#225;s rozando el primero, ya tienes un problema: el segundo llega en cuesti&#243;n de horas.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>De 10.000 a 100.000 filas o m&#225;s por <code>INSERT</code>, y como m&#225;ximo una inserci&#243;n por segundo y por tabla desde cada productor. Si tienes muchos clientes concurrentes y peque&#241;os, no los coordines a mano: deja que el servidor agrupe.</p><pre><code><code>INSERT INTO estados
SETTINGS async_insert = 1,
         wait_for_async_insert = 1,
         async_insert_busy_timeout_ms = 1000,
         async_insert_max_data_size = 10000000
VALUES (3, 'nuevo', 1);</code></code></pre><p><code>wait_for_async_insert = 1</code> mantiene la garant&#237;a de durabilidad: el cliente recibe el acuse cuando el bloque est&#225; escrito. Ponerlo a <code>0</code> multiplica el rendimiento y te deja sin saber si el dato lleg&#243;. Es una decisi&#243;n de negocio, no de ingenier&#237;a.</p><blockquote><p>Si tu soluci&#243;n a <code>TOO_MANY_PARTS</code> es subir el l&#237;mite de partes, no has arreglado nada: has movido el incidente a la semana que viene.</p></blockquote><h3><strong>Reintentos sin duplicados</strong></h3><p>Las tablas replicadas deduplican bloques id&#233;nticos autom&#225;ticamente: guardan en Keeper la huella de los &#250;ltimos 10.000 bloques insertados, durante una hora. Si tu reintento manda exactamente el mismo bloque dentro de esa ventana, no se duplica.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>El problema es que casi ning&#250;n pipeline reenv&#237;a el bloque <em>exactamente</em> igual. Para eso existe el token expl&#237;cito:</p><pre><code><code>INSERT INTO estados
SETTINGS insert_deduplication_token = 'lote-2026-10-09-0001'
VALUES (4, 'nuevo', 1);</code></code></pre><p>Con un token derivado del lote de origen (offset de Kafka, id de fichero, rango de fechas), tu pipeline puede reintentar sin miedo y sin l&#243;gica de deduplicaci&#243;n en la aplicaci&#243;n.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Dos detalles m&#225;s que ahorran incidentes: nombra siempre las columnas (<code>INSERT INTO t (a, b, c) ...</code>) para que un <code>ALTER TABLE ADD COLUMN</code> no te rompa la ingesta, y usa formatos nativos (<code>Native</code> o <code>RowBinary</code> por encima de <code>Parquet</code>, y <code>Parquet</code> por encima de <code>JSONEachRow</code>), con compresi&#243;n activada en el cliente.</p><h3><strong>Actualizar y borrar es excepcional</strong></h3><p><code>ALTER TABLE ... UPDATE</code> y <code>DELETE</code> son <strong>mutaciones</strong>: reescriben partes completas de forma as&#237;ncrona. No son transacciones y no son baratas.</p><ul><li><p>Para corregir datos: <code>DROP PARTITION</code> y reinsertar.</p></li><li><p>Para &#8220;&#250;ltima versi&#243;n gana&#8221;: <code>ReplacingMergeTree</code>.</p></li><li><p>Para borrados puntuales: <code>DELETE FROM ... WHERE ...</code> (ligero, marca filas), entendiendo que la fila sigue en disco hasta el siguiente merge.</p></li><li><p>Para expiraci&#243;n por antig&#252;edad: <code>TTL</code>.</p></li></ul><p>Cuando lances una mutaci&#243;n y necesites esperar a que termine, <code>SETTINGS mutations_sync = 2</code>. Y vigila las que se quedan atascadas, que es un cl&#225;sico silencioso:</p><pre><code><code>SELECT database, table, mutation_id, command, parts_to_do, latest_fail_reason
FROM system.mutations
WHERE NOT is_done;</code></code></pre><div><hr></div><h2><strong>5. Ingesta desde Kafka sin perder eventos</strong></h2><p>Kafka es el origen m&#225;s com&#250;n de datos en ClickHouse, y tambi&#233;n el que m&#225;s gente monta mal. La tabla con <code>ENGINE = Kafka</code> <strong>no es una tabla</strong>: es un consumidor. Leer de ella consume del topic, y lo que lees desaparece para el resto.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!4isR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e07b5b4-99da-4dc8-a49c-545404149ec5_1456x660.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!4isR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e07b5b4-99da-4dc8-a49c-545404149ec5_1456x660.png 424w, https://substackcdn.com/image/fetch/$s_!4isR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e07b5b4-99da-4dc8-a49c-545404149ec5_1456x660.png 848w, https://substackcdn.com/image/fetch/$s_!4isR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e07b5b4-99da-4dc8-a49c-545404149ec5_1456x660.png 1272w, https://substackcdn.com/image/fetch/$s_!4isR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e07b5b4-99da-4dc8-a49c-545404149ec5_1456x660.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!4isR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e07b5b4-99da-4dc8-a49c-545404149ec5_1456x660.png" width="1456" height="660" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2e07b5b4-99da-4dc8-a49c-545404149ec5_1456x660.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:660,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:135458,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/219626269?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e07b5b4-99da-4dc8-a49c-545404149ec5_1456x660.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!4isR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e07b5b4-99da-4dc8-a49c-545404149ec5_1456x660.png 424w, https://substackcdn.com/image/fetch/$s_!4isR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e07b5b4-99da-4dc8-a49c-545404149ec5_1456x660.png 848w, https://substackcdn.com/image/fetch/$s_!4isR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e07b5b4-99da-4dc8-a49c-545404149ec5_1456x660.png 1272w, https://substackcdn.com/image/fetch/$s_!4isR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e07b5b4-99da-4dc8-a49c-545404149ec5_1456x660.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Tres objetos, no dos: solo el tercero guarda algo.</figcaption></figure></div><p>Hacen falta tres objetos, no dos: la cola, la vista que la vac&#237;a y la tabla donde viven los datos.</p><pre><code><code>CREATE TABLE events_kafka
(
    tenant_id  UInt32,
    event_type String,
    user_id    UInt64,
    event_time DateTime
)
ENGINE = Kafka
SETTINGS kafka_broker_list = 'kafka:9092',
         kafka_topic_list = 'events',
         kafka_group_name = 'clickhouse-events',
         kafka_format = 'JSONEachRow',
         kafka_num_consumers = 3,
         kafka_max_block_size = 1048576,
         kafka_handle_error_mode = 'stream';

CREATE MATERIALIZED VIEW mv_kafka_events TO events AS
SELECT tenant_id, event_type, user_id, event_time
FROM events_kafka;</code></code></pre><p>Las reglas que evitan el 90% de los incidentes:</p><ul><li><p><strong>Nunca hagas </strong><code>SELECT</code><strong> a la tabla Kafka</strong> para &#8220;ver si llegan datos&#8221;. Cada consulta consume mensajes que ya no llegar&#225;n a la vista materializada. Si quieres inspeccionar, mira la tabla destino.</p></li><li><p><code>kafka_num_consumers</code><strong> nunca por encima del n&#250;mero de particiones del topic.</strong> Los consumidores sobrantes se quedan ociosos ocupando hilos.</p></li><li><p><code>kafka_handle_error_mode = 'stream'</code> manda los mensajes que no parsean a un flujo de errores en vez de bloquear el consumidor. Sin esto, un solo mensaje corrupto puede parar la ingesta entera.</p></li><li><p><strong>Una vista materializada por destino.</strong> Si necesitas escribir en tres tablas, son tres vistas sobre la misma cola, no una vista con tres <code>INSERT</code>.</p></li><li><p><strong>Vigila </strong><code>system.kafka_consumers</code>: ah&#237; se ve el retraso, las excepciones y si el consumidor est&#225; vivo.</p></li></ul><p>Para idempotencia real de extremo a extremo, usa el offset de Kafka en el <code>insert_deduplication_token</code> de la secci&#243;n anterior. Es la forma m&#225;s simple de aproximarse a exactly-once sin inventar un sistema de control de estado.</p><div><hr></div><h2><strong>6. Consultas: lo que cuesta caro</strong></h2><h3><strong>Nunca SELECT *</strong></h3><p>ClickHouse es columnar. <code>SELECT *</code> lee todas las columnas del disco y anula la principal ventaja del motor. Pide solo lo que necesitas. Siempre.</p><h3><strong>Evita FINAL en el camino caliente</strong></h3><p><code>FINAL</code> fuerza la fusi&#243;n en tiempo de consulta. Es correcto, y es lento. Para <code>ReplacingMergeTree</code>, agrega expl&#237;citamente:</p><pre><code><code>SELECT
    id,
    argMax(status, version) AS estado_actual,
    max(version)            AS ultima_version
FROM estados
GROUP BY id;</code></code></pre><p><strong>Ojo con los alias</strong>, porque aqu&#237; hay una trampa que la mayor&#237;a de art&#237;culos copia mal. Esta variante, que circula por todas partes, <strong>falla</strong> en ClickHouse moderno:</p><pre><code><code>-- NO funciona: Code 184, aggregate function inside another aggregate function
SELECT id, argMax(status, version) AS status, max(version) AS version
FROM estados
GROUP BY id;</code></code></pre><p>Al llamar <code>version</code> al alias de <code>max(version)</code>, el analizador resuelve el <code>version</code> de dentro de <code>argMax</code> contra el alias, y acabas con una agregaci&#243;n dentro de otra. Dale a los alias nombres distintos de las columnas que agregas.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Y nunca ejecutes <code>OPTIMIZE TABLE ... FINAL</code> de forma peri&#243;dica sobre tablas grandes: reescribe todo y es la causa habitual de cl&#250;steres saturados.</p><h3><strong>Haz los JOIN en el orden correcto</strong></h3><p>ClickHouse carga la <strong>tabla derecha en memoria</strong> para construir la hash table. El orden no es una preferencia del optimizador: es la diferencia entre 200 ms y un <code>MEMORY_LIMIT_EXCEEDED</code>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ZS01!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb4f3ab6-d66a-46b1-97d2-35de194f5378_1456x616.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ZS01!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb4f3ab6-d66a-46b1-97d2-35de194f5378_1456x616.png 424w, https://substackcdn.com/image/fetch/$s_!ZS01!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb4f3ab6-d66a-46b1-97d2-35de194f5378_1456x616.png 848w, https://substackcdn.com/image/fetch/$s_!ZS01!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb4f3ab6-d66a-46b1-97d2-35de194f5378_1456x616.png 1272w, https://substackcdn.com/image/fetch/$s_!ZS01!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb4f3ab6-d66a-46b1-97d2-35de194f5378_1456x616.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!ZS01!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb4f3ab6-d66a-46b1-97d2-35de194f5378_1456x616.png" width="1456" height="616" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bb4f3ab6-d66a-46b1-97d2-35de194f5378_1456x616.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:616,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:144812,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/219626269?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb4f3ab6-d66a-46b1-97d2-35de194f5378_1456x616.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ZS01!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb4f3ab6-d66a-46b1-97d2-35de194f5378_1456x616.png 424w, https://substackcdn.com/image/fetch/$s_!ZS01!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb4f3ab6-d66a-46b1-97d2-35de194f5378_1456x616.png 848w, https://substackcdn.com/image/fetch/$s_!ZS01!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb4f3ab6-d66a-46b1-97d2-35de194f5378_1456x616.png 1272w, https://substackcdn.com/image/fetch/$s_!ZS01!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb4f3ab6-d66a-46b1-97d2-35de194f5378_1456x616.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">La tabla que escribas a la derecha es la que acaba en memoria</figcaption></figure></div><p>Filtra y agrega en subconsultas <em>antes</em> de unir, no despu&#233;s. Y si la tabla derecha realmente no cabe, cambia de algoritmo antes que de l&#237;mite de memoria:</p><pre><code><code>SELECT count()
FROM events AS e
JOIN estados AS s ON e.user_id = s.id
SETTINGS join_algorithm = 'grace_hash';</code></code></pre><p>Para dimensiones, lo correcto no es un <code>JOIN</code> mejor, sino ning&#250;n <code>JOIN</code>. Un diccionario vive en memoria, se refresca solo y se consulta con una funci&#243;n:</p><pre><code><code>CREATE DICTIONARY dim_tenants
(
    tenant_id UInt32,
    nombre    String,
    plan      String
)
PRIMARY KEY tenant_id
SOURCE(CLICKHOUSE(QUERY $q$
    SELECT tenant_id, nombre, plan FROM dim.tenants
$q$))
LAYOUT(HASHED())
LIFETIME(MIN 600 MAX 900);

SELECT
    dictGet('dim_tenants', 'nombre', toUInt64(tenant_id)) AS tenant,
    count() AS eventos
FROM events
WHERE event_time &gt;= now() - INTERVAL 1 DAY
GROUP BY tenant
ORDER BY eventos DESC;</code></code></pre><h3><strong>Aproxima cuando puedas</strong></h3><p><code>uniq()</code> en lugar de <code>count(DISTINCT)</code>, <code>uniqCombined</code> si necesitas ajustar memoria y precisi&#243;n, <code>quantile()</code> en lugar de <code>quantileExact()</code>. Reserva las versiones exactas para cuando el negocio realmente las exija, que es menos a menudo de lo que la gente cree.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h3><strong>Pon l&#237;mites a cada consulta</strong></h3><p>Un cliente mal escrito no debe poder tumbar el cl&#250;ster.</p><pre><code><code>SELECT count() FROM events
SETTINGS max_execution_time = 60,
         max_memory_usage = 10000000000,
         max_rows_to_read = 1000000000,
         max_result_rows = 100000,
         max_bytes_before_external_group_by = 2000000000;</code></code></pre><p><code>max_bytes_before_external_group_by</code> es el que evita que una agregaci&#243;n enorme muera: a partir de ese umbral vuelca a disco en vez de reventar. Pero no lo escribas consulta a consulta: eso es la secci&#243;n 9.</p><p>Y si tienes un dashboard que repite la misma consulta cada quince segundos, la cach&#233; de consultas sale casi gratis:</p><pre><code><code>SELECT count() FROM events WHERE tenant_id = 7
SETTINGS use_query_cache = 1, query_cache_ttl = 60;</code></code></pre><div><hr></div><h2><strong>7. &#205;ndice de salto, proyecci&#243;n o vista materializada</strong></h2><p>Cuando aparece un segundo patr&#243;n de acceso, hay cuatro respuestas posibles y cada una te cobra algo distinto. Elegir mal aqu&#237; es el error de arquitectura m&#225;s caro de revertir.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!AUkG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a0eb5f3-571e-4650-948e-60ef495a0481_1456x620.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!AUkG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a0eb5f3-571e-4650-948e-60ef495a0481_1456x620.png 424w, https://substackcdn.com/image/fetch/$s_!AUkG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a0eb5f3-571e-4650-948e-60ef495a0481_1456x620.png 848w, https://substackcdn.com/image/fetch/$s_!AUkG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a0eb5f3-571e-4650-948e-60ef495a0481_1456x620.png 1272w, https://substackcdn.com/image/fetch/$s_!AUkG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a0eb5f3-571e-4650-948e-60ef495a0481_1456x620.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!AUkG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a0eb5f3-571e-4650-948e-60ef495a0481_1456x620.png" width="1456" height="620" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5a0eb5f3-571e-4650-948e-60ef495a0481_1456x620.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:620,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:141852,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/219626269?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a0eb5f3-571e-4650-948e-60ef495a0481_1456x620.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!AUkG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a0eb5f3-571e-4650-948e-60ef495a0481_1456x620.png 424w, https://substackcdn.com/image/fetch/$s_!AUkG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a0eb5f3-571e-4650-948e-60ef495a0481_1456x620.png 848w, https://substackcdn.com/image/fetch/$s_!AUkG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a0eb5f3-571e-4650-948e-60ef495a0481_1456x620.png 1272w, https://substackcdn.com/image/fetch/$s_!AUkG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a0eb5f3-571e-4650-948e-60ef495a0481_1456x620.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Cuatro respuestas, ninguna gratis: disco, ingesta o complejidad.</figcaption></figure></div><h3><strong>&#205;ndice de salto</strong></h3><pre><code><code>ALTER TABLE events
    ADD INDEX idx_user user_id TYPE bloom_filter(0.01) GRANULARITY 4;

ALTER TABLE events MATERIALIZE INDEX idx_user SETTINGS mutations_sync = 2;</code></code></pre><p>Barato en disco, pero <strong>in&#250;til si es poco selectivo</strong>: si el valor buscado aparece en casi todos los granules, el &#237;ndice no descarta nada y solo has a&#241;adido coste de escritura. El <code>GRANULARITY</code> del &#237;ndice multiplica los granules que cubre cada entrada; afinarlo importa tanto como el tipo. Verif&#237;calo siempre con <code>EXPLAIN indexes = 1</code>.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h3><strong>Proyecci&#243;n</strong></h3><p>Una proyecci&#243;n es una segunda copia de los datos con otra <code>ORDER BY</code>, mantenida por el propio motor durante los merges:</p><pre><code><code>ALTER TABLE events ADD PROJECTION by_user
(
    SELECT tenant_id, user_id, event_time, duration_ms
    ORDER BY (user_id, event_time)
);

ALTER TABLE events MATERIALIZE PROJECTION by_user
SETTINGS mutations_sync = 2;</code></code></pre><p>Medido sobre la misma tabla, con y sin proyecci&#243;n para un filtro por <code>user_id</code>:</p><pre><code><code>modo               marcas  filas le&#237;das   bytes le&#237;dos
con proyecci&#243;n          3      24.580         192 KiB
sin proyecci&#243;n         16     131.070        1,00 MiB</code></code></pre><p>Para comprobar que el optimizador la est&#225; usando de verdad, hay dos herramientas: <code>EXPLAIN projections = 1</code>, que muestra <code>ReadFromMergeTree (by_user)</code> cuando entra, y <code>SETTINGS force_optimize_projection = 1</code>, que hace fallar la consulta si ninguna proyecci&#243;n se aplica. Esa segunda es perfecta para un test de regresi&#243;n en CI.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>El precio: duplica el almacenamiento de las columnas proyectadas y no se combina con <code>FINAL</code>.</p><h3><strong>Vista materializada</strong></h3><p>Una vista materializada en ClickHouse es un <strong>trigger de inserci&#243;n</strong>: se dispara con cada bloque insertado en la tabla origen y escribe en la tabla destino.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!mw0m!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd12ddee3-cb68-4f36-8d20-36be7fb5c9b4_1456x576.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mw0m!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd12ddee3-cb68-4f36-8d20-36be7fb5c9b4_1456x576.png 424w, https://substackcdn.com/image/fetch/$s_!mw0m!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd12ddee3-cb68-4f36-8d20-36be7fb5c9b4_1456x576.png 848w, https://substackcdn.com/image/fetch/$s_!mw0m!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd12ddee3-cb68-4f36-8d20-36be7fb5c9b4_1456x576.png 1272w, https://substackcdn.com/image/fetch/$s_!mw0m!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd12ddee3-cb68-4f36-8d20-36be7fb5c9b4_1456x576.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!mw0m!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd12ddee3-cb68-4f36-8d20-36be7fb5c9b4_1456x576.png" width="1456" height="576" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d12ddee3-cb68-4f36-8d20-36be7fb5c9b4_1456x576.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:576,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:110156,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/219626269?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd12ddee3-cb68-4f36-8d20-36be7fb5c9b4_1456x576.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!mw0m!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd12ddee3-cb68-4f36-8d20-36be7fb5c9b4_1456x576.png 424w, https://substackcdn.com/image/fetch/$s_!mw0m!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd12ddee3-cb68-4f36-8d20-36be7fb5c9b4_1456x576.png 848w, https://substackcdn.com/image/fetch/$s_!mw0m!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd12ddee3-cb68-4f36-8d20-36be7fb5c9b4_1456x576.png 1272w, https://substackcdn.com/image/fetch/$s_!mw0m!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd12ddee3-cb68-4f36-8d20-36be7fb5c9b4_1456x576.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Se ejecuta sobre el bloque que entra, no sobre la tabla.</figcaption></figure></div><pre><code><code>CREATE TABLE events_por_hora
(
    tenant_id  UInt32,
    hora       DateTime,
    eventos    AggregateFunction(count),
    usuarios   AggregateFunction(uniq, UInt64),
    ingresos   AggregateFunction(sum, Decimal(18,4))
)
ENGINE = AggregatingMergeTree
ORDER BY (tenant_id, hora);

CREATE MATERIALIZED VIEW mv_events_por_hora TO events_por_hora AS
SELECT
    tenant_id,
    toStartOfHour(event_time) AS hora,
    countState()              AS eventos,
    uniqState(user_id)        AS usuarios,
    sumState(revenue)         AS ingresos
FROM events
GROUP BY tenant_id, hora;</code></code></pre><p>Dos consecuencias que la gente descubre tarde. La primera: <strong>no reprocesa el hist&#243;rico</strong>, solo ve lo que entra a partir de su creaci&#243;n. El backfill lo haces t&#250;, a mano, y conviene hacerlo por rangos para no comerte la memoria:</p><pre><code><code>INSERT INTO events_por_hora
SELECT
    tenant_id,
    toStartOfHour(event_time) AS hora,
    countState(),
    uniqState(user_id),
    sumState(revenue)
FROM events
WHERE event_time &gt;= '2026-01-01' AND event_time &lt; '2026-02-01'
GROUP BY tenant_id, hora;</code></code></pre><p>La segunda: <strong>si la vista falla o es lenta, frena la ingesta de la tabla origen</strong>. Una vista materializada mal hecha no te da consultas lentas, te da un pipeline ca&#237;do. Mantenlas simples: una vista, una agregaci&#243;n.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Y se lee siempre con las funciones <code>-Merge</code>, nunca directamente:</p><pre><code><code>SELECT
    tenant_id,
    countMerge(eventos)  AS eventos,
    uniqMerge(usuarios)  AS usuarios,
    sumMerge(ingresos)   AS ingresos
FROM events_por_hora
WHERE hora &gt;= now() - INTERVAL 7 DAY
GROUP BY tenant_id;</code></code></pre><h3><strong>Tabla aparte</strong></h3><p>Cuando el patr&#243;n de acceso es tan distinto que nada de lo anterior encaja, la respuesta honesta es una segunda tabla alimentada por su propia vista materializada. Doble ingesta y doble almacenamiento, s&#237;, pero sin parches que se rompen a los seis meses.</p><div><hr></div><h2><strong>8. Cl&#250;ster: replicaci&#243;n, Keeper y consultas distribuidas</strong></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!BGQ0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34f4ce69-dff5-410a-b63f-f2731c2e4a01_1456x700.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!BGQ0!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34f4ce69-dff5-410a-b63f-f2731c2e4a01_1456x700.png 424w, https://substackcdn.com/image/fetch/$s_!BGQ0!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34f4ce69-dff5-410a-b63f-f2731c2e4a01_1456x700.png 848w, https://substackcdn.com/image/fetch/$s_!BGQ0!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34f4ce69-dff5-410a-b63f-f2731c2e4a01_1456x700.png 1272w, https://substackcdn.com/image/fetch/$s_!BGQ0!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34f4ce69-dff5-410a-b63f-f2731c2e4a01_1456x700.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!BGQ0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34f4ce69-dff5-410a-b63f-f2731c2e4a01_1456x700.png" width="1456" height="700" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/34f4ce69-dff5-410a-b63f-f2731c2e4a01_1456x700.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:700,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:109420,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/219626269?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34f4ce69-dff5-410a-b63f-f2731c2e4a01_1456x700.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!BGQ0!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34f4ce69-dff5-410a-b63f-f2731c2e4a01_1456x700.png 424w, https://substackcdn.com/image/fetch/$s_!BGQ0!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34f4ce69-dff5-410a-b63f-f2731c2e4a01_1456x700.png 848w, https://substackcdn.com/image/fetch/$s_!BGQ0!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34f4ce69-dff5-410a-b63f-f2731c2e4a01_1456x700.png 1272w, https://substackcdn.com/image/fetch/$s_!BGQ0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34f4ce69-dff5-410a-b63f-f2731c2e4a01_1456x700.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Menos Keeper no da qu&#243;rum; una sola r&#233;plica no da recuperaci&#243;n.</figcaption></figure></div><p><code>ReplicatedMergeTree</code> y al menos dos r&#233;plicas para cualquier dato que te importe. La coordinaci&#243;n va con <strong>ClickHouse Keeper</strong>, no ZooKeeper, con 3 o 5 nodos (n&#250;mero impar) y disco r&#225;pido, porque es sensible a la latencia. Usa macros <code>{shard}</code> y <code>{replica}</code> en las rutas de las tablas replicadas para que el mismo DDL funcione en todo el cl&#250;ster.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h3><strong>La clave de sharding importa m&#225;s de lo que parece</strong></h3><pre><code><code>CREATE TABLE events_distributed AS events
ENGINE = Distributed('default', currentDatabase(), events,
                     cityHash64(tenant_id));</code></code></pre><p>Si repartes con <code>rand()</code>, los datos quedan perfectamente equilibrados y <strong>cada agregaci&#243;n por tenant tiene que cruzar la red</strong>. Si repartes con el hash de la columna por la que agrupas, cada shard puede resolver sus grupos en local. El precio es el desequilibrio: un tenant gigante satura su shard. Elige sabiendo lo que pagas.</p><h3><strong>D&#243;nde se ejecuta cada parte de la consulta</strong></h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!y7g1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7238eba-bc02-4647-b00c-f8687f4d529b_1456x700.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!y7g1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7238eba-bc02-4647-b00c-f8687f4d529b_1456x700.png 424w, https://substackcdn.com/image/fetch/$s_!y7g1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7238eba-bc02-4647-b00c-f8687f4d529b_1456x700.png 848w, https://substackcdn.com/image/fetch/$s_!y7g1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7238eba-bc02-4647-b00c-f8687f4d529b_1456x700.png 1272w, https://substackcdn.com/image/fetch/$s_!y7g1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7238eba-bc02-4647-b00c-f8687f4d529b_1456x700.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!y7g1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7238eba-bc02-4647-b00c-f8687f4d529b_1456x700.png" width="1456" height="700" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b7238eba-bc02-4647-b00c-f8687f4d529b_1456x700.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:700,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:129820,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/219626269?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7238eba-bc02-4647-b00c-f8687f4d529b_1456x700.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!y7g1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7238eba-bc02-4647-b00c-f8687f4d529b_1456x700.png 424w, https://substackcdn.com/image/fetch/$s_!y7g1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7238eba-bc02-4647-b00c-f8687f4d529b_1456x700.png 848w, https://substackcdn.com/image/fetch/$s_!y7g1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7238eba-bc02-4647-b00c-f8687f4d529b_1456x700.png 1272w, https://substackcdn.com/image/fetch/$s_!y7g1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7238eba-bc02-4647-b00c-f8687f4d529b_1456x700.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">El merge final ocurre en un solo nodo. Lo dem&#225;s viaja por la red.</figcaption></figure></div><p>El iniciador reparte la consulta a los shards, cada shard agrega lo suyo sobre su tabla local, y el merge final ocurre en un &#250;nico nodo. De ah&#237; se derivan tres reglas:</p><ul><li><p>El nodo iniciador no deber&#237;a ser tambi&#233;n un nodo de ingesta pesada.</p></li><li><p>Inserta en la tabla local de cada shard cuando puedas, en vez de en la <code>Distributed</code>.</p></li><li><p>Una subconsulta en un <code>IN</code> o un <code>JOIN</code> se resuelve <strong>en cada shard por separado</strong>, lo que multiplica el trabajo y puede dar resultados incompletos. Para eso est&#225;n <code>GLOBAL IN</code> y <code>GLOBAL JOIN</code>, que la resuelven una vez en el iniciador y reparten el resultado.</p></li></ul><pre><code><code>SELECT count()
FROM clusterAllReplicas('default', currentDatabase(), events)
WHERE user_id GLOBAL IN (SELECT id FROM estados);</code></code></pre><div><hr></div><h2><strong>9. Seguridad, cuotas y multi-tenancy</strong></h2><p>Esta es la secci&#243;n que falta en casi todas las gu&#237;as de ClickHouse, y la que m&#225;s caro sale olvidar. Una base anal&#237;tica acaba siempre con herramientas de BI, cuadernos de datos y gente del negocio conectada. Si solo tienes el usuario <code>default</code>, lo que tienes es un incidente pendiente de fecha.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!zkYR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0ef99e8-8e04-42ec-8af2-8944ca0548b0_1456x640.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!zkYR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0ef99e8-8e04-42ec-8af2-8944ca0548b0_1456x640.png 424w, https://substackcdn.com/image/fetch/$s_!zkYR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0ef99e8-8e04-42ec-8af2-8944ca0548b0_1456x640.png 848w, https://substackcdn.com/image/fetch/$s_!zkYR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0ef99e8-8e04-42ec-8af2-8944ca0548b0_1456x640.png 1272w, https://substackcdn.com/image/fetch/$s_!zkYR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0ef99e8-8e04-42ec-8af2-8944ca0548b0_1456x640.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!zkYR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0ef99e8-8e04-42ec-8af2-8944ca0548b0_1456x640.png" width="1456" height="640" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e0ef99e8-8e04-42ec-8af2-8944ca0548b0_1456x640.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:640,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:135483,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/219626269?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0ef99e8-8e04-42ec-8af2-8944ca0548b0_1456x640.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!zkYR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0ef99e8-8e04-42ec-8af2-8944ca0548b0_1456x640.png 424w, https://substackcdn.com/image/fetch/$s_!zkYR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0ef99e8-8e04-42ec-8af2-8944ca0548b0_1456x640.png 848w, https://substackcdn.com/image/fetch/$s_!zkYR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0ef99e8-8e04-42ec-8af2-8944ca0548b0_1456x640.png 1272w, https://substackcdn.com/image/fetch/$s_!zkYR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0ef99e8-8e04-42ec-8af2-8944ca0548b0_1456x640.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Una limita la consulta, otra el consumo, otra las filas. Hacen falta las tres.</figcaption></figure></div><p>Son tres capas distintas y ninguna sustituye a las otras.</p><p><strong>El perfil de ajustes</strong> limita cada consulta individual:</p><pre><code><code>CREATE SETTINGS PROFILE bi_readonly SETTINGS
    max_execution_time = 30,
    max_memory_usage = 4000000000,
    max_rows_to_read = 500000000,
    max_result_rows = 100000,
    readonly = 1;

CREATE USER bi IDENTIFIED WITH sha256_password BY 'cambia-esto'
    SETTINGS PROFILE bi_readonly;

GRANT SELECT ON default.events TO bi;</code></code></pre><p><strong>La cuota</strong> limita el consumo acumulado en una ventana de tiempo, que es lo que el perfil no puede ver. Mil consultas de treinta segundos cada una pasan todos los l&#237;mites por consulta y aun as&#237; tumban el cl&#250;ster:</p><pre><code><code>CREATE QUOTA bi_hora
    FOR INTERVAL 1 HOUR MAX queries = 1000, read_rows = 5000000000
    TO bi;</code></code></pre><p><strong>La pol&#237;tica de filas</strong> decide qu&#233; filas existen para qui&#233;n. Se aplica siempre, tambi&#233;n en <code>SELECT *</code>, y es la &#250;nica forma seria de hacer multi-tenancy sobre una tabla compartida:</p><pre><code><code>CREATE ROW POLICY solo_mi_tenant ON default.events
    USING tenant_id = 5
    TO bi;</code></code></pre><p>Un tenant que puede leer las filas de otro no es un bug de la aplicaci&#243;n: es un fallo de dise&#241;o del esquema. Y revisa lo que hay puesto de verdad, que la deriva de configuraci&#243;n es real:</p><pre><code><code>SELECT short_name, database, table, select_filter, is_restrictive, apply_to_list
FROM system.row_policies
WHERE table = 'events';</code></code></pre><p>Tres reglas m&#225;s: el usuario <code>default</code> sin contrase&#241;a no sale del entorno de desarrollo, cada herramienta externa tiene su propio usuario (si todas comparten uno, no puedes revocar ni medir nada), y los permisos se dan sobre tablas concretas, nunca <code>GRANT ALL ON *.*</code> &#8220;mientras probamos&#8221;.</p><div><hr></div><h2><strong>10. Migraciones de esquema y backups que restauran</strong></h2><h3><strong>No todos los ALTER cuestan lo mismo</strong></h3><p>A&#241;adir una columna es una operaci&#243;n de metadatos: instant&#225;nea, sin reescribir nada.</p><pre><code><code>ALTER TABLE events ADD COLUMN pais LowCardinality(String) DEFAULT '';</code></code></pre><p>Cambiar el tipo de una columna es una <strong>mutaci&#243;n</strong>: reescribe todas las partes afectadas.</p><pre><code><code>ALTER TABLE events MODIFY COLUMN duration_ms UInt64
SETTINGS mutations_sync = 2;</code></code></pre><p>En una tabla de mil millones de filas, lo primero tarda milisegundos y lo segundo puede tardar horas y saturar el pool de merges. Antes de lanzar un <code>MODIFY COLUMN</code> en producci&#243;n, pru&#233;balo sobre una copia de una partici&#243;n y mide. Y usa <code>ON CLUSTER</code> para la DDL distribuida, verificando despu&#233;s <code>system.distributed_ddl_queue</code>, porque un DDL que falla en un solo nodo deja el cl&#250;ster inconsistente en silencio.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Si necesitas tocar un l&#237;mite solo en una tabla, no cambies el servidor entero:</p><pre><code><code>ALTER TABLE events MODIFY SETTING parts_to_throw_insert = 3000;</code></code></pre><h3><strong>Un backup que no has restaurado no es un backup</strong></h3><p><code>BACKUP</code> necesita un disco declarado expl&#237;citamente como permitido; sin esa configuraci&#243;n el comando falla, y descubrirlo el d&#237;a del incidente es tarde:</p><pre><code><code>&lt;!-- /etc/clickhouse-server/config.d/backups.xml --&gt;
&lt;clickhouse&gt;
    &lt;storage_configuration&gt;
        &lt;disks&gt;
            &lt;backups&gt;
                &lt;type&gt;local&lt;/type&gt;
                &lt;path&gt;/var/lib/clickhouse/backups/&lt;/path&gt;
            &lt;/backups&gt;
        &lt;/disks&gt;
    &lt;/storage_configuration&gt;
    &lt;backups&gt;
        &lt;allowed_disk&gt;backups&lt;/allowed_disk&gt;
    &lt;/backups&gt;
&lt;/clickhouse&gt;</code></code></pre><p>Con eso, el ciclo completo funciona, y es exactamente el que deber&#237;as ensayar en un entorno de pruebas cada trimestre:</p><pre><code><code>BACKUP TABLE estados TO Disk('backups', 'estados.zip');

DROP TABLE estados SYNC;

RESTORE TABLE estados FROM Disk('backups', 'estados.zip');</code></code></pre><p>En producci&#243;n, cambia <code>Disk('backups', ...)</code> por <code>S3(...)</code> y a&#241;ade <code>ASYNC</code> para no bloquear la sesi&#243;n. Lo que no cambia es la regla: si nunca has ejecutado el <code>RESTORE</code>, no tienes copia de seguridad, tienes una carpeta.</p><div><hr></div><h2><strong>11. Observabilidad: las consultas que debes tener a mano</strong></h2><p>La m&#233;trica de salud n&#250;mero uno es el n&#250;mero de partes activas:</p><pre><code><code>SELECT
    database,
    table,
    count() AS partes,
    sum(rows) AS filas,
    formatReadableSize(sum(bytes_on_disk)) AS tamano
FROM system.parts
WHERE active AND database = currentDatabase()
GROUP BY database, table
ORDER BY partes DESC;</code></code></pre><p>Las consultas m&#225;s caras, agrupadas por forma y no por texto literal, que es lo que hace &#250;til a <code>normalized_query_hash</code>:</p><pre><code><code>SELECT
    normalized_query_hash,
    count() AS ejecuciones,
    formatReadableSize(avg(memory_usage)) AS memoria_media,
    round(avg(query_duration_ms)) AS ms_medios,
    formatReadableQuantity(avg(read_rows)) AS filas_leidas
FROM system.query_log
WHERE type = 'QueryFinish' AND event_time &gt;= now() - INTERVAL 1 DAY
GROUP BY normalized_query_hash
ORDER BY avg(query_duration_ms) DESC
LIMIT 20;</code></code></pre><p>Y la consulta que convierte &#8220;me parece que va lento&#8221; en un n&#250;mero: cu&#225;ntas marcas y cu&#225;ntas filas toc&#243; de verdad una consulta concreta.</p><pre><code><code>SELECT
    ProfileEvents['SelectedMarks']    AS marcas,
    ProfileEvents['SelectedRanges']   AS rangos,
    formatReadableQuantity(read_rows) AS filas_leidas,
    formatReadableSize(read_bytes)    AS bytes_leidos
FROM system.query_log
WHERE type = 'QueryFinish'
  AND query LIKE '%FROM events WHERE tenant_id = 5%'
  AND event_time &gt;= now() - INTERVAL 10 MINUTE
ORDER BY event_time DESC
LIMIT 1;</code></code></pre><p>Esta es, de lejos, la herramienta m&#225;s infrautilizada de ClickHouse. Todas las cifras de este art&#237;culo salen de ah&#237;.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p><strong>Y una advertencia sobre el propio </strong><code>query_log</code>: en la imagen oficial se crea sin <code>TTL</code>. Crece hasta que se llena el disco, y entonces pierdes a la vez la base de datos y el hist&#243;rico que te habr&#237;a dicho por qu&#233;. Compru&#233;balo y ponle fecha de caducidad:</p><pre><code><code>SELECT engine_full FROM system.tables
WHERE database = 'system' AND name = 'query_log';</code></code></pre><p>El resto del arsenal: <code>system.merges</code> y <code>system.mutations</code> para el almacenamiento, <code>system.replication_queue</code> y <code>system.replicas</code> para el retraso de replicaci&#243;n, <code>system.kafka_consumers</code> si ingieres de Kafka, <code>system.errors</code> para lo que realmente est&#225; fallando, y <code>system.asynchronous_metrics</code> para alimentar Prometheus y Grafana.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Alerta sobre cinco cosas y dormir&#225;s tranquilo: partes activas, retraso de replicaci&#243;n, mutaciones sin terminar, memoria del servidor y espacio en disco.</p><p>En el host, lo de siempre: NVMe para datos calientes, almacenamiento por niveles para el resto, swap desactivado, <code>max_server_memory_usage</code> en torno al 80% de la RAM, l&#237;mite de ficheros abiertos alto y transparent huge pages desactivadas.</p><div><hr></div><h2><strong>12. Antipatrones: lo que nunca debes hacer</strong></h2><ul><li><p>Usar ClickHouse como base OLTP: no hay transacciones multi-sentencia, ni actualizaciones puntuales r&#225;pidas, ni unicidad garantizada.</p></li><li><p>Usarlo como key-value store para leer una fila por clave. Para eso est&#225; Redis.</p></li><li><p>Insertar fila por fila sin <code>async_insert</code>.</p></li><li><p>Hacer <code>SELECT</code> a una tabla con <code>ENGINE = Kafka</code>.</p></li><li><p>Ejecutar <code>OPTIMIZE FINAL</code> en un cron.</p></li><li><p>Dejar <code>SELECT *</code> en c&#243;digo de aplicaci&#243;n.</p></li><li><p>Particionar por una columna de alta cardinalidad.</p></li><li><p>Confiar en que <code>ReplacingMergeTree</code> deduplica al instante.</p></li><li><p>Permitir consultas sin perfil de ajustes ni cuota.</p></li><li><p>Dar acceso a herramientas externas con el usuario <code>default</code>.</p></li><li><p>Guardar <code>DateTime</code> sin zona horaria expl&#237;cita.</p></li><li><p>Dejar <code>system.query_log</code> sin <code>TTL</code>.</p></li><li><p>Tener un solo nodo, sin r&#233;plicas, para datos que no puedes perder.</p></li><li><p>Llamar backup a algo que nunca has restaurado.</p></li><li><p>Asumir que la clave primaria es &#250;nica. En ClickHouse no lo es.</p></li></ul><div><hr></div><h2><strong>13. Preguntas frecuentes</strong></h2><h3><strong>&#191;Sirve ClickHouse como base de datos transaccional?</strong></h3><p>No. ClickHouse es una base anal&#237;tica (OLAP) orientada a columnas. No tiene transacciones multi-sentencia, las actualizaciones por fila son mutaciones as&#237;ncronas que reescriben partes enteras, y la clave primaria no impone unicidad. Para OLTP, usa PostgreSQL o MySQL y replica hacia ClickHouse lo que necesites analizar.</p><h3><strong>&#191;Cada cu&#225;nto debo insertar en ClickHouse?</strong></h3><p>Como mucho una vez por segundo y por tabla desde cada productor, con lotes de 10.000 filas o m&#225;s. Si tu arquitectura no te deja agrupar, activa <code>async_insert = 1</code> y deja que el servidor lo haga por ti.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h3><strong>&#191;Qu&#233; significa el error TOO_MANY_PARTS?</strong></h3><p>Que est&#225;s creando partes m&#225;s r&#225;pido de lo que el motor puede fusionarlas. En las versiones actuales, ClickHouse empieza a retrasar los <code>INSERT</code> a partir de 1.000 partes activas por partici&#243;n y los rechaza a partir de 3.000. Casi siempre la causa es ingesta fila por fila o una partici&#243;n de cardinalidad demasiado alta. La soluci&#243;n es arreglar la ingesta, no subir el l&#237;mite.</p><h3><strong>&#191;Cu&#225;ntas columnas debe tener la ORDER BY?</strong></h3><p>Entre dos y cuatro, ordenadas de menor a mayor cardinalidad, empezando por lo que siempre filtras. M&#225;s columnas encarecen los merges sin mejorar la poda.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h3><strong>&#191;Cu&#225;ndo uso una vista materializada y cu&#225;ndo una proyecci&#243;n?</strong></h3><p>Proyecci&#243;n si necesitas otra <code>ORDER BY</code> sobre los mismos datos y quieres que el motor la mantenga solo. Vista materializada si lo que repites son agregaciones y quieres preagregar en el momento de la ingesta. Si el patr&#243;n es completamente distinto, una tabla aparte.</p><h3><strong>&#191;Por qu&#233; mi consulta con FINAL va lenta?</strong></h3><p>Porque <code>FINAL</code> fusiona las partes en tiempo de consulta para darte la &#250;ltima versi&#243;n de cada fila. Sustit&#250;yelo por una agregaci&#243;n expl&#237;cita con <code>argMax</code> y <code>GROUP BY</code>, cuidando de que los alias no se llamen igual que las columnas agregadas.</p><h3><strong>&#191;C&#243;mo a&#237;slo a varios clientes en la misma tabla de ClickHouse?</strong></h3><p>Con una pol&#237;tica de filas (<code>CREATE ROW POLICY ... USING tenant_id = ...</code>) por usuario, adem&#225;s de un perfil de ajustes y una cuota. Filtrar por tenant solo en la aplicaci&#243;n no es aislamiento: cualquier consulta directa se lo salta.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h3><strong>&#191;C&#243;mo leo de Kafka sin perder mensajes?</strong></h3><p>Con tres objetos: una tabla <code>ENGINE = Kafka</code>, una vista materializada y una tabla <code>MergeTree</code> de destino. Nunca consultes directamente la tabla Kafka, porque cada lectura consume del topic.</p><h3><strong>&#191;ClickHouse necesita &#237;ndices como PostgreSQL?</strong></h3><p>No en el mismo sentido. El &#237;ndice primario es disperso y se deriva de la <code>ORDER BY</code>; no hay &#237;ndices B-tree por fila. Los &#237;ndices de salto son un complemento para columnas fuera de la clave, y solo valen la pena si son muy selectivos.</p><div><hr></div><h2><strong>14. La lista, en una pantalla</strong></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!foI5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38c931cc-91e5-404e-92d1-f6fa5465aa83_1456x1026.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!foI5!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38c931cc-91e5-404e-92d1-f6fa5465aa83_1456x1026.png 424w, https://substackcdn.com/image/fetch/$s_!foI5!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38c931cc-91e5-404e-92d1-f6fa5465aa83_1456x1026.png 848w, https://substackcdn.com/image/fetch/$s_!foI5!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38c931cc-91e5-404e-92d1-f6fa5465aa83_1456x1026.png 1272w, https://substackcdn.com/image/fetch/$s_!foI5!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38c931cc-91e5-404e-92d1-f6fa5465aa83_1456x1026.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!foI5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38c931cc-91e5-404e-92d1-f6fa5465aa83_1456x1026.png" width="1456" height="1026" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/38c931cc-91e5-404e-92d1-f6fa5465aa83_1456x1026.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1026,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:203721,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/219626269?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38c931cc-91e5-404e-92d1-f6fa5465aa83_1456x1026.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!foI5!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38c931cc-91e5-404e-92d1-f6fa5465aa83_1456x1026.png 424w, https://substackcdn.com/image/fetch/$s_!foI5!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38c931cc-91e5-404e-92d1-f6fa5465aa83_1456x1026.png 848w, https://substackcdn.com/image/fetch/$s_!foI5!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38c931cc-91e5-404e-92d1-f6fa5465aa83_1456x1026.png 1272w, https://substackcdn.com/image/fetch/$s_!foI5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38c931cc-91e5-404e-92d1-f6fa5465aa83_1456x1026.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Trece requisitos. Si falta uno, se nota el d&#237;a del incidente.</figcaption></figure></div><h2><strong>C&#243;mo reproducir todo esto en tu m&#225;quina</strong></h2><p>Todo el SQL de este art&#237;culo &#8212;56 bloques, incluidas las mediciones, los backups y la seguridad&#8212; se ejecut&#243; contra ClickHouse 26.9 antes de publicarlo. Puedes repetirlo en cinco minutos:</p><pre><code><code>docker run -d --name ch-blog \
  --ulimit nofile=262144:262144 \
  clickhouse/clickhouse-server:latest

docker exec -it ch-blog clickhouse-client</code></code></pre><p>Crea la tabla <code>events</code> de la secci&#243;n 1, c&#225;rgala con datos sint&#233;ticos y mide t&#250; mismo:</p><pre><code><code>INSERT INTO events
SELECT
    number % 50                                   AS tenant_id,
    ['click','view','purchase'][number % 3 + 1]   AS event_type,
    number % 100000                               AS user_id,
    now() - toIntervalSecond(number % 5184000)    AS event_time,
    number % 900                                  AS duration_ms,
    toDecimal64(number % 100, 4)                  AS revenue,
    repeat('x', 40)                               AS payload
FROM numbers(2000000);</code></code></pre><p>Dos millones de filas en unos segundos, y ya puedes comparar planes con <code>EXPLAIN indexes = 1</code> y marcas le&#237;das en <code>system.query_log</code>. Medir en tu propio hardware, con tu propio esquema, vale m&#225;s que cualquier lista de buenas pr&#225;cticas. Incluida esta.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Si cumples esta gu&#237;a, ClickHouse te devuelve agregaciones sobre miles de millones de filas en menos de un segundo. Si no, vas a culpar a la base de datos de algo que est&#225; escrito en tu <code>CREATE TABLE</code>.</p><p>La documentaci&#243;n oficial de <a href="https://clickhouse.com/docs">ClickHouse</a> es excelente y conviene tenerla cerca, sobre todo las p&#225;ginas de <a href="https://clickhouse.com/docs/en/engines/table-engines/mergetree-family/mergetree">MergeTree</a>, <a href="https://clickhouse.com/docs/en/materialized-view">vistas materializadas</a> y <a href="https://clickhouse.com/docs/en/operations/access-rights">control de acceso</a>.</p><p><em>&#191;Te has peleado con alguno de estos puntos en producci&#243;n? Cu&#233;ntamelo en los comentarios: la lista est&#225; viva, y hay errores que solo se aprenden a las tres de la ma&#241;ana.</em></p>]]></content:encoded></item><item><title><![CDATA[ClickHouse para finanzas: el cierre fiscal con 300 millones de transacciones al mes]]></title><description><![CDATA[Todo el SQL corre en ClickHouse 26.9, PostgreSQL 17 y la extensi&#243;n pg_clickhouse sobre PostgreSQL 18, y las capturas son de ejecuciones reales. El procedimiento incluye ejemplos.]]></description><link>https://blog.carrillo.app/p/clickhouse-para-finanzas-el-cierre</link><guid isPermaLink="false">https://blog.carrillo.app/p/clickhouse-para-finanzas-el-cierre</guid><dc:creator><![CDATA[José Carrillo]]></dc:creator><pubDate>Tue, 06 Oct 2026 14:07:15 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!taCO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F336b1a02-92e0-487a-9c33-72ff73d268e3_1200x630.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!taCO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F336b1a02-92e0-487a-9c33-72ff73d268e3_1200x630.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!taCO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F336b1a02-92e0-487a-9c33-72ff73d268e3_1200x630.png 424w, https://substackcdn.com/image/fetch/$s_!taCO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F336b1a02-92e0-487a-9c33-72ff73d268e3_1200x630.png 848w, https://substackcdn.com/image/fetch/$s_!taCO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F336b1a02-92e0-487a-9c33-72ff73d268e3_1200x630.png 1272w, https://substackcdn.com/image/fetch/$s_!taCO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F336b1a02-92e0-487a-9c33-72ff73d268e3_1200x630.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!taCO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F336b1a02-92e0-487a-9c33-72ff73d268e3_1200x630.png" width="728" height="382.2" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/336b1a02-92e0-487a-9c33-72ff73d268e3_1200x630.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;normal&quot;,&quot;height&quot;:630,&quot;width&quot;:1200,&quot;resizeWidth&quot;:728,&quot;bytes&quot;:56321,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/218934197?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F336b1a02-92e0-487a-9c33-72ff73d268e3_1200x630.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!taCO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F336b1a02-92e0-487a-9c33-72ff73d268e3_1200x630.png 424w, https://substackcdn.com/image/fetch/$s_!taCO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F336b1a02-92e0-487a-9c33-72ff73d268e3_1200x630.png 848w, https://substackcdn.com/image/fetch/$s_!taCO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F336b1a02-92e0-487a-9c33-72ff73d268e3_1200x630.png 1272w, https://substackcdn.com/image/fetch/$s_!taCO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F336b1a02-92e0-487a-9c33-72ff73d268e3_1200x630.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">ClickHouse es el motor ideal en el mundo de las finanzas </figcaption></figure></div><p>Registrar 300 millones de transacciones al mes no es lo dif&#237;cil; un Postgres bien afinado lo aguanta. Lo dif&#237;cil llega el 31 de diciembre, cuando alguien pide el balance de comprobaci&#243;n de un a&#241;o con 3600 millones de transacciones y m&#225;s de 7200 millones de l&#237;neas de asiento, mientras siguen entrando pagos como cualquier otro d&#237;a.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Aqu&#237; cuento c&#243;mo lo resolv&#237; con ClickHouse Cloud, con el SQL que prob&#233;.</p><p>Todo el SQL corre en ClickHouse 26.9, PostgreSQL 17 y la extensi&#243;n <code>pg_clickhouse</code> sobre PostgreSQL 18, y las capturas son de ejecuciones reales. El procedimiento incluye c&#243;mo responder a los fallos del CDC (ClickPipes), que reproduje uno por uno.</p><h2><strong>1. El problema de escala</strong></h2><p>Trescientos millones de transacciones al mes son unas 115 por segundo. El problema es lo que se acumula durante el a&#241;o y lo que hay que leer para cerrarlo.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!X2o4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6264164-c1a7-4be9-89f5-5b2421dd90c9_1456x693.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!X2o4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6264164-c1a7-4be9-89f5-5b2421dd90c9_1456x693.png 424w, https://substackcdn.com/image/fetch/$s_!X2o4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6264164-c1a7-4be9-89f5-5b2421dd90c9_1456x693.png 848w, https://substackcdn.com/image/fetch/$s_!X2o4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6264164-c1a7-4be9-89f5-5b2421dd90c9_1456x693.png 1272w, https://substackcdn.com/image/fetch/$s_!X2o4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6264164-c1a7-4be9-89f5-5b2421dd90c9_1456x693.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!X2o4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6264164-c1a7-4be9-89f5-5b2421dd90c9_1456x693.png" width="1456" height="693" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d6264164-c1a7-4be9-89f5-5b2421dd90c9_1456x693.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:693,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:68605,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/218934197?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6264164-c1a7-4be9-89f5-5b2421dd90c9_1456x693.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!X2o4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6264164-c1a7-4be9-89f5-5b2421dd90c9_1456x693.png 424w, https://substackcdn.com/image/fetch/$s_!X2o4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6264164-c1a7-4be9-89f5-5b2421dd90c9_1456x693.png 848w, https://substackcdn.com/image/fetch/$s_!X2o4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6264164-c1a7-4be9-89f5-5b2421dd90c9_1456x693.png 1272w, https://substackcdn.com/image/fetch/$s_!X2o4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6264164-c1a7-4be9-89f5-5b2421dd90c9_1456x693.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Imagen 1. Las cifras que importan para dimensionar el cierre.</figcaption></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!1ysz!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30320c6c-b548-4fb1-9263-3e367fb9104f_1456x808.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!1ysz!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30320c6c-b548-4fb1-9263-3e367fb9104f_1456x808.png 424w, https://substackcdn.com/image/fetch/$s_!1ysz!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30320c6c-b548-4fb1-9263-3e367fb9104f_1456x808.png 848w, https://substackcdn.com/image/fetch/$s_!1ysz!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30320c6c-b548-4fb1-9263-3e367fb9104f_1456x808.png 1272w, https://substackcdn.com/image/fetch/$s_!1ysz!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30320c6c-b548-4fb1-9263-3e367fb9104f_1456x808.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!1ysz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30320c6c-b548-4fb1-9263-3e367fb9104f_1456x808.png" width="1456" height="808" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/30320c6c-b548-4fb1-9263-3e367fb9104f_1456x808.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:808,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:42834,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/218934197?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30320c6c-b548-4fb1-9263-3e367fb9104f_1456x808.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!1ysz!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30320c6c-b548-4fb1-9263-3e367fb9104f_1456x808.png 424w, https://substackcdn.com/image/fetch/$s_!1ysz!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30320c6c-b548-4fb1-9263-3e367fb9104f_1456x808.png 848w, https://substackcdn.com/image/fetch/$s_!1ysz!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30320c6c-b548-4fb1-9263-3e367fb9104f_1456x808.png 1272w, https://substackcdn.com/image/fetch/$s_!1ysz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30320c6c-b548-4fb1-9263-3e367fb9104f_1456x808.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Imagen 2. Cada transacci&#243;n genera al menos dos l&#237;neas de asiento por la partida doble.</figcaption></figure></div><p>El balance de comprobaci&#243;n agrega todas esas l&#237;neas por cuenta. La conciliaci&#243;n compara miles de millones de registros con los extractos de bancos y pasarelas. La diferencia en cambio reval&#250;a cada saldo monetario en moneda extranjera. Y la auditor&#237;a pide rastrear cualquier saldo hasta su transacci&#243;n de origen.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Una base de datos orientada a filas, como PostgreSQL, MySQL u Oracle, lee todas las columnas de cada fila aunque la consulta solo necesite tres. De ah&#237; que los cierres tradicionales vivan de procesos nocturnos, tablas de resumen mantenidas a mano y equipos trabajando el fin de semana de fin de a&#241;o. ClickHouse es columnar: lee solo las columnas que pide la consulta, las comprime muy bien (cuentas, monedas y centros de costo se repiten much&#237;simo) y agrega en paralelo.</p><h2><strong>2. La arquitectura</strong></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Fm7W!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99cf8da6-ca02-4759-8470-136c343077f5_1456x800.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Fm7W!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99cf8da6-ca02-4759-8470-136c343077f5_1456x800.png 424w, https://substackcdn.com/image/fetch/$s_!Fm7W!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99cf8da6-ca02-4759-8470-136c343077f5_1456x800.png 848w, https://substackcdn.com/image/fetch/$s_!Fm7W!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99cf8da6-ca02-4759-8470-136c343077f5_1456x800.png 1272w, https://substackcdn.com/image/fetch/$s_!Fm7W!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99cf8da6-ca02-4759-8470-136c343077f5_1456x800.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!Fm7W!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99cf8da6-ca02-4759-8470-136c343077f5_1456x800.png" width="1456" height="800" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/99cf8da6-ca02-4759-8470-136c343077f5_1456x800.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:800,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:145693,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/218934197?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99cf8da6-ca02-4759-8470-136c343077f5_1456x800.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Fm7W!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99cf8da6-ca02-4759-8470-136c343077f5_1456x800.png 424w, https://substackcdn.com/image/fetch/$s_!Fm7W!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99cf8da6-ca02-4759-8470-136c343077f5_1456x800.png 848w, https://substackcdn.com/image/fetch/$s_!Fm7W!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99cf8da6-ca02-4759-8470-136c343077f5_1456x800.png 1272w, https://substackcdn.com/image/fetch/$s_!Fm7W!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99cf8da6-ca02-4759-8470-136c343077f5_1456x800.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Imagen 3. Postgres registra las transacciones; ClickHouse guarda el hist&#243;rico y hace el cierre.</figcaption></figure></div><p>Postgres registra cada transacci&#243;n con garant&#237;as ACID: valida el saldo disponible, bloquea la cuenta, aplica la clave de idempotencia y confirma. El CDC (captura de cambios) lleva a ClickHouse cada cambio que hace <code>COMMIT</code>, en torno a un minuto con la configuraci&#243;n por defecto. ClickHouse guarda el hist&#243;rico completo, genera los asientos, mantiene los saldos y responde las consultas del cierre, la conciliaci&#243;n y los reportes.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>ClickHouse no reemplaza al motor transaccional: no tiene transacciones de varias sentencias, ni claves for&#225;neas, ni bloqueos de fila. Para leer un saldo, validarlo y descontarlo est&#225; Postgres. ClickHouse entra cuando hay que agregar miles de millones de filas en segundos.</p><h2><strong>3. El modelo de datos</strong></h2><p>Todo vive en una base de datos llamada <code>finance</code>. Los identificadores y comentarios del c&#243;digo est&#225;n en ingl&#233;s, que es lo habitual en equipos mixtos.</p><h3><strong>3.1 El dinero como enteros en unidades menores</strong></h3><p>Las APIs de pago modernas representan cada importe como un entero en la unidad m&#225;s peque&#241;a de la moneda, junto con su c&#243;digo ISO 4217. Diez d&#243;lares son <code>1000</code>, porque el d&#243;lar tiene dos decimales. Uso la misma convenci&#243;n: los enteros no tienen errores de redondeo, se suman y comparan sin sorpresas, y quedan alineados con las pasarelas de pago.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Donde m&#225;s veo errores es en los decimales de cada moneda. Seg&#250;n la lista oficial de ISO 4217, el peso colombiano tiene dos, igual que el d&#243;lar. O sea que <strong>1 234 567 pesos se guardan como </strong><code>123456700</code>. Si guardas <code>1234567</code> creyendo que el peso no tiene decimales, cualquier integraci&#243;n con una pasarela cobra cien veces menos.</p><p>El yen y el peso chileno no tienen decimales, y el dinar kuwait&#237; tiene tres. Por eso el n&#250;mero de decimales nunca va como un <code>/100</code> fijo en el c&#243;digo: se lee de una tabla de referencia.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!IWjP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfc9cbbd-69ab-4d03-be82-ebf320870357_1456x702.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!IWjP!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfc9cbbd-69ab-4d03-be82-ebf320870357_1456x702.png 424w, https://substackcdn.com/image/fetch/$s_!IWjP!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfc9cbbd-69ab-4d03-be82-ebf320870357_1456x702.png 848w, https://substackcdn.com/image/fetch/$s_!IWjP!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfc9cbbd-69ab-4d03-be82-ebf320870357_1456x702.png 1272w, https://substackcdn.com/image/fetch/$s_!IWjP!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfc9cbbd-69ab-4d03-be82-ebf320870357_1456x702.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!IWjP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfc9cbbd-69ab-4d03-be82-ebf320870357_1456x702.png" width="1456" height="702" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bfc9cbbd-69ab-4d03-be82-ebf320870357_1456x702.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:702,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:84017,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/218934197?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfc9cbbd-69ab-4d03-be82-ebf320870357_1456x702.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!IWjP!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfc9cbbd-69ab-4d03-be82-ebf320870357_1456x702.png 424w, https://substackcdn.com/image/fetch/$s_!IWjP!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfc9cbbd-69ab-4d03-be82-ebf320870357_1456x702.png 848w, https://substackcdn.com/image/fetch/$s_!IWjP!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfc9cbbd-69ab-4d03-be82-ebf320870357_1456x702.png 1272w, https://substackcdn.com/image/fetch/$s_!IWjP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfc9cbbd-69ab-4d03-be82-ebf320870357_1456x702.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Imagen 4. Exponentes de la lista oficial ISO 4217 vigente al 17 de septiembre de 2026.</figcaption></figure></div><p>Esa tabla vive en Postgres con el resto de los datos de referencia:</p><pre><code><code>-- PostgreSQL: ISO 4217 reference data
CREATE TABLE currencies (
    code         char(3)  PRIMARY KEY,  -- alphabetic code
    numeric_code smallint NOT NULL,     -- numeric code
    minor_units  smallint NOT NULL      -- decimal places
);

INSERT INTO currencies VALUES
    ('COP', 170, 2), ('USD', 840, 2), ('EUR', 978, 2),
    ('JPY', 392, 0), ('CLP', 152, 0), ('KWD', 414, 3);</code></code></pre><p>ClickHouse la lee como un diccionario en memoria. Las credenciales de Postgres van en una <em>named collection</em> que crea un administrador una sola vez, y ninguna consulta posterior las repite:</p><pre><code><code>-- ClickHouse: created once by an administrator
CREATE NAMED COLLECTION pg_finance AS
    host = 'pg-finance.internal',
    port = 5432,
    user = 'clickhouse_reader',
    password = '***',
    database = 'accounting';

CREATE DATABASE IF NOT EXISTS finance;

CREATE DICTIONARY finance.currency_dict
(
    code        String,
    minor_units UInt8
)
PRIMARY KEY code
SOURCE(POSTGRESQL(NAME pg_finance TABLE 'currencies'))
LIFETIME(MIN 3600 MAX 7200)
LAYOUT(COMPLEX_KEY_HASHED());</code></code></pre><p>Las tasas de cambio s&#237; necesitan decimales y las guardo como <code>Decimal(18, 10)</code>. Para convertir entre monedas escrib&#237; una funci&#243;n que respeta los decimales de cada una, redondea una sola vez al final y falla si la moneda no existe en el diccionario. Esto &#250;ltimo importa: un <code>dictGet</code> sobre una clave ausente devuelve 0, que aqu&#237; significar&#237;a cero decimales, justo el error de cien veces.</p><pre><code><code>-- Converts an amount in minor units between currencies.
-- rate = units of to_ccy per one unit of from_ccy.
CREATE FUNCTION convert_minor AS
    (amount_minor, from_ccy, to_ccy, rate) -&gt;
    toInt64(round(
        toDecimal256(amount_minor, 0) * rate
        * intExp10(dictGet('finance.currency_dict',
                           'minor_units', toString(to_ccy))
            + throwIf(NOT dictHas('finance.currency_dict',
                                  toString(to_ccy)),
                      'Unknown currency'))
        / intExp10(dictGet('finance.currency_dict',
                           'minor_units', toString(from_ccy))
            + throwIf(NOT dictHas('finance.currency_dict',
                                  toString(from_ccy)),
                      'Unknown currency')),
        0));</code></code></pre><p>Al probarla me encontr&#233; con tres comportamientos de ClickHouse que no esperaba:</p><ul><li><p>Multiplicar un <code>Int64</code> por un <code>Decimal64</code> da un <code>Decimal(18, 10)</code>, que solo tiene ocho d&#237;gitos enteros; con importes grandes la consulta falla con <em>Decimal math overflow</em>. En <code>Decimal128</code> y <code>Decimal256</code> pasa lo contrario: ClickHouse no comprueba el desbordamiento, lo dice su documentaci&#243;n y lo vi en una multiplicaci&#243;n de <code>Decimal128</code> que devolvi&#243; un n&#250;mero negativo sin error. La funci&#243;n trabaja en <code>Decimal256</code>, cuyo rango cubre cualquier <code>Int64</code> por cualquier tasa, y deja que el <code>toInt64</code> final falle si el resultado no cabe.</p></li><li><p><code>round</code> sobre un decimal redondea alej&#225;ndose de cero (2,5 pasa a 3 y &#8722;2,5 a &#8722;3), pero convertir a otra escala con <code>toDecimal128(x, 4)</code> trunca.</p></li><li><p><code>sum()</code> sobre <code>Int64</code> desborda sin error al pasar de 9,2 &#215; 10&#185;&#8312;, unos 92 000 billones de pesos. Ninguna entidad llega ah&#237; en un a&#241;o, y los controles del cierre lo detectar&#237;an.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!s2gG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2d4e205-2863-4346-92e9-fda1fc7e9a26_1456x505.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!s2gG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2d4e205-2863-4346-92e9-fda1fc7e9a26_1456x505.png 424w, https://substackcdn.com/image/fetch/$s_!s2gG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2d4e205-2863-4346-92e9-fda1fc7e9a26_1456x505.png 848w, https://substackcdn.com/image/fetch/$s_!s2gG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2d4e205-2863-4346-92e9-fda1fc7e9a26_1456x505.png 1272w, https://substackcdn.com/image/fetch/$s_!s2gG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2d4e205-2863-4346-92e9-fda1fc7e9a26_1456x505.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!s2gG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2d4e205-2863-4346-92e9-fda1fc7e9a26_1456x505.png" width="1456" height="505" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f2d4e205-2863-4346-92e9-fda1fc7e9a26_1456x505.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:505,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:47858,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/218934197?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2d4e205-2863-4346-92e9-fda1fc7e9a26_1456x505.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!s2gG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2d4e205-2863-4346-92e9-fda1fc7e9a26_1456x505.png 424w, https://substackcdn.com/image/fetch/$s_!s2gG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2d4e205-2863-4346-92e9-fda1fc7e9a26_1456x505.png 848w, https://substackcdn.com/image/fetch/$s_!s2gG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2d4e205-2863-4346-92e9-fda1fc7e9a26_1456x505.png 1272w, https://substackcdn.com/image/fetch/$s_!s2gG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2d4e205-2863-4346-92e9-fda1fc7e9a26_1456x505.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Imagen 5. Coma flotante frente a enteros en unidades menores.</figcaption></figure></div><h3><strong>3.2 La fuente: transacciones en Postgres</strong></h3><p>Postgres es la fuente de verdad. Cada transacci&#243;n guarda su importe en moneda de la transacci&#243;n y en moneda funcional (<code>amount_lcy_minor</code>, COP en los ejemplos), calculado con la tasa vigente en <code>event_ts</code>.</p><pre><code><code>-- PostgreSQL: monthly period status per entity
CREATE TABLE accounting_periods (
    entity_id  text    NOT NULL,
    period     integer NOT NULL,  -- e.g. 202612
    status     text    NOT NULL
        CHECK (status IN ('OPEN', 'CLOSING', 'CLOSED')),
    closed_by  text,
    closed_at  timestamptz,
    PRIMARY KEY (entity_id, period)
);

CREATE TABLE accounts (
    id                      bigint PRIMARY KEY,
    available_balance_minor bigint NOT NULL
);

CREATE TABLE transactions (
    tx_id            uuid    PRIMARY KEY,
    idempotency_key  uuid    NOT NULL UNIQUE,
    entity_id        text    NOT NULL,
    channel          text    NOT NULL,
    tx_type          text    NOT NULL,
    event_ts         timestamptz NOT NULL DEFAULT now(),
    accounting_date  date    NOT NULL,
    account_id       bigint  NOT NULL REFERENCES accounts (id),
    debit_account    bigint  NOT NULL,
    credit_account   bigint  NOT NULL,
    cost_center      text    NOT NULL,
    counterparty_id  bigint  NOT NULL,
    currency         char(3) NOT NULL
        CHECK (currency ~ '^[A-Z]{3}$'),
    amount_minor     bigint  NOT NULL
        CHECK (amount_minor &gt; 0),
    amount_lcy_minor bigint  NOT NULL
        CHECK (amount_lcy_minor &gt; 0),
    -- corrections are new rows with tx_type = 'REVERSAL'
    status           text    NOT NULL
        CHECK (status IN ('PENDING', 'CONFIRMED',
                          'REJECTED'))
);

-- Confirmed or rejected rows are final, only the status of
-- a pending row may change, and only OPEN periods accept
-- new or newly confirmed operations.
CREATE FUNCTION guard_transactions() RETURNS trigger
LANGUAGE plpgsql AS $$
BEGIN
    IF TG_OP IN ('UPDATE', 'DELETE')
       AND OLD.status IN ('CONFIRMED', 'REJECTED') THEN
        RAISE EXCEPTION 'transaction % is final', OLD.tx_id;
    END IF;
    IF TG_OP = 'DELETE' THEN
        RETURN OLD;
    END IF;
    IF TG_OP = 'UPDATE' AND
       (NEW.tx_id, NEW.entity_id, NEW.accounting_date,
        NEW.debit_account, NEW.credit_account, NEW.currency,
        NEW.amount_minor, NEW.amount_lcy_minor)
       IS DISTINCT FROM
       (OLD.tx_id, OLD.entity_id, OLD.accounting_date,
        OLD.debit_account, OLD.credit_account, OLD.currency,
        OLD.amount_minor, OLD.amount_lcy_minor) THEN
        RAISE EXCEPTION 'only the status can change';
    END IF;
    IF NEW.status &lt;&gt; 'REJECTED' AND NOT EXISTS (
        SELECT 1 FROM accounting_periods p
        WHERE p.entity_id = NEW.entity_id
          AND p.period = to_char(NEW.accounting_date,
                                 'YYYYMM')::integer
          AND p.status = 'OPEN') THEN
        RAISE EXCEPTION 'period of % is not open', NEW.tx_id;
    END IF;
    RETURN NEW;
END;
$$;

CREATE TRIGGER transactions_guard
    BEFORE INSERT OR UPDATE OR DELETE ON transactions
    FOR EACH ROW EXECUTE FUNCTION guard_transactions();</code></code></pre><p>Todo lo que sigue depende de este disparador. Una transacci&#243;n confirmada o rechazada no se modifica ni se borra; de una pendiente solo cambia el estado; y nada se confirma en un periodo que no est&#233; abierto. Las correcciones son transacciones de reversi&#243;n nuevas. Para que nadie lo salte, el rol de la aplicaci&#243;n no es due&#241;o de la tabla (no puede desactivar el disparador), no puede cambiar <code>session_replication_role</code> y no tiene permiso de <code>TRUNCATE</code>.</p><p>Este es el registro de un d&#233;bito con control de saldo:</p><pre><code><code>-- $1 account_id, $2 amount_minor (COP), $3 tx_id,
-- $4 idempotency_key, $5 entity_id, $6 accounting_date,
-- $7 debit_account, $8 credit_account, $9 counterparty_id
BEGIN;

SELECT available_balance_minor
FROM accounts
WHERE id = $1
FOR UPDATE;

-- the application checks available_balance_minor &gt;= $2

INSERT INTO transactions
    (tx_id, idempotency_key, entity_id, channel, tx_type,
     accounting_date, account_id, debit_account,
     credit_account, cost_center, counterparty_id,
     currency, amount_minor, amount_lcy_minor, status)
VALUES ($3, $4, $5, 'API', 'PAYMENT', $6, $1, $7, $8,
        'CC100', $9, 'COP', $2, $2, 'CONFIRMED');

UPDATE accounts
SET available_balance_minor = available_balance_minor - $2
WHERE id = $1;

COMMIT;</code></code></pre><p>Los comprobantes que genera el cierre (diferencia en cambio, cierre de resultados y apertura) se calculan en ClickHouse en una tabla de preparaci&#243;n, se aprueban en Postgres con sus totales a la vista y solo entonces se insertan en el libro. As&#237; tienen consecutivo, qui&#233;n los prepar&#243;, qui&#233;n los aprob&#243; y cu&#225;ndo, y el cierre comprueba que ninguna l&#237;nea manual entr&#243; sin aprobaci&#243;n:</p><pre><code><code>-- PostgreSQL: header of every manual voucher
CREATE TABLE journal_vouchers (
    tx_id        uuid    PRIMARY KEY,
    voucher_no   bigint  GENERATED ALWAYS AS IDENTITY UNIQUE,
    period       integer NOT NULL,
    kind         text    NOT NULL
        CHECK (kind IN ('ADJUSTMENT', 'CLOSING', 'OPENING')),
    description  text    NOT NULL,
    prepared_by  text    NOT NULL,
    approved_by  text,
    approved_at  timestamptz,
    CHECK (approved_by IS NULL OR approved_by &lt;&gt; prepared_by)
);</code></code></pre><p>Si la pasarela de pagos ya env&#237;a los importes en unidades menores, se guardan tal cual. Solo hay que normalizar la moneda a may&#250;sculas, convertir las marcas de tiempo en segundos Unix a <code>timestamptz</code> y guardar los identificadores de la pasarela como texto opaco.</p><h3><strong>3.3 La tabla de transacciones en ClickHouse</strong></h3><p>Las transacciones llegan por el CDC de ClickPipes, que escribe en una tabla <code>ReplacingMergeTree</code> con tres columnas propias. Yo creo la tabla vac&#237;a antes de agregarla a la replicaci&#243;n, con los tipos que corresponden al mapeo documentado de ClickPipes (<code>bigint</code> pasa a <code>Int64</code>, <code>uuid</code> a <code>UUID</code>, <code>text</code> a <code>String</code>, <code>date</code> a <code>Date</code> y <code>timestamptz</code> a <code>DateTime64(6)</code>), porque las vistas materializadas tienen que existir antes de la carga inicial; si no, el hist&#243;rico no pasa por ellas. ClickPipes solo rechaza una tabla existente si tiene datos. Despu&#233;s de agregarla, compara el resultado de <code>SHOW CREATE TABLE finance.transactions</code> con esta definici&#243;n.</p><pre><code><code>-- Destination of the ClickPipes CDC for public.transactions
-- (create it empty, then add the table to the pipe)
CREATE TABLE finance.transactions
(
    tx_id              UUID,
    idempotency_key    UUID,
    entity_id          String,
    channel            String,
    tx_type            String,
    event_ts           DateTime64(6),
    accounting_date    Date,
    account_id         Int64,
    debit_account      Int64,
    credit_account     Int64,
    cost_center        String,
    counterparty_id    Int64,
    currency           String,
    amount_minor       Int64,
    amount_lcy_minor   Int64,
    status             String,
    _peerdb_synced_at  DateTime64(9) DEFAULT now64(),
    _peerdb_is_deleted Int8,
    _peerdb_version    Int64
)
ENGINE = ReplacingMergeTree(_peerdb_version)
PARTITION BY toYYYYMM(accounting_date)
ORDER BY tx_id;</code></code></pre><p><code>ReplacingMergeTree</code> se queda con la versi&#243;n m&#225;s reciente de cada fila, pero lo hace durante las fusiones, cuando el motor decide. Toda consulta que necesite exactitud lee con <code>FINAL</code>. La clave de ordenaci&#243;n es la clave primaria de Postgres, la que ClickPipes usa por defecto, as&#237; que no hay que tocar la <code>REPLICA IDENTITY</code>. La partici&#243;n es el mes contable, y como el disparador impide cambiar la fecha contable, todas las versiones de una transacci&#243;n caen en la misma partici&#243;n. Eso permite leer con <code>do_not_merge_across_partitions_select_final = 1</code>, que abarata mucho el <code>FINAL</code>. La &#250;nica excepci&#243;n son los borrados de filas pendientes, que llegan sin fecha y no afectan a nada porque los filtros piden transacciones confirmadas. Las columnas <code>_peerdb_*</code> son de ClickPipes. Su documentaci&#243;n las declara <code>Int8</code> e <code>Int64</code>, y el c&#243;digo de PeerDB las crea como <code>UInt8</code> y <code>UInt64</code>; ninguna consulta de este art&#237;culo depende de esa diferencia.</p><p>Las fechas siguen ISO 8601: los instantes se guardan en UTC y la fecha contable se calcula en la zona horaria de la entidad. Un pago del <code>2026-10-01T02:00:00Z</code> es del 30 de septiembre en Bogot&#225;, y ese detalle mueve el cierre de mes:</p><pre><code><code>SELECT toDate(
    toDateTime64('2026-10-01 02:00:00', 3, 'UTC'),
    'America/Bogota') AS accounting_date;
-- 2026-09-30</code></code></pre><h3><strong>3.4 La partida doble con vistas materializadas</strong></h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!6QPw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F01792530-89ef-4fd8-8bb6-bd1758aa7df1_1456x606.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!6QPw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F01792530-89ef-4fd8-8bb6-bd1758aa7df1_1456x606.png 424w, https://substackcdn.com/image/fetch/$s_!6QPw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F01792530-89ef-4fd8-8bb6-bd1758aa7df1_1456x606.png 848w, https://substackcdn.com/image/fetch/$s_!6QPw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F01792530-89ef-4fd8-8bb6-bd1758aa7df1_1456x606.png 1272w, https://substackcdn.com/image/fetch/$s_!6QPw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F01792530-89ef-4fd8-8bb6-bd1758aa7df1_1456x606.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!6QPw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F01792530-89ef-4fd8-8bb6-bd1758aa7df1_1456x606.png" width="1456" height="606" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/01792530-89ef-4fd8-8bb6-bd1758aa7df1_1456x606.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:606,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:70911,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/218934197?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F01792530-89ef-4fd8-8bb6-bd1758aa7df1_1456x606.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!6QPw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F01792530-89ef-4fd8-8bb6-bd1758aa7df1_1456x606.png 424w, https://substackcdn.com/image/fetch/$s_!6QPw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F01792530-89ef-4fd8-8bb6-bd1758aa7df1_1456x606.png 848w, https://substackcdn.com/image/fetch/$s_!6QPw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F01792530-89ef-4fd8-8bb6-bd1758aa7df1_1456x606.png 1272w, https://substackcdn.com/image/fetch/$s_!6QPw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F01792530-89ef-4fd8-8bb6-bd1758aa7df1_1456x606.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Imagen 6. L&#237;neas de asiento deduplicadas y saldos que se reconstruyen antes de cerrar.</figcaption></figure></div></li></ul><p>Las vistas materializadas de ClickHouse son incrementales: se disparan con cada bloque insertado y procesan solo los datos nuevos. La documentaci&#243;n de ClickPipes las propone como disparadores sobre las tablas del CDC. Una vista se dispara con cada bloque que llega, aunque repita filas, y el CDC repite filas. Por eso guardo las l&#237;neas de asiento de forma que una l&#237;nea repetida se colapse sola:</p><pre><code><code>CREATE TABLE finance.journal_entries
(
    tx_id            UUID,
    line_no          UInt32,
    entity_id        LowCardinality(String),
    accounting_date  Date,
    event_ts         DateTime64(3, 'UTC'),
    account          Int64,
    cost_center      LowCardinality(String),
    counterparty_id  Int64,
    currency         LowCardinality(String),
    debit_minor      Int64,
    credit_minor     Int64,
    debit_lcy_minor  Int64,
    credit_lcy_minor Int64,
    source           LowCardinality(String),
    -- source: OPERATION, ADJUSTMENT, CLOSING, OPENING
    src_version      UInt64,  -- CDC version, 0 for manual
    posted_by        LowCardinality(String)
        DEFAULT currentUser(),
    posted_at        DateTime64(3, 'UTC') DEFAULT now64(3)
)
ENGINE = ReplacingMergeTree(src_version)
PARTITION BY toYYYYMM(accounting_date)
ORDER BY (entity_id, account, accounting_date, tx_id, line_no);

CREATE MATERIALIZED VIEW finance.mv_journal_entries
TO finance.journal_entries AS
SELECT
    tx_id,
    line.1 AS line_no,
    entity_id,
    accounting_date,
    event_ts,
    line.2 AS account,
    cost_center,
    counterparty_id,
    currency,
    line.3 AS debit_minor,
    line.4 AS credit_minor,
    line.5 AS debit_lcy_minor,
    line.6 AS credit_lcy_minor,
    'OPERATION' AS source,
    toUInt64(_peerdb_version) AS src_version
FROM finance.transactions
ARRAY JOIN [
    (toUInt32(1), debit_account, amount_minor, toInt64(0),
     amount_lcy_minor, toInt64(0)),
    (toUInt32(2), credit_account, toInt64(0), amount_minor,
     toInt64(0), amount_lcy_minor)
] AS line
WHERE status = 'CONFIRMED'
  AND _peerdb_is_deleted = 0;</code></code></pre><p><code>ARRAY JOIN</code> convierte cada transacci&#243;n en varias l&#237;neas dentro del mismo bloque. Si una transacci&#243;n lleva IVA, retenci&#243;n y comisi&#243;n, el arreglo tiene cuatro o cinco tuplas y el patr&#243;n no cambia. Como todas las columnas de la clave salen de una transacci&#243;n que no cambia, una l&#237;nea repetida por el CDC tiene la misma clave que la original y <code>ReplacingMergeTree</code> deja una sola. <code>posted_by</code> y <code>posted_at</code> registran qui&#233;n insert&#243; cada l&#237;nea y cu&#225;ndo; en las l&#237;neas del CDC es el usuario de ClickPipes.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Un l&#237;mite del modelo: cada transacci&#243;n tiene una sola moneda y un solo importe en moneda funcional. Una compra de d&#243;lares con pesos, o el pago de una factura en d&#243;lares a una tasa distinta de la de causaci&#243;n, necesita un comprobante de varias l&#237;neas con una cuenta puente de posici&#243;n por moneda y una l&#237;nea en moneda funcional para la diferencia en cambio realizada.</p><p>Los saldos diarios se consolidan con <code>SummingMergeTree</code>:</p><pre><code><code>CREATE TABLE finance.daily_balances
(
    entity_id        LowCardinality(String),
    account          Int64,
    cost_center      LowCardinality(String),
    currency         LowCardinality(String),
    accounting_date  Date,
    debit_minor      Int64,
    credit_minor     Int64,
    debit_lcy_minor  Int64,
    credit_lcy_minor Int64,
    entry_count      UInt64
)
ENGINE = SummingMergeTree((debit_minor, credit_minor,
    debit_lcy_minor, credit_lcy_minor, entry_count))
PARTITION BY toYYYYMM(accounting_date)
ORDER BY (entity_id, account, cost_center, currency,
          accounting_date);

CREATE MATERIALIZED VIEW finance.mv_daily_balances
TO finance.daily_balances AS
SELECT
    entity_id, account, cost_center, currency,
    accounting_date,
    sum(debit_minor)      AS debit_minor,
    sum(credit_minor)     AS credit_minor,
    sum(debit_lcy_minor)  AS debit_lcy_minor,
    sum(credit_lcy_minor) AS credit_lcy_minor,
    count()               AS entry_count
FROM finance.journal_entries
GROUP BY entity_id, account, cost_center, currency,
         accounting_date;</code></code></pre><p>Los 7200 millones de l&#237;neas del a&#241;o quedan en una fila por cuenta, centro de costo, moneda y d&#237;a: decenas de millones de filas al a&#241;o en lugar de miles de millones.</p><blockquote><p><em>Ojo: esta tabla es un saldo provisional. Una suma no se puede deduplicar, y si el CDC repite un bloque, la l&#237;nea repetida se colapsa en </em><code>journal_entries</code><em> pero su importe ya qued&#243; sumado aqu&#237;. Antes de usarla para cerrar la reconstruyo desde las l&#237;neas deduplicadas. Est&#225; particionada por mes para poder reconstruir solo los meses afectados.</em></p></blockquote><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Para indicadores que no se pueden sumar, como clientes &#250;nicos o percentiles, uso <code>AggregatingMergeTree</code>, que guarda estados parciales combinables entre meses. Por la misma raz&#243;n que los saldos, es un indicador de monitoreo: un bloque repetido cuenta dos veces su volumen.</p><pre><code><code>CREATE TABLE finance.monthly_kpis
(
    entity_id        LowCardinality(String),
    month            Date,
    tx_type          LowCardinality(String),
    volume_lcy       AggregateFunction(sum, Int64),
    unique_customers AggregateFunction(uniq, Int64),
    ticket_quantiles AggregateFunction(
        quantiles(0.5, 0.95, 0.99), Int64)
)
ENGINE = AggregatingMergeTree
ORDER BY (entity_id, month, tx_type);

CREATE MATERIALIZED VIEW finance.mv_monthly_kpis
TO finance.monthly_kpis AS
SELECT
    entity_id,
    toStartOfMonth(accounting_date) AS month,
    tx_type,
    sumState(amount_lcy_minor)      AS volume_lcy,
    uniqState(counterparty_id)      AS unique_customers,
    -- approximate percentiles, enough for monitoring
    quantilesState(0.5, 0.95, 0.99)(amount_lcy_minor)
        AS ticket_quantiles
FROM finance.transactions
WHERE status = 'CONFIRMED'
  AND _peerdb_is_deleted = 0
GROUP BY entity_id, month, tx_type;

-- Read path: merge the partial states
SELECT
    month,
    tx_type,
    sumMerge(volume_lcy)        AS volume_lcy_minor,
    uniqMerge(unique_customers) AS customers,
    quantilesMerge(0.5, 0.95, 0.99)(ticket_quantiles)
        AS ticket_p50_p95_p99
FROM finance.monthly_kpis
WHERE entity_id = 'CO01' AND month &gt;= '2026-01-01'
GROUP BY month, tx_type
ORDER BY month, tx_type;</code></code></pre><h3><strong>3.5 El plan de cuentas como diccionario jer&#225;rquico</strong></h3><p>El plan de cuentas es un &#225;rbol: clase, grupo, cuenta, subcuenta y auxiliar. ClickHouse lo carga como diccionario jer&#225;rquico desde Postgres, con la misma <em>named collection</em>, y lo refresca solo. La clave de un diccionario jer&#225;rquico debe ser <code>UInt64</code> y las cuentas ra&#237;z llevan <code>parent_account = 0</code>. Las cuentas del libro son <code>Int64</code> (as&#237; las crea el CDC desde un <code>bigint</code>) y <code>dictGet</code> las acepta sin conversi&#243;n; lo comprob&#233;.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Uso c&#243;digos del PUC (Decreto 2650 de 1993) como ejemplo. Una entidad que reporta bajo NIIF puede tener su propio cat&#225;logo, y las vigiladas por la Superintendencia Financiera reportan con el CUIF, que tiene otros c&#243;digos. En producci&#243;n, las cuentas especiales del cierre (diferencia en cambio, utilidad, p&#233;rdida) deber&#237;an salir de un atributo del plan de cuentas y no del SQL.</p><pre><code><code>CREATE DICTIONARY finance.chart_of_accounts
(
    account        UInt64,
    parent_account UInt64 HIERARCHICAL,
    account_name   String,
    normal_side    String,  -- 'D' debit, 'C' credit
    account_class  UInt8,   -- 1 assets ... 6 cost of sales
    account_level  UInt8
)
PRIMARY KEY account
SOURCE(POSTGRESQL(NAME pg_finance TABLE 'chart_of_accounts'))
LIFETIME(MIN 300 MAX 600)
LAYOUT(HASHED());</code></code></pre><p>Subir por la jerarqu&#237;a es una b&#250;squeda en memoria, sin consultas recursivas:</p><pre><code><code>SELECT
    dictGetHierarchy('finance.chart_of_accounts', 11050501)
        AS ancestry,
    dictIsIn('finance.chart_of_accounts', 11050501, 1)
        AS is_asset;</code></code></pre><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!wZF-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5790a8c7-d4de-4039-a52c-09ad91607dfd_1456x505.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!wZF-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5790a8c7-d4de-4039-a52c-09ad91607dfd_1456x505.png 424w, https://substackcdn.com/image/fetch/$s_!wZF-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5790a8c7-d4de-4039-a52c-09ad91607dfd_1456x505.png 848w, https://substackcdn.com/image/fetch/$s_!wZF-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5790a8c7-d4de-4039-a52c-09ad91607dfd_1456x505.png 1272w, https://substackcdn.com/image/fetch/$s_!wZF-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5790a8c7-d4de-4039-a52c-09ad91607dfd_1456x505.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!wZF-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5790a8c7-d4de-4039-a52c-09ad91607dfd_1456x505.png" width="1456" height="505" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5790a8c7-d4de-4039-a52c-09ad91607dfd_1456x505.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:505,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:41231,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/218934197?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5790a8c7-d4de-4039-a52c-09ad91607dfd_1456x505.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!wZF-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5790a8c7-d4de-4039-a52c-09ad91607dfd_1456x505.png 424w, https://substackcdn.com/image/fetch/$s_!wZF-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5790a8c7-d4de-4039-a52c-09ad91607dfd_1456x505.png 848w, https://substackcdn.com/image/fetch/$s_!wZF-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5790a8c7-d4de-4039-a52c-09ad91607dfd_1456x505.png 1272w, https://substackcdn.com/image/fetch/$s_!wZF-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5790a8c7-d4de-4039-a52c-09ad91607dfd_1456x505.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Imagen 7. La ascendencia completa de una subcuenta en una sola llamada.</figcaption></figure></div><h3><strong>3.6 Tasas de cambio con ASOF JOIN</strong></h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!A3sW!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faac4c57d-efe0-4f83-b408-d32ffe502023_1456x554.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!A3sW!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faac4c57d-efe0-4f83-b408-d32ffe502023_1456x554.png 424w, https://substackcdn.com/image/fetch/$s_!A3sW!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faac4c57d-efe0-4f83-b408-d32ffe502023_1456x554.png 848w, https://substackcdn.com/image/fetch/$s_!A3sW!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faac4c57d-efe0-4f83-b408-d32ffe502023_1456x554.png 1272w, https://substackcdn.com/image/fetch/$s_!A3sW!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faac4c57d-efe0-4f83-b408-d32ffe502023_1456x554.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!A3sW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faac4c57d-efe0-4f83-b408-d32ffe502023_1456x554.png" width="1456" height="554" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/aac4c57d-efe0-4f83-b408-d32ffe502023_1456x554.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:554,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:45114,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/218934197?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faac4c57d-efe0-4f83-b408-d32ffe502023_1456x554.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!A3sW!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faac4c57d-efe0-4f83-b408-d32ffe502023_1456x554.png 424w, https://substackcdn.com/image/fetch/$s_!A3sW!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faac4c57d-efe0-4f83-b408-d32ffe502023_1456x554.png 848w, https://substackcdn.com/image/fetch/$s_!A3sW!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faac4c57d-efe0-4f83-b408-d32ffe502023_1456x554.png 1272w, https://substackcdn.com/image/fetch/$s_!A3sW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faac4c57d-efe0-4f83-b408-d32ffe502023_1456x554.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Imagen 8. Cada transacci&#243;n toma la tasa vigente en su instante, no la del d&#237;a.</figcaption></figure></div><p>Convertir a moneda funcional exige la tasa vigente en el instante de la transacci&#243;n. <code>ASOF JOIN</code> busca, para cada fila, la tasa m&#225;s reciente anterior o igual a ese instante. Lo uso como control de auditor&#237;a: recalculo el importe en pesos con la tasa de la mesa de cambios, que cambia durante el d&#237;a, y lo comparo con el que registr&#243; el origen. La TRM, que rige un d&#237;a completo, queda para la revaluaci&#243;n del cierre.</p><pre><code><code>CREATE TABLE finance.fx_rates
(
    currency    LowCardinality(String),
    valid_from  DateTime64(3, 'UTC'),
    rate        Decimal(18, 10),  -- COP per unit
    rate_source LowCardinality(String)  -- 'DESK' or 'TRM'
)
ENGINE = ReplacingMergeTree
ORDER BY (currency, rate_source, valid_from);

SELECT
    t.tx_id,
    t.event_ts,
    t.currency,
    t.amount_minor,
    r.rate,
    convert_minor(t.amount_minor, t.currency, 'COP', r.rate)
        AS recalculated_lcy_minor,
    t.amount_lcy_minor,
    recalculated_lcy_minor - t.amount_lcy_minor
        AS difference_minor
FROM finance.transactions AS t FINAL
ASOF LEFT JOIN
(
    SELECT currency, valid_from, rate
    FROM finance.fx_rates
    WHERE rate_source = 'DESK'
) AS r
    ON t.currency = r.currency
   AND t.event_ts &gt;= r.valid_from
WHERE t.accounting_date = '2026-12-31'
  AND t.currency != 'COP'
  AND t._peerdb_is_deleted = 0
SETTINGS do_not_merge_across_partitions_select_final = 1;</code></code></pre><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!VUeV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816a2a58-01b4-4381-918f-375c49c64167_1456x1261.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!VUeV!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816a2a58-01b4-4381-918f-375c49c64167_1456x1261.png 424w, https://substackcdn.com/image/fetch/$s_!VUeV!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816a2a58-01b4-4381-918f-375c49c64167_1456x1261.png 848w, https://substackcdn.com/image/fetch/$s_!VUeV!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816a2a58-01b4-4381-918f-375c49c64167_1456x1261.png 1272w, https://substackcdn.com/image/fetch/$s_!VUeV!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816a2a58-01b4-4381-918f-375c49c64167_1456x1261.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!VUeV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816a2a58-01b4-4381-918f-375c49c64167_1456x1261.png" width="1456" height="1261" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/816a2a58-01b4-4381-918f-375c49c64167_1456x1261.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1261,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:146177,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/218934197?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816a2a58-01b4-4381-918f-375c49c64167_1456x1261.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!VUeV!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816a2a58-01b4-4381-918f-375c49c64167_1456x1261.png 424w, https://substackcdn.com/image/fetch/$s_!VUeV!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816a2a58-01b4-4381-918f-375c49c64167_1456x1261.png 848w, https://substackcdn.com/image/fetch/$s_!VUeV!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816a2a58-01b4-4381-918f-375c49c64167_1456x1261.png 1272w, https://substackcdn.com/image/fetch/$s_!VUeV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816a2a58-01b4-4381-918f-375c49c64167_1456x1261.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Imagen 9. Una diferencia distinta de cero se&#241;ala una tasa mal aplicada en el origen.</figcaption></figure></div><h2><strong>4. El CDC desde Postgres: &#191;qu&#233; garantiza y qu&#233; no?</strong></h2><p>El CDC funciona casi siempre, y por eso es f&#225;cil suponer que cada fila llega exactamente una vez. &#191;No es as&#237;?</p><h3><strong>4.1 &#191;C&#243;mo funciona?</strong></h3><p>ClickPipes lee el WAL de Postgres mediante un slot de replicaci&#243;n l&#243;gica y una publicaci&#243;n. Primero hace una carga inicial de cada tabla y luego aplica los cambios en lotes. Cada <code>INSERT</code> o <code>UPDATE</code> llega como una fila nueva con una versi&#243;n mayor, y cada <code>DELETE</code> como una fila con <code>_peerdb_is_deleted = 1</code>. Cada replicaci&#243;n configurada se llama un <em>pipe</em>.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h3><strong>4.2 Requisitos en Postgres</strong></h3><p>ClickPipes admite Postgres 12 o superior, autoadministrado o en los servicios administrados m&#225;s comunes, y se conecta directo al servidor: los <em>poolers</em> de conexiones como PgBouncer no sirven para CDC. En un Postgres propio, la decodificaci&#243;n l&#243;gica se activa as&#237;:</p><pre><code><code>-- PostgreSQL (self-managed): enable logical decoding
ALTER SYSTEM SET wal_level = 'logical';
ALTER SYSTEM SET max_wal_senders = 10;
ALTER SYSTEM SET max_replication_slots = 10;
ALTER SYSTEM SET max_slot_wal_keep_size = '100GB';
-- restart PostgreSQL for wal_level to take effect</code></code></pre><p>En un Postgres administrado, la replicaci&#243;n l&#243;gica se activa con el par&#225;metro que define el proveedor, tambi&#233;n con reinicio. Para el WAL retenido, la gu&#237;a de instalaci&#243;n propone 100 GB y la FAQ pide al menos dos d&#237;as de WAL o 200 GB; yo dimensiono con dos o tres veces el pico diario.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>El usuario de ClickPipes necesita lectura sobre las tablas y permiso de replicaci&#243;n:</p><pre><code><code>-- PostgreSQL: dedicated CDC user (password from a vault)
CREATE USER clickpipes_user PASSWORD '***';
GRANT USAGE ON SCHEMA public TO clickpipes_user;
GRANT SELECT ON ALL TABLES IN SCHEMA public
    TO clickpipes_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
    GRANT SELECT ON TABLES TO clickpipes_user;
ALTER USER clickpipes_user WITH REPLICATION;</code></code></pre><p>Cada tabla replicada necesita clave primaria o <code>REPLICA IDENTITY</code>. ClickPipes crea por su cuenta la publicaci&#243;n y el slot para las tablas que eliges. Limita la duraci&#243;n de las transacciones con <code>statement_timeout</code> e <code>idle_in_transaction_session_timeout</code>: una transacci&#243;n abierta durante horas retiene WAL en el slot.</p><h3><strong>4.3 Configuraci&#243;n del pipe</strong></h3><p>En ClickPipes elijo <code>transactions</code>, <code>accounting_periods</code>, <code>journal_vouchers</code> y <code>parties</code>, con la partici&#243;n <code>toYYYYMM(accounting_date)</code> para <code>transactions</code> y sin las columnas cifradas de <code>parties</code>. Antes de crear el pipe, ten en cuenta:</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><ul><li><p>Despu&#233;s de crearlo puedes agregar o quitar tablas y ajustar el intervalo de sincronizaci&#243;n y el tama&#241;o de lote. La clave de ordenaci&#243;n, la partici&#243;n, el motor y las columnas excluidas de cada tabla se fijan al agregarla; cambiarlos exige resincronizarla.</p></li><li><p>El intervalo de sincronizaci&#243;n es de 60 segundos por defecto y la documentaci&#243;n recomienda no bajarlo de 10. Un lote adem&#225;s espera el <code>COMMIT</code> de cada transacci&#243;n de Postgres.</p></li><li><p>Si una vista se crea despu&#233;s de la carga inicial, hay que rellenarla con el procedimiento de la secci&#243;n 4.6.</p></li></ul><h3><strong>4.4 Lo que el CDC no garantiza</strong></h3><p>Esto fue lo que m&#225;s me cost&#243; entender, y de aqu&#237; sale el dise&#241;o de los asientos.</p><p><strong>La entrega se comporta como &#8220;al menos una vez&#8221;.</strong> La FAQ de ClickPipes explica que, si se interrumpe la escritura en la tabla final, la deduplicaci&#243;n queda a cargo de <code>ReplacingMergeTree</code>. En el c&#243;digo de PeerDB, esa escritura es un <code>INSERT ... SELECT</code> por lote que no usa <code>insert_deduplication_token</code> y que marca el lote como terminado en una operaci&#243;n aparte. Si el proceso cae entre las dos, el lote se inserta otra vez con la misma versi&#243;n. La tabla de transacciones lo resuelve en la siguiente fusi&#243;n, pero las vistas materializadas se disparan de nuevo.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p><strong>Una resincronizaci&#243;n no pasa por las vistas.</strong> Resincronizar carga todo en tablas con sufijo <code>_resync</code> y luego las intercambia con las originales. Las vistas definidas sobre la tabla original no ven esa carga y sus tablas de destino pueden quedar con huecos.</p><p><strong>Hay operaciones que no viajan.</strong> <code>TRUNCATE</code> se ignora; solo <code>ADD COLUMN</code> se propaga como cambio de esquema, y solo cuando la tabla recibe su siguiente cambio; las columnas generadas no se replican; y por defecto ninguna columna es <code>Nullable</code>, as&#237; que un <code>NULL</code> llega como el valor por defecto del tipo (una cadena vac&#237;a, por ejemplo).</p><p><strong>Pausar no detiene el WAL.</strong> Un pipe pausado deja que el slot siga acumulando WAL. Si supera <code>max_slot_wal_keep_size</code>, Postgres invalida el slot, y seg&#250;n la FAQ la &#250;nica salida es una resincronizaci&#243;n completa.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!wozg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a1ea5d-154d-49bb-bf4b-3ccfa9f46766_1456x1541.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!wozg!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a1ea5d-154d-49bb-bf4b-3ccfa9f46766_1456x1541.png 424w, https://substackcdn.com/image/fetch/$s_!wozg!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a1ea5d-154d-49bb-bf4b-3ccfa9f46766_1456x1541.png 848w, https://substackcdn.com/image/fetch/$s_!wozg!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a1ea5d-154d-49bb-bf4b-3ccfa9f46766_1456x1541.png 1272w, https://substackcdn.com/image/fetch/$s_!wozg!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a1ea5d-154d-49bb-bf4b-3ccfa9f46766_1456x1541.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!wozg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a1ea5d-154d-49bb-bf4b-3ccfa9f46766_1456x1541.png" width="1456" height="1541" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/07a1ea5d-154d-49bb-bf4b-3ccfa9f46766_1456x1541.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1541,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:209117,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/218934197?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a1ea5d-154d-49bb-bf4b-3ccfa9f46766_1456x1541.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!wozg!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a1ea5d-154d-49bb-bf4b-3ccfa9f46766_1456x1541.png 424w, https://substackcdn.com/image/fetch/$s_!wozg!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a1ea5d-154d-49bb-bf4b-3ccfa9f46766_1456x1541.png 848w, https://substackcdn.com/image/fetch/$s_!wozg!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a1ea5d-154d-49bb-bf4b-3ccfa9f46766_1456x1541.png 1272w, https://substackcdn.com/image/fetch/$s_!wozg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a1ea5d-154d-49bb-bf4b-3ccfa9f46766_1456x1541.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Imagen 10. Simulaci&#243;n de un lote repetido: las l&#237;neas se deduplican, los saldos provisionales no, y la reconstrucci&#243;n lo corrige.</em></figcaption></figure></div><h3><strong>4.5 El dise&#241;o que lo absorbe</strong></h3><ol><li><p><strong>Transacciones definitivas en Postgres</strong>, de modo que cada l&#237;nea de asiento tiene una clave estable.</p></li><li><p><strong>L&#237;neas de asiento idempotentes:</strong> <code>journal_entries</code> usa <code>ReplacingMergeTree</code> con <code>(tx_id, line_no)</code> en la clave. Repetir un lote o volver a derivar un mes nunca deja una l&#237;nea duplicada despu&#233;s de deduplicar.</p></li><li><p><strong>Saldos reconstruibles:</strong> <code>daily_balances</code> se reconstruye antes de cerrar.</p></li><li><p><strong>Controles hasta el origen:</strong> el cierre compara Postgres con <code>transactions</code>, <code>transactions</code> con <code>journal_entries</code> y <code>journal_entries</code> con <code>daily_balances</code>. Cualquier diferencia detiene el proceso.</p></li></ol><h3><strong>4.6 Despu&#233;s de una resincronizaci&#243;n</strong></h3><p>Primero compruebo que las vistas siguen enganchadas a la tabla, porque una resincronizaci&#243;n de tabla la reemplaza:</p><pre><code><code>-- Both materialized views must still depend on the table
SELECT dependencies_table
FROM system.tables
WHERE database = 'finance' AND name = 'transactions';
-- expected: ['mv_journal_entries', 'mv_monthly_kpis']</code></code></pre><p>Luego vuelvo a derivar las l&#237;neas de asiento de los meses afectados desde las transacciones deduplicadas. Como la tabla de asientos es idempotente, las l&#237;neas que ya estaban no se duplican:</p><pre><code><code>-- After a ClickPipes resync: re-derive the journal lines
-- of the affected months (idempotent thanks to the RMT)
INSERT INTO finance.journal_entries
    (tx_id, line_no, entity_id, accounting_date, event_ts,
     account, cost_center, counterparty_id, currency,
     debit_minor, credit_minor, debit_lcy_minor,
     credit_lcy_minor, source, src_version)
SELECT
    tx_id,
    line.1 AS line_no,
    entity_id,
    accounting_date,
    event_ts,
    line.2 AS account,
    cost_center,
    counterparty_id,
    currency,
    line.3 AS debit_minor,
    line.4 AS credit_minor,
    line.5 AS debit_lcy_minor,
    line.6 AS credit_lcy_minor,
    'OPERATION' AS source,
    toUInt64(_peerdb_version) AS src_version
FROM finance.transactions FINAL
ARRAY JOIN [
    (toUInt32(1), debit_account, amount_minor, toInt64(0),
     amount_lcy_minor, toInt64(0)),
    (toUInt32(2), credit_account, toInt64(0), amount_minor,
     toInt64(0), amount_lcy_minor)
] AS line
WHERE status = 'CONFIRMED'
  AND _peerdb_is_deleted = 0
  AND toYYYYMM(accounting_date) BETWEEN 202611 AND 202612
SETTINGS do_not_merge_across_partitions_select_final = 1;</code></code></pre><p>Despu&#233;s reconstruyo los saldos de esos meses y repito los controles del paso 1. Los indicadores de <code>monthly_kpis</code> se reconstruyen igual si se usan para algo m&#225;s que monitoreo.</p><h3><strong>4.7 Monitoreo</strong></h3><p>ClickHouse Cloud expone m&#233;tricas de ClickPipes en formato Prometheus. Vigilo <code>ClickPipes_SourceReplicationLatency_MiB</code> (retraso del slot en Postgres), la distancia entre <code>ClickPipes_LastFetchedBatchId</code> y <code>ClickPipes_LastSentBatchId</code>, <code>ClickPipes_Errors_Total</code> y el estado del pipe en <code>ClickPipes_Info</code>. En Postgres, el retraso del slot tambi&#233;n se ve en <code>pg_replication_slots</code>.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2><strong>5. Consultas financieras</strong></h2><h3><strong>5.1 Saldo acumulado</strong></h3><p>Una consulta de operaci&#243;n diaria sobre los saldos provisionales; para cifras de cierre, ejec&#250;tala despu&#233;s del paso 0.</p><pre><code><code>SELECT
    accounting_date,
    account,
    sum(debit_lcy_minor - credit_lcy_minor) AS movement,
    sum(sum(debit_lcy_minor - credit_lcy_minor)) OVER (
        PARTITION BY account
        ORDER BY accounting_date
        ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
    ) AS running_balance
FROM finance.daily_balances
WHERE entity_id = 'CO01'
  AND account = 111005
  AND accounting_date BETWEEN '2026-01-01'
                          AND '2026-12-31'
GROUP BY accounting_date, account
ORDER BY accounting_date;</code></code></pre><p>Como el rango empieza el 1 de enero, el saldo incluye la apertura del a&#241;o.</p><h3><strong>5.2 Antig&#252;edad de cartera en una sola pasada</strong></h3><pre><code><code>SELECT
    counterparty_id,
    sumIf(balance, days &lt;= 30)              AS d0_30,
    sumIf(balance, days BETWEEN 31 AND 60)  AS d31_60,
    sumIf(balance, days BETWEEN 61 AND 90)  AS d61_90,
    sumIf(balance, days BETWEEN 91 AND 180) AS d91_180,
    sumIf(balance, days &gt; 180)              AS d180_plus,
    sum(balance)                            AS total
FROM
(
    SELECT
        counterparty_id,
        dateDiff('day', accounting_date,
                 toDate('2026-12-31')) AS days,
        debit_lcy_minor - credit_lcy_minor AS balance
    FROM finance.journal_entries FINAL
    WHERE entity_id = 'CO01'
      -- receivables group (13) and every sub-account
      AND dictIsIn('finance.chart_of_accounts', account, 13)
      AND accounting_date BETWEEN '2026-01-01'
                              AND '2026-12-31'
)
GROUP BY counterparty_id
HAVING total != 0
ORDER BY total DESC
SETTINGS do_not_merge_across_partitions_select_final = 1;</code></code></pre><p>El rango es el a&#241;o, por la raz&#243;n que explico en la secci&#243;n 6.4. Es un ejemplo simplificado. La apertura conserva el saldo de cada tercero pero no la fecha de sus documentos, as&#237; que un informe de antig&#252;edad real cruza cada pago con su factura y usa la fecha de vencimiento. Lo que me interesa mostrar es el combinador <code>-If</code>, que evita un <code>CASE</code> por columna o varias pasadas sobre los datos.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h3><strong>5.3 VPN y TIR dentro del motor</strong></h3><p>Desde la versi&#243;n 25.7, ClickHouse trae funciones financieras nativas, incluidas las versiones con fechas irregulares equivalentes a <code>XNPV</code> y <code>XIRR</code> de las hojas de c&#225;lculo. Solo aceptan enteros o <code>Float</code>, no <code>Decimal</code>; convierto los flujos a unidades mayores en <code>Float64</code>, que para valoraci&#243;n alcanza. El libro sigue en enteros.</p><pre><code><code>-- finance.loan_cash_flows(loan_id, payment_date,
--                         currency, cash_flow_minor)
SELECT
    loan_id,
    arraySort(groupArray((
        payment_date,
        cash_flow_minor / intExp10(dictGet(
            'finance.currency_dict', 'minor_units',
            toString(currency)))
    ))) AS flows,
    financialInternalRateOfReturnExtended(
        arrayMap(f -&gt; f.2, flows),
        arrayMap(f -&gt; f.1, flows)) AS irr,
    financialNetPresentValueExtended(
        0.12,
        arrayMap(f -&gt; f.2, flows),
        arrayMap(f -&gt; f.1, flows)) AS npv_12
FROM finance.loan_cash_flows
GROUP BY loan_id;</code></code></pre><h3><strong>5.4 Riesgo de mercado</strong></h3><p>VaR hist&#243;rico al 99 %, volatilidad diaria y correlaci&#243;n con el &#237;ndice de referencia, por portafolio:</p><pre><code><code>-- Historical 99% VaR, volatility and benchmark correlation
SELECT
    portfolio_id,
    quantileExact(0.01)(daily_return)    AS var_99,
    stddevSamp(daily_return)             AS volatility,
    corr(daily_return, benchmark_return) AS correlation
FROM finance.portfolio_returns
WHERE return_date &gt;= today() - 500
GROUP BY portfolio_id;</code></code></pre><p>ClickHouse tambi&#233;n tiene <code>exponentialMovingAverage</code>, <code>simpleLinearRegression</code>, <code>quantileTDigest</code>, <code>covarSamp</code>, <code>studentTTest</code> y <code>mannWhitneyUTest</code>, entre otras.</p><h3><strong>5.5 Anomal&#237;as en tiempo real</strong></h3><p>Transacciones del &#250;ltimo cuarto de hora que se salen m&#225;s de seis desviaciones est&#225;ndar del comportamiento del tercero en los &#250;ltimos 90 d&#237;as:</p><pre><code><code>WITH stats AS
(
    SELECT
        counterparty_id,
        avg(amount_lcy_minor)       AS mean_minor,
        stddevPop(amount_lcy_minor) AS sd_minor
    FROM finance.transactions FINAL
    WHERE accounting_date &gt;= today() - 90
      AND status = 'CONFIRMED'
      AND _peerdb_is_deleted = 0
    GROUP BY counterparty_id
)
SELECT
    t.tx_id,
    t.counterparty_id,
    t.amount_lcy_minor,
    (t.amount_lcy_minor - s.mean_minor)
        / nullIf(s.sd_minor, 0) AS z_score
FROM finance.transactions AS t FINAL
INNER JOIN stats AS s USING (counterparty_id)
WHERE t.accounting_date &gt;= today() - 1
  AND t.event_ts &gt;= now() - INTERVAL 15 MINUTE
  AND t.status = 'CONFIRMED'
  AND t._peerdb_is_deleted = 0
  AND z_score &gt; 6
ORDER BY z_score DESC
SETTINGS do_not_merge_across_partitions_select_final = 1;</code></code></pre><p>Para secuencias sospechosas, como un cambio de contrase&#241;a seguido de un beneficiario nuevo y una transferencia grande en pocos minutos, est&#225;n <code>sequenceMatch</code> y <code>windowFunnel</code>.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2><strong>6. El cierre fiscal</strong></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!tCE7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbea8bd58-5832-48b2-b891-9a09f83ebd39_1456x476.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!tCE7!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbea8bd58-5832-48b2-b891-9a09f83ebd39_1456x476.png 424w, https://substackcdn.com/image/fetch/$s_!tCE7!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbea8bd58-5832-48b2-b891-9a09f83ebd39_1456x476.png 848w, https://substackcdn.com/image/fetch/$s_!tCE7!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbea8bd58-5832-48b2-b891-9a09f83ebd39_1456x476.png 1272w, https://substackcdn.com/image/fetch/$s_!tCE7!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbea8bd58-5832-48b2-b891-9a09f83ebd39_1456x476.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!tCE7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbea8bd58-5832-48b2-b891-9a09f83ebd39_1456x476.png" width="1456" height="476" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bea8bd58-5832-48b2-b891-9a09f83ebd39_1456x476.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:476,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:70213,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/218934197?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbea8bd58-5832-48b2-b891-9a09f83ebd39_1456x476.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!tCE7!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbea8bd58-5832-48b2-b891-9a09f83ebd39_1456x476.png 424w, https://substackcdn.com/image/fetch/$s_!tCE7!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbea8bd58-5832-48b2-b891-9a09f83ebd39_1456x476.png 848w, https://substackcdn.com/image/fetch/$s_!tCE7!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbea8bd58-5832-48b2-b891-9a09f83ebd39_1456x476.png 1272w, https://substackcdn.com/image/fetch/$s_!tCE7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbea8bd58-5832-48b2-b891-9a09f83ebd39_1456x476.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Imagen 11. Qu&#233; aporta ClickHouse en cada fase del cierre.</figcaption></figure></div><h3><strong>6.1 Calendario y periodos</strong></h3><p>Los periodos son mensuales y los controla Postgres. Diciembre sigue <code>OPEN</code> despu&#233;s del 31, porque las liquidaciones de tarjetas, los archivos bancarios y las compensaciones del 31 llegan el 1 y el 2 de enero y deben quedar en 2026. El corte es una fecha que fija el equipo contable, por ejemplo el 3 de enero a las 23:59. En ese momento diciembre pasa a <code>CLOSING</code> (el disparador ya no deja confirmar operaciones con fecha de diciembre) y espero a que el CDC haya llevado a ClickHouse todo lo anterior:</p><pre><code><code>-- PostgreSQL: freeze December for operations
UPDATE accounting_periods
SET status = 'CLOSING'
WHERE period = 202612;

-- note the current WAL position...
SELECT pg_current_wal_lsn() AS cutoff_lsn;

-- ...and wait until the ClickPipes slot has confirmed it
SELECT slot_name,
       confirmed_flush_lsn &gt;= '0/0'::pg_lsn AS caught_up
FROM pg_replication_slots
WHERE slot_type = 'logical';
-- replace '0/0' with the cutoff_lsn returned above</code></code></pre><p>Antes de anotar la posici&#243;n espero a que termine cualquier transacci&#243;n que empez&#243; antes del cambio a <code>CLOSING</code> (<code>xact_start</code> en <code>pg_stat_activity</code>), porque el disparador ya la dej&#243; pasar. Cuando <code>caught_up</code> es verdadero, los cambios anteriores al corte ya salieron de Postgres; ClickPipes los aplica a la tabla final en el siguiente lote. Que diciembre est&#233; completo en ClickHouse no lo prueba el slot sino el control contra Postgres de la secci&#243;n 6.4. Los meses anteriores pasaron por lo mismo al cerrarse.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!vpu0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7cc58b7-c8cf-4c0c-9c9e-a11760defe83_1456x670.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vpu0!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7cc58b7-c8cf-4c0c-9c9e-a11760defe83_1456x670.png 424w, https://substackcdn.com/image/fetch/$s_!vpu0!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7cc58b7-c8cf-4c0c-9c9e-a11760defe83_1456x670.png 848w, https://substackcdn.com/image/fetch/$s_!vpu0!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7cc58b7-c8cf-4c0c-9c9e-a11760defe83_1456x670.png 1272w, https://substackcdn.com/image/fetch/$s_!vpu0!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7cc58b7-c8cf-4c0c-9c9e-a11760defe83_1456x670.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!vpu0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7cc58b7-c8cf-4c0c-9c9e-a11760defe83_1456x670.png" width="1456" height="670" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c7cc58b7-c8cf-4c0c-9c9e-a11760defe83_1456x670.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:670,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:69139,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/218934197?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7cc58b7-c8cf-4c0c-9c9e-a11760defe83_1456x670.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!vpu0!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7cc58b7-c8cf-4c0c-9c9e-a11760defe83_1456x670.png 424w, https://substackcdn.com/image/fetch/$s_!vpu0!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7cc58b7-c8cf-4c0c-9c9e-a11760defe83_1456x670.png 848w, https://substackcdn.com/image/fetch/$s_!vpu0!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7cc58b7-c8cf-4c0c-9c9e-a11760defe83_1456x670.png 1272w, https://substackcdn.com/image/fetch/$s_!vpu0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7cc58b7-c8cf-4c0c-9c9e-a11760defe83_1456x670.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Imagen 12. Cada mes contable es una partici&#243;n f&#237;sica.</figcaption></figure></div><h3><strong>6.2 Pre-cierre: el balance preliminar</strong></h3><p>Durante diciembre uso una vista materializada refrescable. Ejecuta la consulta completa cada hora y reemplaza el resultado de forma at&#243;mica:</p><pre><code><code>CREATE MATERIALIZED VIEW finance.preliminary_trial_balance
REFRESH EVERY 1 HOUR
ENGINE = MergeTree
ORDER BY (entity_id, account)
AS
SELECT
    entity_id,
    account,
    dictGet('finance.chart_of_accounts', 'account_name',
            account) AS account_name,
    sum(debit_lcy_minor)  AS total_debit_lcy,
    sum(credit_lcy_minor) AS total_credit_lcy,
    total_debit_lcy - total_credit_lcy AS balance_lcy,
    now() AS computed_at
FROM finance.daily_balances
WHERE accounting_date BETWEEN '2026-01-01'
                          AND '2026-12-31'
GROUP BY entity_id, account;</code></code></pre><p>Sale de los saldos provisionales, as&#237; que sirve para ver venir el cierre, no para cerrarlo. Estas vistas admiten dependencias (<code>DEPENDS ON</code>) y se pueden encadenar sin un orquestador externo.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h3><strong>6.3 Conciliaci&#243;n</strong></h3><p>Comparar fila por fila 300 millones de registros entre dos sistemas es caro. Primero comparo huellas por d&#237;a, cuenta y moneda, y solo bajo al detalle donde no coinciden. La huella es un XOR de un MD5 por transacci&#243;n; la misma t&#233;cnica, calculada en Postgres con <code>bit_xor</code>, es la que uso en la secci&#243;n 6.4 para comparar contra el origen:</p><pre><code><code>SELECT
    accounting_date,
    debit_account AS account,
    currency,
    count()           AS tx_count,
    sum(amount_minor) AS total_minor,
    groupBitXor(reinterpretAsInt64(reverse(unhex(left(hex(
        MD5(concat(toString(tx_id), '|',
                   toString(amount_minor)))), 16)))))
        AS fingerprint
FROM finance.transactions FINAL
WHERE entity_id = 'CO01'
  AND toYYYYMM(accounting_date) = 202612
  AND status = 'CONFIRMED'
  AND _peerdb_is_deleted = 0
GROUP BY accounting_date, account, currency
SETTINGS do_not_merge_across_partitions_select_final = 1;</code></code></pre><p>El XOR no depende del orden de las filas, pero dos filas id&#233;nticas se anulan entre s&#237;; por eso la huella siempre se compara junto con el conteo y el total.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Cuando una combinaci&#243;n no cuadra, cruzo el libro auxiliar de bancos con el extracto. Los bancos y el sistema de pagos inmediatos Bre-B ya usan mensajes ISO 20022, y lo pr&#225;ctico es normalizar los extractos a una estructura tipo camt.053 en archivos Parquet que ClickHouse lee desde el almacenamiento de objetos. Las credenciales del almacenamiento tambi&#233;n van en <em>named collections</em>:</p><pre><code><code>-- Created once by an administrator; queries use the names
CREATE NAMED COLLECTION s3_finance AS
    url = 'https://storage.example.com/finance-data/',
    access_key_id = '***',
    secret_access_key = '***';
CREATE NAMED COLLECTION s3_worm AS
    url = 'https://storage.example.com/finance-worm/',
    access_key_id = '***',
    secret_access_key = '***';</code></code></pre><pre><code><code>SELECT
    coalesce(l.reference, b.reference) AS reference,
    l.amount_minor AS ledger_minor,
    b.amount_minor AS bank_minor,
    multiIf(
        l.reference IS NULL, 'BANK_ONLY',
        b.reference IS NULL, 'LEDGER_ONLY',
        l.amount_minor != b.amount_minor, 'AMOUNT_MISMATCH',
        'MATCHED') AS match_status
FROM
(
    SELECT reference, amount_minor
    FROM finance.cash_book_entries
    WHERE entry_date = '2026-12-31' AND account = 111005
) AS l
FULL OUTER JOIN
(
    -- camt.053-style statement, amounts in COP
    SELECT
        reference,
        toInt64(round(toDecimal128(amount, 4)
            * intExp10(dictGet('finance.currency_dict',
                               'minor_units', 'COP')), 0))
            AS amount_minor
    FROM s3(s3_finance,
            filename = 'bank-statements/2026-12-31/*.parquet',
            format = 'Parquet')
) AS b
ON l.reference = b.reference
WHERE match_status != 'MATCHED'
SETTINGS join_use_nulls = 1;</code></code></pre><p>En ClickHouse Cloud tambi&#233;n se puede dar acceso al bucket con un rol del proveedor de nube en lugar de claves.</p><h3><strong>6.4 Reconstruir y verificar</strong></h3><p>Todas las consultas del cierre filtran el a&#241;o, del 1 de enero al 31 de diciembre, y nunca el hist&#243;rico: cada a&#241;o parte de su propia apertura, y sumar el hist&#243;rico contar&#237;a dos veces lo ya trasladado. Lo que se suma entre cuentas y monedas es siempre el importe en moneda funcional.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p><strong>Paso 0. Reconstruir los saldos desde las l&#237;neas deduplicadas.</strong> Lo hago mes a mes (un script recorre de 202601 a 202612) y lo repito antes del paso 4, que escribe un comprobante a partir de los saldos:</p><pre><code><code>-- 0a. Rebuild one month of balances
CREATE TABLE IF NOT EXISTS finance.daily_balances_rebuild
    AS finance.daily_balances;
TRUNCATE TABLE finance.daily_balances_rebuild;

INSERT INTO finance.daily_balances_rebuild
SELECT
    entity_id, account, cost_center, currency,
    accounting_date,
    sum(debit_minor), sum(credit_minor),
    sum(debit_lcy_minor), sum(credit_lcy_minor),
    count()
FROM finance.journal_entries FINAL
WHERE toYYYYMM(accounting_date) = {period:UInt32}
GROUP BY entity_id, account, cost_center, currency,
         accounting_date
SETTINGS do_not_merge_across_partitions_select_final = 1;

ALTER TABLE finance.daily_balances
    REPLACE PARTITION {period:UInt32}
    FROM finance.daily_balances_rebuild;

-- 0b. Verify the month; if it fails, run 0a again
SELECT throwIf(count() &gt; 0, 'Balances differ from journal')
FROM
(
    SELECT entity_id, account, currency,
           sum(debit_lcy_minor) AS d,
           sum(credit_lcy_minor) AS c
    FROM finance.daily_balances
    WHERE toYYYYMM(accounting_date) = {period:UInt32}
    GROUP BY entity_id, account, currency
) AS b
FULL OUTER JOIN
(
    SELECT entity_id, account, currency,
           sum(debit_lcy_minor) AS d,
           sum(credit_lcy_minor) AS c
    FROM finance.journal_entries FINAL
    WHERE toYYYYMM(accounting_date) = {period:UInt32}
    GROUP BY entity_id, account, currency
) AS j USING (entity_id, account, currency)
WHERE b.d != j.d OR b.c != j.c
SETTINGS do_not_merge_across_partitions_select_final = 1;</code></code></pre><p><code>REPLACE PARTITION</code> cambia la partici&#243;n de forma at&#243;mica y no dispara las vistas materializadas. Si una l&#237;nea llega a los asientos despu&#233;s de leer y antes del reemplazo, se queda fuera de los saldos; para eso est&#225; la verificaci&#243;n 0b.</p><p><strong>Paso 1. Comprobar la partida doble, las l&#237;neas, el origen y los comprobantes.</strong> Cada consulta falla si algo no cuadra:</p><pre><code><code>-- 1a. Debits equal credits per entity and currency
SELECT
    entity_id,
    currency,
    sum(debit_minor)      AS total_debit,
    sum(credit_minor)     AS total_credit,
    sum(debit_lcy_minor)  AS total_debit_lcy,
    sum(credit_lcy_minor) AS total_credit_lcy,
    throwIf(
        total_debit != total_credit
            OR total_debit_lcy != total_credit_lcy,
        'Double-entry check failed') AS check_result
FROM finance.daily_balances
WHERE accounting_date BETWEEN '2026-01-01'
                          AND '2026-12-31'
GROUP BY entity_id, currency;

-- 1b. A line may repeat (CDC retries), but two copies of
-- the same (tx_id, line_no) must never disagree
SELECT throwIf(count() &gt; 0, 'Conflicting journal lines')
FROM
(
    SELECT tx_id, line_no
    FROM finance.journal_entries
    WHERE toYear(accounting_date) = 2026
    GROUP BY tx_id, line_no
    HAVING uniqExact(account, debit_minor, credit_minor,
                     debit_lcy_minor, credit_lcy_minor) &gt; 1
);

-- 1c. Journal lines match the confirmed transactions
SELECT throwIf(count() &gt; 0, 'Journal differs from CDC data')
FROM
(
    SELECT entity_id, toYYYYMM(accounting_date) AS period,
           2 * count() AS lines, sum(amount_lcy_minor) AS lcy
    FROM finance.transactions FINAL
    WHERE status = 'CONFIRMED' AND _peerdb_is_deleted = 0
      AND toYear(accounting_date) = 2026
    GROUP BY entity_id, period
) AS t
FULL OUTER JOIN
(
    SELECT entity_id, toYYYYMM(accounting_date) AS period,
           count() AS lines, sum(debit_lcy_minor) AS lcy
    FROM finance.journal_entries FINAL
    WHERE source = 'OPERATION'
      AND toYear(accounting_date) = 2026
    GROUP BY entity_id, period
) AS j USING (entity_id, period)
WHERE t.lines != j.lines OR t.lcy != j.lcy
SETTINGS do_not_merge_across_partitions_select_final = 1;

-- 1d. Every manual voucher was approved in Postgres
SELECT throwIf(count() &gt; 0, 'Voucher without approval')
FROM
(
    SELECT DISTINCT tx_id
    FROM finance.journal_entries
    WHERE source != 'OPERATION'
      AND toYear(accounting_date) = 2026
) AS j
LEFT ANTI JOIN
(
    SELECT tx_id
    FROM finance.journal_vouchers FINAL
    WHERE approved_by != '' AND _peerdb_is_deleted = 0
) AS v USING (tx_id);

-- 1e. Every account exists in the chart of accounts
SELECT throwIf(count() &gt; 0, 'Unmapped accounts')
FROM finance.daily_balances
WHERE toYear(accounting_date) = 2026
  AND NOT dictHas('finance.chart_of_accounts',
                  toUInt64(account));</code></code></pre><p>El control 1a no basta por s&#237; solo: una l&#237;nea duplicada tambi&#233;n cuadra. Por eso existen 1b y 1c. El control 1c supone dos l&#237;neas por transacci&#243;n, como en este modelo; si las tuyas generan m&#225;s, compara con el n&#250;mero esperado. El 1e importa porque una cuenta que no est&#225; en el diccionario tendr&#237;a clase 0 y desaparecer&#237;a en silencio de los pasos 3, 4 y 6.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!6RF_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3dc0e47-d5fb-4a36-8f58-3d75b1b1ccc5_1456x1337.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!6RF_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3dc0e47-d5fb-4a36-8f58-3d75b1b1ccc5_1456x1337.png 424w, https://substackcdn.com/image/fetch/$s_!6RF_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3dc0e47-d5fb-4a36-8f58-3d75b1b1ccc5_1456x1337.png 848w, https://substackcdn.com/image/fetch/$s_!6RF_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3dc0e47-d5fb-4a36-8f58-3d75b1b1ccc5_1456x1337.png 1272w, https://substackcdn.com/image/fetch/$s_!6RF_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3dc0e47-d5fb-4a36-8f58-3d75b1b1ccc5_1456x1337.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!6RF_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3dc0e47-d5fb-4a36-8f58-3d75b1b1ccc5_1456x1337.png" width="1456" height="1337" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b3dc0e47-d5fb-4a36-8f58-3d75b1b1ccc5_1456x1337.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1337,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:181412,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/218934197?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3dc0e47-d5fb-4a36-8f58-3d75b1b1ccc5_1456x1337.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!6RF_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3dc0e47-d5fb-4a36-8f58-3d75b1b1ccc5_1456x1337.png 424w, https://substackcdn.com/image/fetch/$s_!6RF_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3dc0e47-d5fb-4a36-8f58-3d75b1b1ccc5_1456x1337.png 848w, https://substackcdn.com/image/fetch/$s_!6RF_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3dc0e47-d5fb-4a36-8f58-3d75b1b1ccc5_1456x1337.png 1272w, https://substackcdn.com/image/fetch/$s_!6RF_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3dc0e47-d5fb-4a36-8f58-3d75b1b1ccc5_1456x1337.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Imagen 13. Arriba, el cuadre correcto. Abajo, el control detecta una l&#237;nea contradictoria inyectada a prop&#243;sito.</figcaption></figure></div><p>El &#250;ltimo eslab&#243;n es Postgres. Al cerrar cada mes comparo conteo, total y huella con una vista de ClickHouse que Postgres consulta a trav&#233;s de <code>pg_clickhouse</code>:</p><pre><code><code>-- ClickHouse: monthly control figures from the CDC table
CREATE VIEW finance.monthly_tx_control AS
SELECT
    entity_id,
    toYYYYMM(accounting_date) AS period,
    count()                   AS tx_count,
    sum(amount_lcy_minor)     AS total_lcy,
    groupBitXor(reinterpretAsInt64(reverse(unhex(left(hex(
        MD5(concat(toString(tx_id), '|',
                   toString(amount_lcy_minor)))), 16)))))
        AS fingerprint
FROM finance.transactions FINAL
WHERE status = 'CONFIRMED' AND _peerdb_is_deleted = 0
GROUP BY entity_id, period
SETTINGS do_not_merge_across_partitions_select_final = 1;</code></code></pre><pre><code><code>-- PostgreSQL: the month in Postgres against ClickHouse
SELECT
    coalesce(p.entity_id, c.entity_id) AS entity_id,
    p.tx_count, c.tx_count AS ch_tx_count,
    p.total_lcy, c.total_lcy AS ch_total_lcy,
    p.tx_count = c.tx_count
        AND p.total_lcy = c.total_lcy
        AND p.fingerprint = c.fingerprint AS matched
FROM
(
    SELECT
        entity_id,
        count(*) AS tx_count,
        sum(amount_lcy_minor) AS total_lcy,
        bit_xor(('x' || left(md5(tx_id::text || '|'
            || amount_lcy_minor), 16))::bit(64)::bigint)
            AS fingerprint
    FROM transactions
    WHERE status = 'CONFIRMED'
      AND accounting_date &gt;= DATE '2026-12-01'
      AND accounting_date &lt;  DATE '2027-01-01'
    GROUP BY entity_id
) AS p
FULL JOIN
(
    SELECT entity_id, tx_count, total_lcy, fingerprint
    FROM ch.monthly_tx_control
    WHERE period = 202612
) AS c
    ON c.entity_id = p.entity_id;</code></code></pre><p>Si alguna fila devuelve <code>matched</code> falso o vac&#237;o, el mes no est&#225; completo en ClickHouse y el cierre no sigue.</p><h3><strong>6.5 Ajustes y cierre de resultados</strong></h3><p><strong>Paso 2. El balance de comprobaci&#243;n con subtotales.</strong></p><pre><code><code>SELECT
    multiIf(
        grouping(account_class) = 1, 'TOTAL',
        grouping(account_group) = 1, 'CLASS',
        grouping(account) = 1,       'GROUP',
        'ACCOUNT') AS row_level,
    dictGet('finance.chart_of_accounts', 'account_class',
            account) AS account_class,
    toUInt16(substring(toString(account), 1, 2))
        AS account_group,
    account,
    dictGet('finance.chart_of_accounts', 'account_name',
            account) AS account_name,
    sum(debit_lcy_minor)  AS total_debit_lcy,
    sum(credit_lcy_minor) AS total_credit_lcy,
    total_debit_lcy - total_credit_lcy AS balance_lcy
FROM finance.daily_balances
WHERE entity_id = 'CO01'
  AND accounting_date BETWEEN '2026-01-01'
                          AND '2026-12-31'
GROUP BY ROLLUP(account_class, account_group, account)
ORDER BY account_class, account_group, account;</code></code></pre><p><code>row_level</code> marca cada fila como cuenta, subtotal de grupo, subtotal de clase o total general; el grupo son los dos primeros d&#237;gitos del c&#243;digo. Como en todo <code>*MergeTree</code>, nunca doy por hecho una fila por clave: siempre <code>sum()</code> y <code>GROUP BY</code>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Of3P!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55f46e00-dbbf-4874-afbd-3e378414e116_1456x1369.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Of3P!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55f46e00-dbbf-4874-afbd-3e378414e116_1456x1369.png 424w, https://substackcdn.com/image/fetch/$s_!Of3P!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55f46e00-dbbf-4874-afbd-3e378414e116_1456x1369.png 848w, https://substackcdn.com/image/fetch/$s_!Of3P!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55f46e00-dbbf-4874-afbd-3e378414e116_1456x1369.png 1272w, https://substackcdn.com/image/fetch/$s_!Of3P!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55f46e00-dbbf-4874-afbd-3e378414e116_1456x1369.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!Of3P!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55f46e00-dbbf-4874-afbd-3e378414e116_1456x1369.png" width="1456" height="1369" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/55f46e00-dbbf-4874-afbd-3e378414e116_1456x1369.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1369,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:188397,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/218934197?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55f46e00-dbbf-4874-afbd-3e378414e116_1456x1369.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Of3P!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55f46e00-dbbf-4874-afbd-3e378414e116_1456x1369.png 424w, https://substackcdn.com/image/fetch/$s_!Of3P!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55f46e00-dbbf-4874-afbd-3e378414e116_1456x1369.png 848w, https://substackcdn.com/image/fetch/$s_!Of3P!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55f46e00-dbbf-4874-afbd-3e378414e116_1456x1369.png 1272w, https://substackcdn.com/image/fetch/$s_!Of3P!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55f46e00-dbbf-4874-afbd-3e378414e116_1456x1369.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Imagen 14. Balance de comprobaci&#243;n con subtotales, calculado sobre los saldos reconstruidos.</figcaption></figure></div><p><strong>Paso 3. Diferencia en cambio.</strong> Reval&#250;o, por tercero, los saldos en moneda extranjera de las cuentas de balance con la &#250;ltima TRM vigente al cierre (las 23:59:59 del 31 de diciembre en Bogot&#225;) y registro la contrapartida en ingresos (421020) o gastos (530525) por diferencia en cambio. Antes registro y apruebo en Postgres el comprobante con su <code>tx_id</code>:</p><pre><code><code>INSERT INTO finance.journal_entries
    (tx_id, line_no, entity_id, accounting_date, event_ts,
     account, cost_center, counterparty_id, currency,
     debit_minor, credit_minor, debit_lcy_minor,
     credit_lcy_minor, source)
SELECT
    {fx_tx_id:UUID} AS tx_id,
    toUInt32(row_number() OVER (
        ORDER BY entity_id, currency, line.1, line.2,
                 line.3, line.4)) AS line_no,
    entity_id,
    toDate('2026-12-31') AS accounting_date,
    toDateTime64('2026-12-31 23:59:59.999', 3,
                 'America/Bogota') AS event_ts,
    line.1 AS account,
    line.2 AS cost_center,
    line.3 AS counterparty_id,
    currency,
    toInt64(0) AS debit_minor,
    toInt64(0) AS credit_minor,
    greatest(line.4, 0) AS debit_lcy_minor,
    greatest(-line.4, 0) AS credit_lcy_minor,
    'ADJUSTMENT' AS source
FROM
(
    SELECT
        b.entity_id,
        b.account         AS revalued_account,
        b.cost_center     AS revalued_cost_center,
        b.counterparty_id AS revalued_counterparty,
        b.currency,
        convert_minor(b.fc_minor, b.currency, 'COP', r.rate)
            - b.lcy_minor AS fx_diff_minor
    FROM
    (
        -- foreign-currency balances of monetary accounts
        SELECT
            entity_id, account, cost_center, counterparty_id,
            currency,
            sum(debit_minor) - sum(credit_minor) AS fc_minor,
            sum(debit_lcy_minor) - sum(credit_lcy_minor)
                AS lcy_minor
        FROM finance.journal_entries FINAL
        WHERE accounting_date BETWEEN '2026-01-01'
                                  AND '2026-12-31'
          AND currency != 'COP'
          AND dictGet('finance.chart_of_accounts',
                      'account_class', account) IN (1, 2)
        GROUP BY entity_id, account, cost_center,
                 counterparty_id, currency
    ) AS b
    INNER JOIN
    (
        -- latest official rate before the cut-off
        SELECT currency, argMax(rate, valid_from) AS rate
        FROM finance.fx_rates
        WHERE rate_source = 'TRM'
          AND valid_from &lt; toDateTime64(
              '2027-01-01 00:00:00', 3, 'America/Bogota')
        GROUP BY currency
    ) AS r ON b.currency = r.currency
    WHERE fx_diff_minor != 0
)
ARRAY JOIN [
    -- revalued account, per counterparty
    (revalued_account, revalued_cost_center,
     revalued_counterparty, fx_diff_minor),
    -- FX gain (421020) or loss (530525)
    (if(fx_diff_minor &gt; 0, 421020, 530525), 'CORP',
     toInt64(0), -fx_diff_minor)
] AS line
SETTINGS do_not_merge_across_partitions_select_final = 1;</code></code></pre><p>Cada ajuste genera dos l&#237;neas que se compensan, as&#237; que el comprobante cuadra por construcci&#243;n. Revaluar por tercero mantiene cuadrados los auxiliares de cartera y proveedores. Filtrar las clases 1 y 2 es una simplificaci&#243;n: seg&#250;n la NIC 21 solo se reval&#250;an las partidas monetarias, y no los inventarios, las propiedades, los intangibles, los gastos pagados por anticipado ni los anticipos dados o recibidos. En producci&#243;n el filtro sale del plan de cuentas. Las horas del corte van en la zona horaria de Bogot&#225; y ClickHouse las convierte a UTC al comparar y al guardar; con <code>'UTC'</code> el corte quedar&#237;a cinco horas antes.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Esta diferencia en cambio es contable (NIIF). En lo fiscal, la diferencia no realizada no tiene efecto hasta su realizaci&#243;n (art&#237;culo 288 del Estatuto Tributario), genera impuesto diferido y debe quedar en el control de diferencias y en el reporte de conciliaci&#243;n fiscal (formato 2516).</p><p>Renombr&#233; <code>account</code>, <code>cost_center</code> y <code>counterparty_id</code> en la subconsulta porque en ClickHouse un alias tiene prioridad sobre una columna del mismo nombre y, sin ese cambio, la consulta falla con un error de identificador desconocido. Me pas&#243; en la primera versi&#243;n. Por lo mismo, cuando un total se reutiliza en el mismo <code>SELECT</code> (control 1a, balance de comprobaci&#243;n) lo llamo <code>total_debit</code> y no <code>debit_minor</code>.</p><p>Si la inserci&#243;n se interrumpe y la repito tal cual, con los mismos saldos de entrada, las l&#237;neas repetidas se colapsan como las del CDC: el <code>row_number</code> ordena por la tupla completa y numera igual. Si algo cambi&#243; entre los dos intentos, el control 1b lo detecta; en ese caso, y siempre que haya que corregir un comprobante ya registrado, se revierte y se registra uno nuevo con otro <code>tx_id</code>.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p><strong>Paso 4. Cerrar las cuentas de resultado.</strong> Antes de este paso ya est&#225;n registrados el impuesto de renta corriente y diferido (NIC 12), las provisiones, las depreciaciones y las reclasificaciones, y la clase 7 (costos de producci&#243;n) ya se traslad&#243; a la 6 o al inventario. Repito el paso 0 y cierro las clases 4, 5 y 6 contra la utilidad (3605) o la p&#233;rdida (3610) del ejercicio:</p><pre><code><code>INSERT INTO finance.journal_entries
    (tx_id, line_no, entity_id, accounting_date, event_ts,
     account, cost_center, counterparty_id, currency,
     debit_minor, credit_minor, debit_lcy_minor,
     credit_lcy_minor, source)
SELECT
    {closing_tx_id:UUID} AS tx_id,
    toUInt32(row_number() OVER (
        ORDER BY entity_id, currency, is_offset, account,
                 cost_center)) AS line_no,
    entity_id,
    toDate('2026-12-31') AS accounting_date,
    toDateTime64('2026-12-31 23:59:59.999', 3,
                 'America/Bogota') AS event_ts,
    account,
    cost_center,
    0 AS counterparty_id,
    currency,
    -- post the opposite of each balance
    greatest(-fc_minor, 0)  AS debit_minor,
    greatest(fc_minor, 0)   AS credit_minor,
    greatest(-lcy_minor, 0) AS debit_lcy_minor,
    greatest(lcy_minor, 0)  AS credit_lcy_minor,
    'CLOSING' AS source
FROM
(
    -- lines that bring each income-statement account to 0
    SELECT
        entity_id, account, cost_center, currency,
        0 AS is_offset,
        sum(debit_minor) - sum(credit_minor) AS fc_minor,
        sum(debit_lcy_minor) - sum(credit_lcy_minor)
            AS lcy_minor
    FROM finance.daily_balances
    WHERE accounting_date BETWEEN '2026-01-01'
                              AND '2026-12-31'
      AND dictGet('finance.chart_of_accounts',
                  'account_class', account) IN (4, 5, 6)
    GROUP BY entity_id, account, cost_center, currency
    HAVING fc_minor != 0 OR lcy_minor != 0

    UNION ALL

    -- offset per entity and currency. Profit (3605) or
    -- loss (3610) is decided on the entity's total result
    -- in functional currency, not per currency.
    SELECT
        entity_id,
        if(sum(sum(debit_lcy_minor) - sum(credit_lcy_minor))
               OVER (PARTITION BY entity_id) &lt;= 0,
           3605, 3610) AS offset_account,
        'CORP' AS offset_cost_center,
        currency,
        1 AS is_offset,
        sum(credit_minor) - sum(debit_minor) AS offset_fc,
        sum(credit_lcy_minor) - sum(debit_lcy_minor)
            AS offset_lcy
    FROM finance.daily_balances
    WHERE accounting_date BETWEEN '2026-01-01'
                              AND '2026-12-31'
      AND dictGet('finance.chart_of_accounts',
                  'account_class', account) IN (4, 5, 6)
    GROUP BY entity_id, currency
    HAVING offset_fc != 0 OR offset_lcy != 0
);</code></code></pre><p>La cuenta de utilidad o p&#233;rdida se elige con el resultado total de la entidad en moneda funcional. Las l&#237;neas de contrapartida se separan por moneda solo para que el control 1a siga cuadrando por moneda; el resultado del ejercicio solo tiene sentido en moneda funcional, y as&#237; se presenta.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Si tu entidad pasa primero por la 5905 (Ganancias y p&#233;rdidas), excl&#250;yela del filtro de la clase 5. En el segundo bloque los alias tienen nombres distintos (<code>offset_account</code>) por la misma raz&#243;n de antes: <code>UNION ALL</code> toma los nombres del primer <code>SELECT</code>, y <code>account</code> en el <code>WHERE</code> debe seguir siendo la columna.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!IZaP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c739a0d-4ceb-4d0f-9621-8f8c07ba2642_1456x1373.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!IZaP!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c739a0d-4ceb-4d0f-9621-8f8c07ba2642_1456x1373.png 424w, https://substackcdn.com/image/fetch/$s_!IZaP!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c739a0d-4ceb-4d0f-9621-8f8c07ba2642_1456x1373.png 848w, https://substackcdn.com/image/fetch/$s_!IZaP!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c739a0d-4ceb-4d0f-9621-8f8c07ba2642_1456x1373.png 1272w, https://substackcdn.com/image/fetch/$s_!IZaP!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c739a0d-4ceb-4d0f-9621-8f8c07ba2642_1456x1373.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!IZaP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c739a0d-4ceb-4d0f-9621-8f8c07ba2642_1456x1373.png" width="1456" height="1373" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5c739a0d-4ceb-4d0f-9621-8f8c07ba2642_1456x1373.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1373,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:152347,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/218934197?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c739a0d-4ceb-4d0f-9621-8f8c07ba2642_1456x1373.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!IZaP!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c739a0d-4ceb-4d0f-9621-8f8c07ba2642_1456x1373.png 424w, https://substackcdn.com/image/fetch/$s_!IZaP!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c739a0d-4ceb-4d0f-9621-8f8c07ba2642_1456x1373.png 848w, https://substackcdn.com/image/fetch/$s_!IZaP!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c739a0d-4ceb-4d0f-9621-8f8c07ba2642_1456x1373.png 1272w, https://substackcdn.com/image/fetch/$s_!IZaP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c739a0d-4ceb-4d0f-9621-8f8c07ba2642_1456x1373.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Imagen 15. El comprobante de cierre cuadra y deja las cuentas de resultado en cero.</figcaption></figure></div><p><strong>Paso 5. Reconstruir y comprobar.</strong> Repito el paso 0 y los controles 1a, 1b y 1d, y compruebo que no qued&#243; ninguna cuenta de resultado con saldo:</p><pre><code><code>-- 5. No income-statement account may keep a balance
SELECT throwIf(count() &gt; 0, 'P&amp;L not closed')
FROM
(
    SELECT entity_id, account, currency
    FROM finance.daily_balances
    WHERE toYear(accounting_date) = 2026
      AND dictGet('finance.chart_of_accounts',
                  'account_class', account) IN (4, 5, 6)
    GROUP BY entity_id, account, currency
    HAVING sum(debit_lcy_minor) != sum(credit_lcy_minor)
        OR sum(debit_minor) != sum(credit_minor)
);</code></code></pre><h3><strong>6.6 Apertura, sellado y archivo</strong></h3><p><strong>Paso 6. Saldos de apertura de 2027.</strong> Traslado los saldos de las clases 1, 2 y 3 por tercero, para que la cartera y los proveedores conserven su detalle:</p><pre><code><code>INSERT INTO finance.journal_entries
    (tx_id, line_no, entity_id, accounting_date, event_ts,
     account, cost_center, counterparty_id, currency,
     debit_minor, credit_minor, debit_lcy_minor,
     credit_lcy_minor, source)
SELECT
    {opening_tx_id:UUID} AS tx_id,
    toUInt32(row_number() OVER (
        ORDER BY entity_id, currency, account, cost_center,
                 counterparty_id)) AS line_no,
    entity_id,
    toDate('2027-01-01') AS accounting_date,
    toDateTime64('2027-01-01 00:00:00', 3,
                 'America/Bogota') AS event_ts,
    account,
    cost_center,
    counterparty_id,
    currency,
    greatest(fc_minor, 0)   AS debit_minor,
    greatest(-fc_minor, 0)  AS credit_minor,
    greatest(lcy_minor, 0)  AS debit_lcy_minor,
    greatest(-lcy_minor, 0) AS credit_lcy_minor,
    'OPENING' AS source
FROM
(
    SELECT
        entity_id, account, cost_center, counterparty_id,
        currency,
        sum(debit_minor) - sum(credit_minor) AS fc_minor,
        sum(debit_lcy_minor) - sum(credit_lcy_minor)
            AS lcy_minor
    FROM finance.journal_entries FINAL
    WHERE accounting_date BETWEEN '2026-01-01'
                              AND '2026-12-31'
      AND dictGet('finance.chart_of_accounts',
                  'account_class', account) IN (1, 2, 3)
    GROUP BY entity_id, account, cost_center,
             counterparty_id, currency
    HAVING fc_minor != 0 OR lcy_minor != 0
)
SETTINGS do_not_merge_across_partitions_select_final = 1;</code></code></pre><p>Con las cuentas de resultado en cero y la clase 7 ya trasladada, los saldos de las clases 1, 2 y 3 suman cero y la apertura cuadra sola. Las cuentas de orden (clases 8 y 9) se trasladan aparte. La utilidad o p&#233;rdida del a&#241;o (3605 o 3610) entra a 2027 tal cual y se reclasifica a utilidades acumuladas o reservas cuando la asamblea decide su destino. Desde aqu&#237;, las consultas de 2027 parten de la apertura y no necesitan leer 2026.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p><strong>Paso 7. Sellar el a&#241;o.</strong> Calculo la huella de cada mes y la guardo en Postgres con el acta de cierre; si dentro de cinco a&#241;os alguien vuelve a calcularla y no coincide, algo cambi&#243;. Despu&#233;s respaldo el a&#241;o en un bucket con bloqueo de objetos y guardo una copia del plan de cuentas tal como estaba, porque el diccionario se refresca y en diez a&#241;os los nombres y las clases pueden ser otros:</p><pre><code><code>-- 7a. Closing fingerprint per month
SELECT
    toYYYYMM(accounting_date) AS period,
    count()                   AS line_count,
    sum(debit_lcy_minor)      AS total_debit_lcy,
    sum(credit_lcy_minor)     AS total_credit_lcy,
    groupBitXor(cityHash64(tx_id, line_no, account,
        currency, debit_minor, credit_minor,
        debit_lcy_minor, credit_lcy_minor)) AS fingerprint
FROM finance.journal_entries FINAL
WHERE accounting_date BETWEEN '2026-01-01'
                          AND '2026-12-31'
GROUP BY period
ORDER BY period
SETTINGS do_not_merge_across_partitions_select_final = 1;

-- 7b. Back up the year to the object-locked bucket
BACKUP TABLE finance.journal_entries
    PARTITIONS '202601', '202602', '202603', '202604',
               '202605', '202606', '202607', '202608',
               '202609', '202610', '202611', '202612'
TO S3(s3_worm, '2026/journal_entries');

-- 7c. Freeze the chart of accounts used for 2026
CREATE TABLE finance.chart_of_accounts_2026
ENGINE = MergeTree ORDER BY account AS
SELECT * FROM dictionary('finance.chart_of_accounts');</code></code></pre><p>Los datos de 2026 se quedan en <code>journal_entries</code>. Lo que impide cambiarlos es que solo el rol del proceso de cierre tiene <code>INSERT</code> sobre la tabla, que todo comprobante manual exige aprobaci&#243;n en Postgres (control 1d) y que la huella delatar&#237;a cualquier cambio. Vale la pena darle a <code>journal_vouchers</code> la misma validaci&#243;n de periodo que tiene el disparador de <code>transactions</code>. ClickHouse Cloud hace adem&#225;s sus propias copias autom&#225;ticas.</p><p><strong>Paso 8. Exportar para la retenci&#243;n legal.</strong></p><pre><code><code>INSERT INTO FUNCTION s3(s3_worm,
    filename = 'legal-archive/2026/{_partition_id}.parquet',
    format = 'Parquet')
PARTITION BY toYYYYMM(accounting_date)
SELECT *
FROM finance.journal_entries FINAL
WHERE toYear(accounting_date) = 2026
SETTINGS do_not_merge_across_partitions_select_final = 1;</code></code></pre><p>Va al bucket con bloqueo, como el respaldo. Eleg&#237; Parquet porque dentro de diez a&#241;os se podr&#225; leer con DuckDB, Spark o pandas, sin depender de ClickHouse.</p><h3><strong>6.7 Despu&#233;s del cierre</strong></h3><p>Diciembre se queda en <code>CLOSING</code> hasta que la asamblea aprueba los estados financieros (en marzo, como tarde) y solo entonces pasa a <code>CLOSED</code>. Si el auditor pide un ajuste despu&#233;s de registrar la apertura, registro el ajuste, un comprobante complementario de cierre de resultados (paso 4) y otro de apertura por la diferencia (paso 6), repito los pasos 0, 1 y 5 y vuelvo a sellar y exportar (pasos 7 y 8) con otra ruta de destino. La huella que vale es la del a&#241;o que aprueba la asamblea. Un error material de a&#241;os anteriores no se corrige en el resultado del a&#241;o: la NIC 8 exige reexpresi&#243;n retroactiva contra las ganancias acumuladas.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Si la moneda funcional de la entidad no es el peso, <code>amount_lcy_minor</code> va en esa moneda y los estados financieros necesitan adem&#225;s una conversi&#243;n a la moneda de presentaci&#243;n.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!D2UE!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F362a62eb-16c9-461d-9ed2-525924877e2d_1456x783.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!D2UE!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F362a62eb-16c9-461d-9ed2-525924877e2d_1456x783.png 424w, https://substackcdn.com/image/fetch/$s_!D2UE!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F362a62eb-16c9-461d-9ed2-525924877e2d_1456x783.png 848w, https://substackcdn.com/image/fetch/$s_!D2UE!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F362a62eb-16c9-461d-9ed2-525924877e2d_1456x783.png 1272w, https://substackcdn.com/image/fetch/$s_!D2UE!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F362a62eb-16c9-461d-9ed2-525924877e2d_1456x783.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!D2UE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F362a62eb-16c9-461d-9ed2-525924877e2d_1456x783.png" width="1456" height="783" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/362a62eb-16c9-461d-9ed2-525924877e2d_1456x783.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:783,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:98655,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/218934197?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F362a62eb-16c9-461d-9ed2-525924877e2d_1456x783.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!D2UE!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F362a62eb-16c9-461d-9ed2-525924877e2d_1456x783.png 424w, https://substackcdn.com/image/fetch/$s_!D2UE!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F362a62eb-16c9-461d-9ed2-525924877e2d_1456x783.png 848w, https://substackcdn.com/image/fetch/$s_!D2UE!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F362a62eb-16c9-461d-9ed2-525924877e2d_1456x783.png 1272w, https://substackcdn.com/image/fetch/$s_!D2UE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F362a62eb-16c9-461d-9ed2-525924877e2d_1456x783.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Imagen 16. Comparaci&#243;n cualitativa: los tiempos reales dependen del modelo y del hardware.</figcaption></figure></div><h2><strong>7. Datos personales y seguridad</strong></h2><p>Un libro de pagos est&#225; lleno de datos personales: nombres, c&#233;dulas, correos, tel&#233;fonos, cuentas bancarias, llaves de Bre-B (que pueden ser un celular, un correo o un n&#250;mero de documento) y, si hay tarjetas, n&#250;meros de tarjeta. La Ley 1581 de 2012, el Reglamento General de Protecci&#243;n de Datos europeo (GDPR) si hay clientes en la Uni&#243;n Europea y PCI DSS si hay tarjetas ponen reglas distintas, pero llevan al mismo dise&#241;o: el almac&#233;n anal&#237;tico no necesita saber qui&#233;n es cada persona.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!yHxk!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1c74b55-3a97-4901-8556-65df7603aee6_1456x783.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!yHxk!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1c74b55-3a97-4901-8556-65df7603aee6_1456x783.png 424w, https://substackcdn.com/image/fetch/$s_!yHxk!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1c74b55-3a97-4901-8556-65df7603aee6_1456x783.png 848w, https://substackcdn.com/image/fetch/$s_!yHxk!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1c74b55-3a97-4901-8556-65df7603aee6_1456x783.png 1272w, https://substackcdn.com/image/fetch/$s_!yHxk!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1c74b55-3a97-4901-8556-65df7603aee6_1456x783.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!yHxk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1c74b55-3a97-4901-8556-65df7603aee6_1456x783.png" width="1456" height="783" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e1c74b55-3a97-4901-8556-65df7603aee6_1456x783.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:783,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:98655,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/218934197?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1c74b55-3a97-4901-8556-65df7603aee6_1456x783.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!yHxk!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1c74b55-3a97-4901-8556-65df7603aee6_1456x783.png 424w, https://substackcdn.com/image/fetch/$s_!yHxk!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1c74b55-3a97-4901-8556-65df7603aee6_1456x783.png 848w, https://substackcdn.com/image/fetch/$s_!yHxk!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1c74b55-3a97-4901-8556-65df7603aee6_1456x783.png 1272w, https://substackcdn.com/image/fetch/$s_!yHxk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1c74b55-3a97-4901-8556-65df7603aee6_1456x783.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Imagen 17. Cada dato personal con su tratamiento en el dise&#241;o.</figcaption></figure></div><h3><strong>7.1 Seud&#243;nimos en el libro, identidad en Postgres</strong></h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!t1Il!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc20426d-6773-4abc-b648-00f53fd978ce_1456x742.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!t1Il!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc20426d-6773-4abc-b648-00f53fd978ce_1456x742.png 424w, https://substackcdn.com/image/fetch/$s_!t1Il!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc20426d-6773-4abc-b648-00f53fd978ce_1456x742.png 848w, https://substackcdn.com/image/fetch/$s_!t1Il!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc20426d-6773-4abc-b648-00f53fd978ce_1456x742.png 1272w, https://substackcdn.com/image/fetch/$s_!t1Il!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc20426d-6773-4abc-b648-00f53fd978ce_1456x742.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!t1Il!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc20426d-6773-4abc-b648-00f53fd978ce_1456x742.png" width="1456" height="742" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cc20426d-6773-4abc-b648-00f53fd978ce_1456x742.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:742,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:92437,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/218934197?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc20426d-6773-4abc-b648-00f53fd978ce_1456x742.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!t1Il!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc20426d-6773-4abc-b648-00f53fd978ce_1456x742.png 424w, https://substackcdn.com/image/fetch/$s_!t1Il!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc20426d-6773-4abc-b648-00f53fd978ce_1456x742.png 848w, https://substackcdn.com/image/fetch/$s_!t1Il!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc20426d-6773-4abc-b648-00f53fd978ce_1456x742.png 1272w, https://substackcdn.com/image/fetch/$s_!t1Il!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc20426d-6773-4abc-b648-00f53fd978ce_1456x742.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Imagen 18. La identidad de las personas no sale de Postgres.</figcaption></figure></div><p>El libro de ClickHouse solo guarda <code>counterparty_id</code>, una clave sustituta. Los datos personales viven en Postgres, cifrados por la aplicaci&#243;n, y no se replican. Para cruzar con fuentes externas, como listas de sanciones, uso un HMAC de la c&#233;dula que calcula la aplicaci&#243;n con un secreto guardado fuera de ambas bases de datos.</p><pre><code><code>-- PostgreSQL 15+: identity data stays here, encrypted
CREATE TABLE parties (
    party_id           bigint  PRIMARY KEY,
    party_key          char(64),  -- hex HMAC-SHA256 of ID
    country_code       char(2) NOT NULL,  -- ISO 3166-1
    full_name_enc      bytea,     -- encrypted by the app
    national_id_enc    bytea,
    email_enc          bytea,
    phone_enc          bytea,
    -- address, Bre-B key and bank account: same pattern
    processing_blocked boolean NOT NULL DEFAULT false,
    retention_until    date
);

-- Optional second layer, only if you create the
-- publication yourself and give its name to ClickPipes
CREATE PUBLICATION clickhouse_cdc
    FOR TABLE transactions, accounting_periods,
              journal_vouchers,
              parties (party_id, party_key, country_code,
                       processing_blocked);</code></code></pre><p>La barrera que documenta ClickPipes es la exclusi&#243;n de columnas al configurar el pipe: en <code>parties</code> excluyo las columnas cifradas. Una columna excluida no se puede volver a incluir sin resincronizar la tabla, que es justo lo que quiero. ClickPipes crea por defecto su propia publicaci&#243;n; la lista de columnas en la publicaci&#243;n (PostgreSQL 15 o superior) solo aplica si la creas t&#250;, y la uso como capa adicional, nunca como la &#250;nica. La documentaci&#243;n de Postgres advierte adem&#225;s que las listas de columnas no son un mecanismo de seguridad. Evito <code>REPLICA IDENTITY FULL</code> en tablas con datos personales porque escribe la fila completa en el WAL.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Aqu&#237; la retenci&#243;n contable choca con el derecho de supresi&#243;n. Los libros, sus soportes y la informaci&#243;n de terceros se conservan diez a&#241;os contados desde el &#250;ltimo asiento, documento o comprobante (art&#237;culo 28 de la Ley 962 de 2005, que modific&#243; el art&#237;culo 60 del C&#243;digo de Comercio), y esa identidad tambi&#233;n soporta la informaci&#243;n ex&#243;gena y el SARLAFT o el SAGRILAFT, seg&#250;n el supervisor. La Ley 1581, por su parte, da derecho a pedir la supresi&#243;n.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p><p>El art&#237;culo 9 del Decreto 1377 de 2013 resuelve el choque: mientras exista el deber legal de conservar, la supresi&#243;n no procede sobre esos datos. Se le responde al titular con la causal, se bloquean los datos para cualquier otra finalidad y se borran al vencer el plazo. Lo que no tiene deber de conservaci&#243;n, como el correo o el tel&#233;fono de contacto, s&#237; se borra de inmediato:</p><pre><code><code>-- PostgreSQL: erasure request for party 42.
-- Contact data has no retention duty: delete it now.
-- Identity data backs accounting, tax and AML records:
-- block it and delete it when the retention period ends.
UPDATE parties
SET email_enc          = NULL,
    phone_enc          = NULL,
    processing_blocked = true
WHERE party_id = 42;

-- Scheduled job: purge identity data after retention
UPDATE parties
SET full_name_enc   = NULL,
    national_id_enc = NULL,
    party_key       = NULL
WHERE processing_blocked
  AND retention_until &lt; current_date;</code></code></pre><pre><code><code>-- ClickHouse: after the purge job, drop the previous
-- version of each row (the one that still holds the HMAC)
OPTIMIZE TABLE finance.parties FINAL;</code></code></pre><p><code>processing_blocked</code> s&#237; se replica: cualquier an&#225;lisis de mercadeo o perfilamiento en ClickHouse debe excluir a esos terceros. Cuando el trabajo programado borra la identidad, el cambio llega a ClickHouse como una versi&#243;n nueva de la fila, con <code>party_key</code> vac&#237;o. La versi&#243;n anterior, con el HMAC, sigue en disco hasta la siguiente fusi&#243;n; <code>OPTIMIZE ... FINAL</code> la adelanta, y en una tabla peque&#241;a como <code>parties</code> es barato. Las copias de seguridad guardan la versi&#243;n anterior hasta que vencen.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Si hay titulares en la Uni&#243;n Europea, el GDPR no ofrece la misma salida: la excepci&#243;n del art&#237;culo 17.3.b exige una obligaci&#243;n del derecho de la Uni&#243;n o de un Estado miembro, y una norma colombiana no basta. Ese caso requiere otro an&#225;lisis. Y en ambos reg&#237;menes, los datos seudonimizados siguen siendo datos personales.</p><h3><strong>7.2 Controles en ClickHouse</strong></h3><p>El primer control es el permiso por columna, que funciona en cualquier edici&#243;n. Un analista consulta las l&#237;neas de asiento sin ver el identificador del tercero:</p><pre><code><code>CREATE ROLE analyst_role;
GRANT SELECT(tx_id, line_no, entity_id, accounting_date,
             account, cost_center, currency, debit_minor,
             credit_minor, debit_lcy_minor, credit_lcy_minor,
             source)
    ON finance.journal_entries TO analyst_role;</code></code></pre><p>Si ese rol pide <code>counterparty_id</code>, ClickHouse responde con un error de acceso denegado, no con filas vac&#237;as, y as&#237; nadie lo pasa por alto. Lo mismo pasa con un <code>SELECT *</code>, que obliga a listar las columnas permitidas.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!HTzb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f639b0d-1022-4449-ace9-eef909d47d7b_1456x833.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!HTzb!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f639b0d-1022-4449-ace9-eef909d47d7b_1456x833.png 424w, https://substackcdn.com/image/fetch/$s_!HTzb!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f639b0d-1022-4449-ace9-eef909d47d7b_1456x833.png 848w, https://substackcdn.com/image/fetch/$s_!HTzb!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f639b0d-1022-4449-ace9-eef909d47d7b_1456x833.png 1272w, https://substackcdn.com/image/fetch/$s_!HTzb!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f639b0d-1022-4449-ace9-eef909d47d7b_1456x833.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!HTzb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f639b0d-1022-4449-ace9-eef909d47d7b_1456x833.png" width="1456" height="833" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3f639b0d-1022-4449-ace9-eef909d47d7b_1456x833.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:833,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:88632,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/218934197?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f639b0d-1022-4449-ace9-eef909d47d7b_1456x833.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!HTzb!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f639b0d-1022-4449-ace9-eef909d47d7b_1456x833.png 424w, https://substackcdn.com/image/fetch/$s_!HTzb!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f639b0d-1022-4449-ace9-eef909d47d7b_1456x833.png 848w, https://substackcdn.com/image/fetch/$s_!HTzb!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f639b0d-1022-4449-ace9-eef909d47d7b_1456x833.png 1272w, https://substackcdn.com/image/fetch/$s_!HTzb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f639b0d-1022-4449-ace9-eef909d47d7b_1456x833.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Imagen 19. El permiso por columna en acci&#243;n.</figcaption></figure></div><p>En ClickHouse Cloud, desde la versi&#243;n 25.12, hay adem&#225;s pol&#237;ticas de enmascaramiento que transforman una columna al consultarla. Son exclusivas de Cloud: la versi&#243;n de c&#243;digo abierto responde &#8220;Masking Policies are available only in ClickHouse Cloud&#8221;.</p><pre><code><code>-- ClickHouse Cloud 25.12+ only
CREATE MASKING POLICY mask_counterparty
    ON finance.journal_entries
    UPDATE counterparty_id = 0
    TO bi_role;</code></code></pre><p>Con las pol&#237;ticas de fila hay una trampa que comprob&#233;: un usuario sin ninguna pol&#237;tica sobre una tabla ve todas sus filas, aunque otros roles tengan pol&#237;ticas restrictivas. Por eso concedo acceso solo a trav&#233;s de roles y defino una pol&#237;tica para cada uno.</p><pre><code><code>CREATE ROW POLICY entity_co01_only
    ON finance.journal_entries
    FOR SELECT USING entity_id = 'CO01'
    TO co01_accountant_role;</code></code></pre><p>Y adem&#225;s:</p><ul><li><p>Las claves escritas como literales en funciones como <code>encrypt</code> o <code>HMAC</code> pueden quedar en <code>system.query_log</code>; la documentaci&#243;n de <code>query_masking_rules</code> describe ese riesgo. Las credenciales de Postgres y del almacenamiento van en <em>named collections</em> y los secretos de cifrado se usan antes de que el dato llegue a ClickHouse. El acceso a <code>query_log</code> tambi&#233;n se restringe.</p></li><li><p>Solo el rol del proceso de cierre tiene <code>INSERT</code> sobre <code>journal_entries</code>; el usuario de ClickPipes escribe en las tablas del CDC y las vistas hacen el resto.</p></li><li><p>En ClickHouse Cloud el cifrado en reposo viene activado por defecto. El cifrado con clave del cliente (CMEK) requiere el plan Enterprise, y borrar esa clave inutiliza el servicio completo; el borrado criptogr&#225;fico de una persona se hace en la aplicaci&#243;n, con una clave por titular.</p></li><li><p><code>DELETE</code>, las mutaciones y el TTL borran al fusionar, y los respaldos guardan rastros.</p></li><li><p>Desde el 31 de marzo de 2025, PCI DSS 4.0.1 exige que, si se usa un hash para hacer ilegible el n&#250;mero de tarjeta, sea un hash con clave (requisito 3.5.1.1), y deja de aceptar el cifrado de disco como &#250;nica protecci&#243;n salvo en medios extra&#237;bles (3.5.1.2). El truncamiento m&#225;ximo depende de la longitud y la marca (hasta los primeros 8 y los &#250;ltimos 4 en tarjetas de 16 d&#237;gitos), y las versiones truncada y con hash de una misma tarjeta no deben poder correlacionarse. Lo m&#225;s simple es guardar solo el token de la pasarela, y con eso el almac&#233;n queda fuera del alcance de PCI.</p></li><li><p>Las claves de idempotencia tampoco llevan datos personales. Uso UUID v4, con <code>UNIQUE</code> en Postgres como fuente de verdad.</p></li></ul><h3><strong>7.3 Normas colombianas</strong></h3><p>Las regiones de ClickHouse Cloud est&#225;n fuera de Colombia (la m&#225;s cercana es S&#227;o Paulo). Aun con seud&#243;nimos hay transmisi&#243;n internacional, porque <code>counterparty_id</code> y el HMAC siguen siendo datos personales: se necesita un contrato de transmisi&#243;n con el encargado o las cl&#225;usulas contractuales modelo de la Red Iberoamericana de Protecci&#243;n de Datos, que la SIC adopt&#243; como opcionales en la Circular Externa 003 de 2025. La Circular Externa 002 de 2025 aplica adem&#225;s si hay transferencia de tecnolog&#237;a. Las entidades vigiladas por la Superintendencia Financiera tienen tambi&#233;n las reglas de computaci&#243;n en la nube de la Circular Externa 005 de 2019 y los requisitos de ciberseguridad de la Circular Externa 007 de 2018.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Si la entidad presta servicios financieros digitales (cr&#233;dito, dep&#243;sitos de bajo monto o billeteras), revisa la Circular Externa 001 de 2025 de la SIC, que seg&#250;n los an&#225;lisis publicados exige minimizaci&#243;n, plazos de supresi&#243;n y consentimientos separados. El registro de bases de datos ante la SIC es obligatorio para las sociedades y entidades sin &#225;nimo de lucro con activos superiores a 100 000 UVT y para las personas jur&#237;dicas de naturaleza p&#250;blica.</p><p>No soy abogado: esto es lo que encontr&#233; al revisar las normas para dise&#241;ar el sistema. Val&#237;dalo con tu &#225;rea jur&#237;dica antes de implementarlo.</p><h2><strong>8. ClickHouse Cloud</strong></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!kkET!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffb23271-8b03-4886-980a-8fd309976bd7_1456x662.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!kkET!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffb23271-8b03-4886-980a-8fd309976bd7_1456x662.png 424w, https://substackcdn.com/image/fetch/$s_!kkET!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffb23271-8b03-4886-980a-8fd309976bd7_1456x662.png 848w, https://substackcdn.com/image/fetch/$s_!kkET!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffb23271-8b03-4886-980a-8fd309976bd7_1456x662.png 1272w, https://substackcdn.com/image/fetch/$s_!kkET!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffb23271-8b03-4886-980a-8fd309976bd7_1456x662.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!kkET!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffb23271-8b03-4886-980a-8fd309976bd7_1456x662.png" width="1456" height="662" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ffb23271-8b03-4886-980a-8fd309976bd7_1456x662.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:662,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:82020,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/218934197?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffb23271-8b03-4886-980a-8fd309976bd7_1456x662.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!kkET!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffb23271-8b03-4886-980a-8fd309976bd7_1456x662.png 424w, https://substackcdn.com/image/fetch/$s_!kkET!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffb23271-8b03-4886-980a-8fd309976bd7_1456x662.png 848w, https://substackcdn.com/image/fetch/$s_!kkET!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffb23271-8b03-4886-980a-8fd309976bd7_1456x662.png 1272w, https://substackcdn.com/image/fetch/$s_!kkET!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffb23271-8b03-4886-980a-8fd309976bd7_1456x662.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Imagen 20. Varios servicios de c&#243;mputo sobre los mismos datos.</figcaption></figure></div><p>Operar un cl&#250;ster de ClickHouse que recibe 7200 millones de filas al a&#241;o (r&#233;plicas, fragmentos, discos, actualizaciones, respaldos) pide un equipo dedicado. En Cloud eso lo opera ClickHouse: los datos viven en almacenamiento de objetos en una sola copia y el almacenamiento crece sin redimensionar discos.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Para el cierre, lo m&#225;s &#250;til fue separar el c&#243;mputo. Varios servicios leen los mismos datos: uno estable para la ingesta, otro para el cierre que agrando en diciembre y enero y apago el resto del a&#241;o, uno de solo lectura para BI con escalado autom&#225;tico y otro para auditores, con sus propios usuarios y red, que solo enciendo durante la auditor&#237;a. As&#237; el cierre no le quita CPU a la ingesta, y el servicio grande solo lo enciendo, de diciembre a marzo, cuando hay que correr el cierre.</p><p>ClickPipes, adem&#225;s del CDC de Postgres, se conecta a Kafka y servicios compatibles, a los servicios de streaming y almacenamiento de objetos de los principales proveedores de nube, y ofrece CDC para MySQL y MongoDB; algunos conectores siguen en vista previa. En cumplimiento, ClickHouse Cloud tiene SOC 2 Tipo II desde 2022, ISO 27001 desde 2023, HIPAA desde 2024 y PCI DSS desde 2025, con los informes en su <a href="https://trust.clickhouse.com/">Trust Center</a>. HIPAA y PCI DSS requieren el plan Enterprise; la conectividad privada est&#225; disponible desde el plan Scale.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!euXh!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73deaef5-75ec-4f63-abd9-2dee28866c87_1456x982.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!euXh!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73deaef5-75ec-4f63-abd9-2dee28866c87_1456x982.png 424w, https://substackcdn.com/image/fetch/$s_!euXh!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73deaef5-75ec-4f63-abd9-2dee28866c87_1456x982.png 848w, https://substackcdn.com/image/fetch/$s_!euXh!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73deaef5-75ec-4f63-abd9-2dee28866c87_1456x982.png 1272w, https://substackcdn.com/image/fetch/$s_!euXh!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73deaef5-75ec-4f63-abd9-2dee28866c87_1456x982.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!euXh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73deaef5-75ec-4f63-abd9-2dee28866c87_1456x982.png" width="1456" height="982" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/73deaef5-75ec-4f63-abd9-2dee28866c87_1456x982.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:982,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:133174,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/218934197?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73deaef5-75ec-4f63-abd9-2dee28866c87_1456x982.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!euXh!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73deaef5-75ec-4f63-abd9-2dee28866c87_1456x982.png 424w, https://substackcdn.com/image/fetch/$s_!euXh!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73deaef5-75ec-4f63-abd9-2dee28866c87_1456x982.png 848w, https://substackcdn.com/image/fetch/$s_!euXh!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73deaef5-75ec-4f63-abd9-2dee28866c87_1456x982.png 1272w, https://substackcdn.com/image/fetch/$s_!euXh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73deaef5-75ec-4f63-abd9-2dee28866c87_1456x982.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Imagen 21. Las capacidades que m&#225;s uso en un sistema financiero.</figcaption></figure></div><h2><strong>9. ClickHouse Managed Postgres y pg_clickhouse</strong></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!_-GN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc97daa27-a619-4cb0-825b-3517d30e1f80_1456x662.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!_-GN!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc97daa27-a619-4cb0-825b-3517d30e1f80_1456x662.png 424w, https://substackcdn.com/image/fetch/$s_!_-GN!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc97daa27-a619-4cb0-825b-3517d30e1f80_1456x662.png 848w, https://substackcdn.com/image/fetch/$s_!_-GN!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc97daa27-a619-4cb0-825b-3517d30e1f80_1456x662.png 1272w, https://substackcdn.com/image/fetch/$s_!_-GN!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc97daa27-a619-4cb0-825b-3517d30e1f80_1456x662.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!_-GN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc97daa27-a619-4cb0-825b-3517d30e1f80_1456x662.png" width="1456" height="662" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c97daa27-a619-4cb0-825b-3517d30e1f80_1456x662.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:662,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:82616,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/218934197?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc97daa27-a619-4cb0-825b-3517d30e1f80_1456x662.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!_-GN!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc97daa27-a619-4cb0-825b-3517d30e1f80_1456x662.png 424w, https://substackcdn.com/image/fetch/$s_!_-GN!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc97daa27-a619-4cb0-825b-3517d30e1f80_1456x662.png 848w, https://substackcdn.com/image/fetch/$s_!_-GN!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc97daa27-a619-4cb0-825b-3517d30e1f80_1456x662.png 1272w, https://substackcdn.com/image/fetch/$s_!_-GN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc97daa27-a619-4cb0-825b-3517d30e1f80_1456x662.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Imagen 22. Managed Postgres con CDC hacia ClickHouse Cloud y pg_clickhouse.</figcaption></figure></div><p>ClickHouse Managed Postgres, anunciado al principio como &#8220;Postgres managed by ClickHouse&#8221;, es un Postgres administrado dentro de ClickHouse Cloud. Corre sobre discos NVMe locales; en su prueba de rendimiento PostgresBench, ClickHouse reporta hasta cinco veces las transacciones por segundo de un Postgres administrado sobre discos de red, en cargas limitadas por disco. Trae integrado el CDC hacia ClickHouse, en beta y construido sobre ClickPipes, as&#237; que todo lo de la secci&#243;n 4 aplica igual. Tambi&#233;n trae <code>pg_clickhouse</code>, una extensi&#243;n de c&#243;digo abierto para consultar ClickHouse desde Postgres.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Sali&#243; en beta p&#250;blica en un primer proveedor de nube. Durante la beta se anunci&#243; gratis hasta el 15 de junio de 2026 y luego con 50 % de descuento mientras durara esa fase, con el CDC y <code>pg_clickhouse</code> incluidos, y el 9 de septiembre de 2026 se anunci&#243; una vista previa privada en un segundo proveedor. Esas condiciones cambian: revisa la p&#225;gina del producto antes de decidir.</p><p>Antes, para llevar Postgres a un almac&#233;n anal&#237;tico hab&#237;a que montar Debezium, Kafka y conectores. Desde mayo de 2025, ClickPipes ofrece CDC administrado para cualquier Postgres 12 o superior, y Managed Postgres lo integra en el mismo proveedor.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!8zZ-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F217a649f-0291-4cdb-8651-47dd05078640_1456x622.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8zZ-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F217a649f-0291-4cdb-8651-47dd05078640_1456x622.png 424w, https://substackcdn.com/image/fetch/$s_!8zZ-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F217a649f-0291-4cdb-8651-47dd05078640_1456x622.png 848w, https://substackcdn.com/image/fetch/$s_!8zZ-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F217a649f-0291-4cdb-8651-47dd05078640_1456x622.png 1272w, https://substackcdn.com/image/fetch/$s_!8zZ-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F217a649f-0291-4cdb-8651-47dd05078640_1456x622.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!8zZ-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F217a649f-0291-4cdb-8651-47dd05078640_1456x622.png" width="1456" height="622" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/217a649f-0291-4cdb-8651-47dd05078640_1456x622.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:622,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:65470,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/218934197?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F217a649f-0291-4cdb-8651-47dd05078640_1456x622.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!8zZ-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F217a649f-0291-4cdb-8651-47dd05078640_1456x622.png 424w, https://substackcdn.com/image/fetch/$s_!8zZ-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F217a649f-0291-4cdb-8651-47dd05078640_1456x622.png 848w, https://substackcdn.com/image/fetch/$s_!8zZ-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F217a649f-0291-4cdb-8651-47dd05078640_1456x622.png 1272w, https://substackcdn.com/image/fetch/$s_!8zZ-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F217a649f-0291-4cdb-8651-47dd05078640_1456x622.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Imagen 23. Qu&#233; resuelve cada motor en este dise&#241;o.</figcaption></figure></div><p>Con <code>pg_clickhouse</code>, Postgres ve las tablas y vistas de ClickHouse como tablas for&#225;neas:</p><pre><code><code>-- PostgreSQL
CREATE EXTENSION IF NOT EXISTS pg_clickhouse;

CREATE SERVER clickhouse_finance
    FOREIGN DATA WRAPPER clickhouse_fdw
    OPTIONS (driver 'binary',
             host 'your-service.clickhouse.cloud',
             dbname 'finance');

-- one mapping for the admin who imports the schema,
-- one for the application
CREATE USER MAPPING FOR CURRENT_USER
    SERVER clickhouse_finance
    OPTIONS (user 'reader', password '***');
CREATE USER MAPPING FOR backoffice_app
    SERVER clickhouse_finance
    OPTIONS (user 'reader', password '***');

CREATE SCHEMA IF NOT EXISTS ch;
IMPORT FOREIGN SCHEMA "finance"
    LIMIT TO (daily_balances, monthly_tx_control)
    FROM SERVER clickhouse_finance INTO ch;

GRANT USAGE ON SCHEMA ch TO backoffice_app;
GRANT SELECT ON ch.daily_balances, ch.monthly_tx_control
    TO backoffice_app;

-- the aggregation runs inside ClickHouse
SELECT
    account,
    sum(debit_lcy_minor) - sum(credit_lcy_minor)
        AS balance_lcy_minor
FROM ch.daily_balances
WHERE entity_id = 'CO01'
  AND accounting_date BETWEEN '2026-01-01'
                          AND '2026-12-31'
GROUP BY account;</code></code></pre><p>En la primera versi&#243;n de este ejemplo olvid&#233; el mapeo para el administrador y <code>IMPORT FOREIGN SCHEMA</code> fall&#243;; con los dos mapeos funciona. <code>EXPLAIN VERBOSE</code> muestra que Postgres env&#237;a a ClickHouse el filtro y la agregaci&#243;n y solo recibe el resultado:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!WGL4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b72bc71-73fb-4c2f-8912-63a0effa4d4f_1456x937.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!WGL4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b72bc71-73fb-4c2f-8912-63a0effa4d4f_1456x937.png 424w, https://substackcdn.com/image/fetch/$s_!WGL4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b72bc71-73fb-4c2f-8912-63a0effa4d4f_1456x937.png 848w, https://substackcdn.com/image/fetch/$s_!WGL4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b72bc71-73fb-4c2f-8912-63a0effa4d4f_1456x937.png 1272w, https://substackcdn.com/image/fetch/$s_!WGL4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b72bc71-73fb-4c2f-8912-63a0effa4d4f_1456x937.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!WGL4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b72bc71-73fb-4c2f-8912-63a0effa4d4f_1456x937.png" width="1456" height="937" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6b72bc71-73fb-4c2f-8912-63a0effa4d4f_1456x937.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:937,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:111977,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/218934197?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b72bc71-73fb-4c2f-8912-63a0effa4d4f_1456x937.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!WGL4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b72bc71-73fb-4c2f-8912-63a0effa4d4f_1456x937.png 424w, https://substackcdn.com/image/fetch/$s_!WGL4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b72bc71-73fb-4c2f-8912-63a0effa4d4f_1456x937.png 848w, https://substackcdn.com/image/fetch/$s_!WGL4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b72bc71-73fb-4c2f-8912-63a0effa4d4f_1456x937.png 1272w, https://substackcdn.com/image/fetch/$s_!WGL4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b72bc71-73fb-4c2f-8912-63a0effa4d4f_1456x937.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Imagen 24. El &#225;rea de operaciones sigue usando Postgres; la agregaci&#243;n la hace ClickHouse.</figcaption></figure></div><p>Con <code>driver 'binary'</code> y un host de ClickHouse Cloud, <code>pg_clickhouse</code> usa el puerto 9440 y activa TLS autom&#225;ticamente.</p><p>No lo recomiendo cuando el volumen exige fragmentar las escrituras (decenas de miles de transacciones por segundo sostenidas), cuando la regulaci&#243;n obliga a tener el OLTP en una regi&#243;n donde el servicio no existe, o mientras siga en beta si la pol&#237;tica de riesgo de la organizaci&#243;n no admite servicios beta en producci&#243;n.</p><h2><strong>10. Tama&#241;o estimado y riesgos</strong></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!HhKW!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a545e9e-d265-4833-933b-5b0a64825b0a_1456x859.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!HhKW!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a545e9e-d265-4833-933b-5b0a64825b0a_1456x859.png 424w, https://substackcdn.com/image/fetch/$s_!HhKW!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a545e9e-d265-4833-933b-5b0a64825b0a_1456x859.png 848w, https://substackcdn.com/image/fetch/$s_!HhKW!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a545e9e-d265-4833-933b-5b0a64825b0a_1456x859.png 1272w, https://substackcdn.com/image/fetch/$s_!HhKW!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a545e9e-d265-4833-933b-5b0a64825b0a_1456x859.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!HhKW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a545e9e-d265-4833-933b-5b0a64825b0a_1456x859.png" width="1456" height="859" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0a545e9e-d265-4833-933b-5b0a64825b0a_1456x859.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:859,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:93977,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/218934197?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a545e9e-d265-4833-933b-5b0a64825b0a_1456x859.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!HhKW!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a545e9e-d265-4833-933b-5b0a64825b0a_1456x859.png 424w, https://substackcdn.com/image/fetch/$s_!HhKW!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a545e9e-d265-4833-933b-5b0a64825b0a_1456x859.png 848w, https://substackcdn.com/image/fetch/$s_!HhKW!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a545e9e-d265-4833-933b-5b0a64825b0a_1456x859.png 1272w, https://substackcdn.com/image/fetch/$s_!HhKW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a545e9e-d265-4833-933b-5b0a64825b0a_1456x859.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Imagen 25. Cifras para planificar. La compresi&#243;n real depende del esquema y de los datos.</figcaption></figure></div><p>Lo que m&#225;s pesa en disco son los identificadores aleatorios: dos UUID por transacci&#243;n son 32 bytes que casi no se comprimen, a diferencia de las cuentas o las monedas. Si no usas <code>idempotency_key</code> en ClickHouse, excl&#250;yela del pipe.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Para las cargas propias, inserta en lotes o con <code>async_insert</code> (miles de inserciones de una fila generan miles de partes peque&#241;as), usa <code>insert_deduplication_token</code> para que los reintentos sean idempotentes y no particiones m&#225;s fino que un mes. ClickPipes ya inserta en lotes; sus reintentos est&#225;n en la secci&#243;n 4.4.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!KPbr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7af3b44-88f6-4b36-b191-085209c4d4ed_1456x1538.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!KPbr!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7af3b44-88f6-4b36-b191-085209c4d4ed_1456x1538.png 424w, https://substackcdn.com/image/fetch/$s_!KPbr!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7af3b44-88f6-4b36-b191-085209c4d4ed_1456x1538.png 848w, https://substackcdn.com/image/fetch/$s_!KPbr!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7af3b44-88f6-4b36-b191-085209c4d4ed_1456x1538.png 1272w, https://substackcdn.com/image/fetch/$s_!KPbr!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7af3b44-88f6-4b36-b191-085209c4d4ed_1456x1538.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!KPbr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7af3b44-88f6-4b36-b191-085209c4d4ed_1456x1538.png" width="1456" height="1538" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c7af3b44-88f6-4b36-b191-085209c4d4ed_1456x1538.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1538,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:225213,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/218934197?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7af3b44-88f6-4b36-b191-085209c4d4ed_1456x1538.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!KPbr!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7af3b44-88f6-4b36-b191-085209c4d4ed_1456x1538.png 424w, https://substackcdn.com/image/fetch/$s_!KPbr!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7af3b44-88f6-4b36-b191-085209c4d4ed_1456x1538.png 848w, https://substackcdn.com/image/fetch/$s_!KPbr!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7af3b44-88f6-4b36-b191-085209c4d4ed_1456x1538.png 1272w, https://substackcdn.com/image/fetch/$s_!KPbr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7af3b44-88f6-4b36-b191-085209c4d4ed_1456x1538.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Imagen 26. Los riesgos que encontr&#233; al probar el dise&#241;o, con su mitigaci&#243;n.</figcaption></figure></div><h2><strong>11. Lista de verificaci&#243;n del cierre</strong></h2><p>En noviembre:</p><ul><li><p>Servicio de c&#243;mputo para el cierre creado y probado.</p></li><li><p>Ensayo general del cierre con los datos de noviembre, incluida la reconstrucci&#243;n del paso 0.</p></li><li><p>Balance preliminar refrescable activo.</p></li><li><p>TRM como fuente oficial de tasas y hora de corte definidas.</p></li><li><p>Bucket con bloqueo de objetos y <em>named collections</em> configurados.</p></li><li><p>Alertas sobre el retraso del slot y el estado del pipe.</p></li></ul><p>Entre el 31 de diciembre y el corte de operaciones (por ejemplo, el 3 de enero):</p><ul><li><p>202612 sigue <code>OPEN</code> para las operaciones con fecha de diciembre que llegan tarde.</p></li><li><p>Monitoreo de los pagos tard&#237;os.</p></li></ul><p>En el corte:</p><ul><li><p>202612 en <code>CLOSING</code> en Postgres y posici&#243;n del WAL anotada.</p></li><li><p>Slot de ClickPipes al d&#237;a con esa posici&#243;n.</p></li></ul><p>Conciliaci&#243;n:</p><ul><li><p>Saldos reconstruidos y verificados mes a mes (paso 0).</p></li><li><p>Controles 1a a 1e superados.</p></li><li><p>Cada mes comparado con Postgres a trav&#233;s de <code>pg_clickhouse</code> (conteo, total y huella).</p></li><li><p>Conteos y totales iguales a los de bancos y pasarelas; diferencias explicadas partida por partida.</p></li><li><p>Partidas conciliatorias documentadas.</p></li></ul><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Ajustes y cierre:</p><ul><li><p>Comprobantes registrados y aprobados en Postgres antes de insertarlos.</p></li><li><p>Diferencia en cambio con la TRM del corte (paso 3), con su efecto fiscal documentado.</p></li><li><p>Impuesto de renta corriente y diferido (incluido el de la diferencia en cambio), provisiones, depreciaciones, reclasificaciones y clase 7 contabilizados.</p></li><li><p>Cuentas de resultado cerradas y sin saldo (pasos 4 y 5).</p></li><li><p>Apertura de 2027 registrada y cuadrada (paso 6).</p></li><li><p>Huella mensual guardada con el acta, respaldo en el bucket con bloqueo y plan de cuentas congelado (paso 7).</p></li><li><p>Exportaci&#243;n a Parquet (paso 8).</p></li></ul><p>Hasta la aprobaci&#243;n de los estados financieros:</p><ul><li><p>Diciembre en <code>CLOSING</code>; ajustes del auditor con el procedimiento de la secci&#243;n 6.7, incluido un nuevo sellado y exportaci&#243;n.</p></li><li><p>Servicio de solo lectura para auditores, con permisos por rol y pol&#237;ticas de fila.</p></li><li><p>Diciembre en <code>CLOSED</code> despu&#233;s de la aprobaci&#243;n.</p></li></ul><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Durante todo el a&#241;o:</p><ul><li><p>Si hubo una resincronizaci&#243;n del CDC: comprobar que las vistas siguen enganchadas, volver a derivar las l&#237;neas de los meses afectados, reconstruir saldos e indicadores y repetir los controles.</p></li><li><p>Solicitudes de supresi&#243;n de datos personales atendidas en Postgres, sin tocar el libro.</p></li></ul><p>Este dise&#241;o lo arm&#233; para una sola moneda funcional. Si te toca llevar NIIF y fiscal en paralelo, o varias monedas funcionales, cu&#233;ntame en los comentarios c&#243;mo lo resolviste: es lo siguiente que quiero probar.</p><h2><strong>12. Referencias</strong></h2><p><strong>CDC de Postgres con ClickPipes</strong></p><ul><li><p><a href="https://clickhouse.com/docs/integrations/clickpipes/postgres">Ingesting data from Postgres to ClickHouse (using CDC)</a></p></li><li><p><a href="https://clickhouse.com/docs/integrations/clickpipes/postgres/source/generic">Generic Postgres source setup guide</a></p></li><li><p><a href="https://clickhouse.com/docs/integrations/clickpipes/postgres/faq">ClickPipes for Postgres FAQ</a></p></li><li><p><a href="https://clickhouse.com/docs/integrations/clickpipes/postgres/deduplication">Deduplication strategies (using CDC)</a></p></li><li><p><a href="https://clickhouse.com/docs/integrations/clickpipes/postgres/ordering_keys">Ordering keys</a></p></li><li><p><a href="https://clickhouse.com/docs/integrations/clickpipes/postgres/toast">Handling TOAST columns</a></p></li><li><p><a href="https://clickhouse.com/docs/integrations/clickpipes/postgres/parallel_initial_load">Parallel snapshot in the Postgres ClickPipe</a></p></li><li><p><a href="https://clickhouse.com/docs/integrations/clickpipes/postgres/sync_control">Controlling the syncing of a database ClickPipe</a></p></li><li><p><a href="https://clickhouse.com/docs/integrations/clickpipes/postgres/schema-changes">Schema changes propagation support</a></p></li><li><p><a href="https://clickhouse.com/docs/integrations/clickpipes/postgres/resync">Resyncing a database ClickPipe</a></p></li><li><p><a href="https://clickhouse.com/docs/integrations/clickpipes/postgres/table_resync">Resyncing specific tables</a></p></li><li><p><a href="https://clickhouse.com/docs/integrations/clickpipes/postgres/pause_and_resume">Pausing and resuming a Postgres ClickPipe</a></p></li><li><p><a href="https://clickhouse.com/docs/integrations/clickpipes/postgres/generated_columns">Postgres generated columns: gotchas and best practices</a></p></li><li><p><a href="https://clickhouse.com/docs/integrations/clickpipes/monitoring">Monitoring ClickPipes</a></p></li><li><p><a href="https://clickhouse.com/docs/integrations/clickpipes/programmatic-access/terraform">ClickPipes Terraform reference</a></p></li><li><p><a href="https://clickhouse.com/blog/postgres-cdc-connector-clickpipes-ga">Postgres CDC connector for ClickPipes is now Generally Available</a></p></li><li><p><a href="https://clickhouse.com/blog/postgres-to-clickhouse-data-modeling-tips-v2">Postgres to ClickHouse: Data Modeling Tips V2</a></p></li><li><p>PeerDB: <a href="https://docs.peerdb.io/datatypes/datatype-matrix">Data type matrix</a> &#183; <a href="https://docs.peerdb.io/bestpractices/clickhouse_datamodeling">ClickHouse data modeling best practices</a> &#183; <a href="https://github.com/PeerDB-io/peerdb/blob/main/flow/connectors/clickhouse/normalize.go">C&#243;digo de normalizaci&#243;n (normalize.go)</a></p></li></ul><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p><strong>ClickHouse</strong></p><ul><li><p><a href="https://clickhouse.com/docs/engines/table-engines/mergetree-family">MergeTree engine family</a></p></li><li><p><a href="https://clickhouse.com/docs/materialized-views">Materialized views</a> &#183; <a href="https://clickhouse.com/docs/sql-reference/statements/create/view">CREATE VIEW (incremental y refrescables)</a></p></li><li><p><a href="https://clickhouse.com/docs/sql-reference/statements/select/join#asof-join-usage">JOIN clause: ASOF JOIN</a></p></li><li><p><a href="https://clickhouse.com/docs/reference/statements/create/dictionary/layouts/hierarchical">Hierarchical dictionaries</a> &#183; <a href="https://clickhouse.com/docs/reference/functions/regular-functions/ext-dict-functions">Functions for working with dictionaries</a> &#183; <a href="https://clickhouse.com/docs/reference/statements/create/dictionary/sources/postgresql">PostgreSQL dictionary source</a></p></li><li><p><a href="https://clickhouse.com/docs/operations/named-collections">Named collections</a> &#183; <a href="https://clickhouse.com/docs/sql-reference/statements/create/function">CREATE FUNCTION</a></p></li><li><p><a href="https://clickhouse.com/docs/sql-reference/data-types/decimal">Decimal(P, S)</a> &#183; <a href="https://clickhouse.com/docs/sql-reference/functions/rounding-functions">Rounding functions</a> &#183; <a href="https://clickhouse.com/docs/sql-reference/functions/financial-functions">Financial functions</a></p></li><li><p><a href="https://clickhouse.com/docs/sql-reference/functions/encryption-functions">Encryption functions</a> &#183; <a href="https://clickhouse.com/docs/reference/settings/server-settings/settings/query">query_masking_rules</a></p></li><li><p><a href="https://clickhouse.com/docs/sql-reference/statements/grant">GRANT</a> &#183; <a href="https://clickhouse.com/docs/sql-reference/statements/create/row-policy">CREATE ROW POLICY</a> &#183; <a href="https://clickhouse.com/docs/reference/statements/create/masking-policy">CREATE MASKING POLICY</a> &#183; <a href="https://clickhouse.com/docs/cloud/guides/data-masking">Data masking in ClickHouse</a></p></li><li><p><a href="https://clickhouse.com/docs/sql-reference/statements/backup">BACKUP and RESTORE</a> &#183; <a href="https://clickhouse.com/docs/sql-reference/statements/alter/partition">Manipulating partitions</a> &#183; <a href="https://clickhouse.com/docs/sql-reference/table-functions/s3">s3 table function</a></p></li><li><p><a href="https://clickhouse.com/blog/clickhouse-release-25-07">ClickHouse Release 25.7</a> &#183; <a href="https://clickhouse.com/blog/clickhouse-release-25-12">ClickHouse Release 25.12</a></p></li></ul><p><strong>ClickHouse Cloud, Managed Postgres y pg_clickhouse</strong></p><ul><li><p><a href="https://clickhouse.com/docs/cloud/reference/shared-merge-tree">SharedMergeTree</a> &#183; <a href="https://clickhouse.com/docs/cloud/reference/warehouses">Warehouses (compute-compute separation)</a> &#183; <a href="https://clickhouse.com/docs/cloud/manage/cloud-tiers">ClickHouse Cloud tiers</a> &#183; <a href="https://clickhouse.com/docs/cloud/reference/supported-regions">Supported cloud regions</a></p></li><li><p><a href="https://clickhouse.com/docs/cloud/security/compliance-overview">Security and compliance</a> &#183; <a href="https://trust.clickhouse.com/">Trust Center</a> &#183; <a href="https://clickhouse.com/docs/cloud/security/cmek">Data encryption (CMEK)</a></p></li><li><p><a href="https://clickhouse.com/docs/products/managed-postgres/overview">ClickHouse Managed Postgres</a> &#183; <a href="https://clickhouse.com/docs/products/managed-postgres/clickhouse-integration">Sync to ClickHouse</a> &#183; <a href="https://clickhouse.com/docs/products/managed-postgres/pricing">Pricing</a></p></li><li><p><a href="https://clickhouse.com/blog/postgres-managed-by-clickhouse-beta">Postgres managed by ClickHouse is now in beta</a> &#183; <a href="https://clickhouse.com/blog/postgres-managed-by-clickhouse-gcp-private-preview">Anuncio de la vista previa privada (9 de septiembre de 2026)</a> &#183; <a href="https://clickhouse.com/blog/postgresbench">PostgresBench</a></p></li><li><p><a href="https://github.com/ClickHouse/pg_clickhouse">pg_clickhouse (GitHub)</a> &#183; <a href="https://github.com/ClickHouse/pg_clickhouse/blob/main/doc/pg_clickhouse.md">pg_clickhouse reference</a></p></li></ul><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p><strong>PostgreSQL</strong></p><ul><li><p><a href="https://www.postgresql.org/docs/current/sql-createpublication.html">CREATE PUBLICATION</a> &#183; <a href="https://www.postgresql.org/docs/current/logical-replication-col-lists.html">Logical replication: column lists</a> &#183; <a href="https://www.postgresql.org/docs/current/sql-altertable.html">ALTER TABLE (REPLICA IDENTITY)</a> &#183; <a href="https://www.postgresql.org/docs/current/sql-createtrigger.html">CREATE TRIGGER</a></p></li></ul><p><strong>Dinero y est&#225;ndares</strong></p><ul><li><p>ISO 4217: <a href="https://www.six-group.com/en/products-services/financial-information/data-standards.html">Agencia de mantenimiento</a> &#183; <a href="https://www.six-group.com/dam/download/financial-information/data-center/iso-currrency/lists/list-one.xml">Lista oficial (XML)</a></p></li><li><p><a href="https://www.rfc-editor.org/rfc/rfc3339">RFC 3339: Date and Time on the Internet</a> &#183; <a href="https://www.iso.org/iso-8601-date-and-time-format.html">ISO 8601</a> &#183; <a href="https://www.iso.org/iso-3166-country-codes.html">ISO 3166</a></p></li><li><p><a href="https://www.iso20022.org/iso-20022-message-definitions">ISO 20022 message definitions</a></p></li><li><p><a href="https://www.banrep.gov.co/en/publications-research/working-papers/paper-bre-b-february-2026">Banco de la Rep&#250;blica: Bre-B (documento de trabajo, febrero de 2026)</a></p></li></ul><p><strong>Datos personales y seguridad</strong></p><ul><li><p><a href="https://www.funcionpublica.gov.co/eva/gestornormativo/norma.php?i=49981">Ley 1581 de 2012</a> &#183; <a href="https://www.funcionpublica.gov.co/eva/gestornormativo/norma.php?i=53646">Decreto 1377 de 2013</a> &#183; <a href="https://www.funcionpublica.gov.co/eva/gestornormativo/norma.php?i=76608">Decreto 1074 de 2015</a> &#183; <a href="https://www.funcionpublica.gov.co/eva/gestornormativo/norma_pdf.php?i=85039">Decreto 090 de 2018</a></p></li><li><p>SIC: <a href="https://sedeelectronica.sic.gov.co/transparencia/normativa/circular-externa-no-003-del-19-de-diciembre-de-2025">Circular Externa 003 de 2025</a> &#183; <a href="https://sedeelectronica.sic.gov.co/comunicado/la-superintendencia-de-industria-y-comercio-emite-instrucciones-para-la-proteccion-de-datos-personales-en-procesos-de-transferencia-de">Circular Externa 002 de 2025</a> &#183; <a href="https://www.alcaldiabogota.gov.co/sisjur/normas/Norma1.jsp?i=190946&amp;dt=S">Circular Externa 001 de 2025</a></p></li><li><p><a href="https://www.superfinanciera.gov.co/publicaciones/10097769/superfinanciera-fortalece-la-proteccion-de-la-informacion-de-los-consumidores-financieros-ante-riesgos-de-ciberseguridad-y-la-realizacion-de-operaciones-en-pasarelas-de-pago-10097769/">Superintendencia Financiera: Circular Externa 007 de 2018</a></p></li><li><p><a href="https://eur-lex.europa.eu/eli/reg/2016/679/oj">Reglamento (UE) 2016/679 (GDPR)</a></p></li><li><p>PCI SSC: <a href="https://docs-prv.pcisecuritystandards.org/PCI%20DSS/Standard/PCI-DSS-v4_0_1.pdf">PCI DSS v4.0.1</a> &#183; <a href="https://www.pcisecuritystandards.org/faq/articles/Frequently_Asked_Question/what-are-acceptable-formats-for-truncation-of-primary-account-numbers/">Formatos de truncamiento aceptados</a></p></li></ul><p><strong>Contabilidad y tributario</strong></p><ul><li><p><a href="https://www.funcionpublica.gov.co/eva/gestornormativo/norma.php?i=17004">Ley 962 de 2005</a> &#183; <a href="https://www.funcionpublica.gov.co/eva/gestornormativo/norma.php?i=41102">C&#243;digo de Comercio (Decreto 410 de 1971)</a> &#183; <a href="https://www.funcionpublica.gov.co/eva/gestornormativo/norma.php?i=6533">Estatuto Tributario (Decreto 624 de 1989)</a></p></li><li><p><a href="https://gestornormativo.creg.gov.co/gestor/entorno/docs/decreto_2650_1993.htm">Decreto 2650 de 1993 (PUC)</a> &#183; <a href="https://www.funcionpublica.gov.co/eva/gestornormativo/norma.php?i=36833">Ley 1314 de 2009</a> &#183; <a href="https://www.funcionpublica.gov.co/eva/gestornormativo/norma.php?i=76745">Decreto 2420 de 2015</a></p></li><li><p>IFRS: <a href="https://www.ifrs.org/issued-standards/list-of-standards/ias-8-accounting-policies-changes-in-accounting-estimates-and-errors/">NIC 8</a> &#183; <a href="https://www.ifrs.org/issued-standards/list-of-standards/ias-12-income-taxes/">NIC 12</a> &#183; <a href="https://www.ifrs.org/issued-standards/list-of-standards/ias-21-the-effects-of-changes-in-foreign-exchange-rates/">NIC 21</a></p></li></ul>]]></content:encoded></item><item><title><![CDATA[Pago Móvil, el primo venezolano de Pix y Bre-B, para pagos inmediatos: nacido en 2017]]></title><description><![CDATA[Por debajo, Pix, Bre-B y el Pago M&#243;vil venezolano son tres respuestas muy distintas a una misma pregunta &#8212; y la diferencia entre ellas te la explico en este art&#237;culo.]]></description><link>https://blog.carrillo.app/p/pago-movil-el-primo-venezolano-de</link><guid isPermaLink="false">https://blog.carrillo.app/p/pago-movil-el-primo-venezolano-de</guid><dc:creator><![CDATA[José Carrillo]]></dc:creator><pubDate>Tue, 15 Sep 2026 20:39:26 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Vil_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7f20439-becc-43a2-a64e-f861f20968b0_3904x2765.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Vil_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7f20439-becc-43a2-a64e-f861f20968b0_3904x2765.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Vil_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7f20439-becc-43a2-a64e-f861f20968b0_3904x2765.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Vil_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7f20439-becc-43a2-a64e-f861f20968b0_3904x2765.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Vil_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7f20439-becc-43a2-a64e-f861f20968b0_3904x2765.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Vil_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7f20439-becc-43a2-a64e-f861f20968b0_3904x2765.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Vil_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7f20439-becc-43a2-a64e-f861f20968b0_3904x2765.jpeg" width="728" height="515.5" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c7f20439-becc-43a2-a64e-f861f20968b0_3904x2765.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;normal&quot;,&quot;height&quot;:1031,&quot;width&quot;:1456,&quot;resizeWidth&quot;:728,&quot;bytes&quot;:218216,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/215757889?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7f20439-becc-43a2-a64e-f861f20968b0_3904x2765.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Vil_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7f20439-becc-43a2-a64e-f861f20968b0_3904x2765.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Vil_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7f20439-becc-43a2-a64e-f861f20968b0_3904x2765.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Vil_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7f20439-becc-43a2-a64e-f861f20968b0_3904x2765.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Vil_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7f20439-becc-43a2-a64e-f861f20968b0_3904x2765.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Son sistemas de pagos inmediatos modernos que tienen gran aceptaci&#243;n en m&#243;viles que incluso pueden ser arrow phones</figcaption></figure></div><p><strong>Un brasile&#241;o paga el caf&#233; con una llave de correo electr&#243;nico. Un colombiano manda plata con una arroba. Un venezolano teclea c&#233;dula, tel&#233;fono y banco, y reza.</strong> Los tres creen que est&#225;n haciendo lo mismo. Y en parte tienen raz&#243;n: los tres mueven dinero entre bancos distintos en segundos, sin tarjeta, sin efectivo y sin horario.</p><p>Pero por debajo, <em>Pix</em>, <em>Bre-B</em> y el <em>Pago M&#243;vil</em> venezolano son tres respuestas muy distintas a una misma pregunta &#8212; y la diferencia entre ellas explica por qu&#233; uno arras&#243;, otro arranc&#243; disparado y el tercero lleva casi una d&#233;cada funcionando sin que casi nadie fuera de Venezuela lo estudie.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Esta es la anatom&#237;a de los tres, con cifras oficiales, diagramas y las diferencias que s&#237; importan. Si eres ingeniero de pagos, encontrar&#225;s la fontaner&#237;a. Si nunca has o&#237;do hablar de un &#171;sistema de pagos de bajo valor&#187;, tambi&#233;n: cada cosa se explica antes de usarse. <strong>Cada n&#250;mero lleva al lado el enlace a la fuente de donde sali&#243;</strong>, para que puedas comprobarlo sin creerme nada.</p><h2>En 60 segundos</h2><ul><li><p><strong>&#191;Son lo mismo?</strong> No. Son la <em>misma categor&#237;a</em> &#8212;pagos inmediatos, interoperables, 24/7&#8212; con arquitecturas y due&#241;os distintos.</p></li><li><p><strong>&#191;Cu&#225;l es la diferencia de fondo?</strong> El <strong>directorio de llaves</strong>: la base de datos que traduce tu correo o tu celular a un n&#250;mero de cuenta. Pix y Bre-B tienen uno; el Pago M&#243;vil venezolano no. Todo lo dem&#225;s se deriva de ah&#237;.</p></li><li><p><strong>&#191;Cu&#225;l se usa m&#225;s?</strong> Pix, sin competencia: m&#225;s de <strong>7.000 millones de transacciones en un solo mes</strong>. Pero si en vez de contar el total se cuenta <em>por habitante</em>, Venezuela queda en segundo lugar y muy por encima de Colombia &#8212; unas <strong>360 operaciones diarias por cada 1.000 personas frente a 152</strong>. Ese c&#225;lculo es m&#237;o y lo explico, con sus l&#237;mites en los puntos.</p></li><li><p><strong>&#191;Cu&#225;l lleg&#243; primero?</strong> Venezuela, en <strong>2017</strong> &#8212; tres a&#241;os antes que Pix y ocho antes que Bre-B.</p></li><li><p><strong>&#191;Funcionan entre pa&#237;ses?</strong> Ninguno. Ni uno solo cruza la frontera todav&#237;a.</p></li><li><p><strong>&#191;Cu&#225;nto cuestan?</strong> Pix y Bre-B son gratis para las personas. El Pago M&#243;vil venezolano <strong>no</strong>: cobra <strong>0,30 % del monto con un m&#237;nimo de 14 bol&#237;vares</strong>, y ese m&#237;nimo <em>subi&#243; desde 2 bol&#237;vares</em> en julio de 2026 &#8212; un alza del 600 % que se siente sobre todo en los pagos chicos, porque un cobro fijo pesa m&#225;s cuanto menos pagas.</p></li><li><p><strong>&#191;Porqu&#233; nadie esta hablando de la soluci&#243;n venezolana si fue pionera junto con SPEI de M&#233;xico?</strong> No les voy a mentir, nadie lo sabe, pero yo particularmente supongo que es por la situaci&#243;n actual del pa&#237;s y como se ve desde afuera.</p></li></ul><div><hr></div><h2>1. &#191;Qu&#233; es exactamente un &#171;pago inmediato&#187;?</h2><p>La expresi&#243;n se usa para todo, as&#237; que conviene fijarla. Un sistema de pagos inmediatos &#8212;<em>fast payment system</em> en la literatura del Banco de Pagos Internacionales&#8212; cumple <strong>cuatro condiciones a la vez</strong>. Si le falta una, es otra cosa:</p><ol><li><p><strong>Es inmediato de verdad.</strong> El beneficiario puede <em>usar</em> el dinero en segundos, no verlo &#171;en camino&#187;.</p></li><li><p><strong>Est&#225; siempre encendido.</strong> Domingo a las tres de la ma&#241;ana, 1.&#186; de enero, feriado bancario: da igual.</p></li><li><p><strong>Es interoperable.</strong> Funciona entre entidades distintas. Un sistema que solo mueve dinero dentro del mismo banco o de la misma billetera no clasifica.</p></li><li><p><strong>Es irrevocable.</strong> Una vez ejecutado, no se deshace unilateralmente. Esto es una virtud y un peligro, y m&#225;s adelante veremos por qu&#233;.</p></li></ol><blockquote><p>N&#243;tese lo que <em>no</em> est&#225; en la lista: ni gratuidad, ni QR, ni celular, ni app bonita. Todo eso son decisiones de dise&#241;o encima de la infraestructura &#8212; y son justamente las decisiones donde Brasil, Colombia y Venezuela se separan.</p></blockquote><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2>2. La anatom&#237;a: &#191;qu&#233; pasa en esos diez segundos?</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!OtzG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F856eb106-e666-4c2c-89c1-049ed7baf921_2240x1320.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!OtzG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F856eb106-e666-4c2c-89c1-049ed7baf921_2240x1320.png 424w, https://substackcdn.com/image/fetch/$s_!OtzG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F856eb106-e666-4c2c-89c1-049ed7baf921_2240x1320.png 848w, https://substackcdn.com/image/fetch/$s_!OtzG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F856eb106-e666-4c2c-89c1-049ed7baf921_2240x1320.png 1272w, https://substackcdn.com/image/fetch/$s_!OtzG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F856eb106-e666-4c2c-89c1-049ed7baf921_2240x1320.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!OtzG!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F856eb106-e666-4c2c-89c1-049ed7baf921_2240x1320.png" width="1200" height="707.1428571428571" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/856eb106-e666-4c2c-89c1-049ed7baf921_2240x1320.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:858,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:285213,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/215757889?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F856eb106-e666-4c2c-89c1-049ed7baf921_2240x1320.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="" srcset="https://substackcdn.com/image/fetch/$s_!OtzG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F856eb106-e666-4c2c-89c1-049ed7baf921_2240x1320.png 424w, https://substackcdn.com/image/fetch/$s_!OtzG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F856eb106-e666-4c2c-89c1-049ed7baf921_2240x1320.png 848w, https://substackcdn.com/image/fetch/$s_!OtzG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F856eb106-e666-4c2c-89c1-049ed7baf921_2240x1320.png 1272w, https://substackcdn.com/image/fetch/$s_!OtzG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F856eb106-e666-4c2c-89c1-049ed7baf921_2240x1320.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Figura 1. El esquema es com&#250;n a los tres sistemas. Lo que cambia es qui&#233;n opera cada caja.</em></figcaption></figure></div><p>Hay un detalle que casi nunca se cuenta y que ordena todo lo dem&#225;s: <strong>el mensaje y el dinero viajan por caminos distintos.</strong></p><p>Cuando pulsas &#171;enviar&#187;, lo que sale disparado es un <em>mensaje</em>: &#171;la cuenta A autoriza 50.000 a la cuenta B&#187;. Ese mensaje va a tu entidad, que valida saldo y firma; de ah&#237; a la infraestructura central, que averigua a qu&#233; cuenta apunta el identificador y enruta; de ah&#237; a la entidad de destino, que acepta y abona. Todo eso ocurre en menos de diez segundos y es lo que t&#250; ves. Esa parte es compartida entre todos los sistemas.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>El dinero <em>entre bancos</em> es otra historia. Los bancos se deben plata entre ellos todo el d&#237;a, y eso se salda contra las cuentas que cada uno mantiene en el banco central &#8212; en tiempo real, o por compensaci&#243;n en ventanas a lo largo del d&#237;a. <strong>Quien recibi&#243; ya gast&#243; su dinero mucho antes de que esa cuenta cuadre.</strong> Ah&#237; vive el riesgo del sistema, y por eso el banco central nunca est&#225; lejos del volante.</p><h3>Los cuatro papeles que alguien tiene que ocupar</h3><ul><li><p><strong>El que manda.</strong> Obliga a participar, fija tarifas y define las reglas. Casi siempre el banco central o el regulador bancario.</p></li><li><p><strong>El que opera.</strong> Enruta los mensajes y resuelve las llaves. Puede ser el propio banco central, una c&#225;mara de compensaci&#243;n o un consorcio privado.</p></li><li><p><strong>El que liquida.</strong> Cuadra las cuentas entre entidades. Esto casi nunca se delega: lo hace el banco central.</p></li><li><p><strong>El que atiende.</strong> Pone la app, el soporte y la lucha contra el fraude. Bancos, cooperativas y billeteras.</p></li></ul><h2>3. La pregunta que lo decide todo: &#191;c&#243;mo nombras a quien recibe?</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7D4h!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca693569-ca1b-44cf-b06d-08486aaada8c_2240x1200.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7D4h!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca693569-ca1b-44cf-b06d-08486aaada8c_2240x1200.png 424w, https://substackcdn.com/image/fetch/$s_!7D4h!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca693569-ca1b-44cf-b06d-08486aaada8c_2240x1200.png 848w, https://substackcdn.com/image/fetch/$s_!7D4h!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca693569-ca1b-44cf-b06d-08486aaada8c_2240x1200.png 1272w, https://substackcdn.com/image/fetch/$s_!7D4h!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca693569-ca1b-44cf-b06d-08486aaada8c_2240x1200.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!7D4h!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca693569-ca1b-44cf-b06d-08486aaada8c_2240x1200.png" width="1200" height="642.8571428571429" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ca693569-ca1b-44cf-b06d-08486aaada8c_2240x1200.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:780,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:290991,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/215757889?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca693569-ca1b-44cf-b06d-08486aaada8c_2240x1200.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="" srcset="https://substackcdn.com/image/fetch/$s_!7D4h!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca693569-ca1b-44cf-b06d-08486aaada8c_2240x1200.png 424w, https://substackcdn.com/image/fetch/$s_!7D4h!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca693569-ca1b-44cf-b06d-08486aaada8c_2240x1200.png 848w, https://substackcdn.com/image/fetch/$s_!7D4h!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca693569-ca1b-44cf-b06d-08486aaada8c_2240x1200.png 1272w, https://substackcdn.com/image/fetch/$s_!7D4h!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca693569-ca1b-44cf-b06d-08486aaada8c_2240x1200.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Figura 2. Un dato contra tres. No es un detalle de interfaz.</em></figcaption></figure></div><p>Aqu&#237; est&#225;, en serio, la diferencia de fondo. Un n&#250;mero de cuenta bancaria es un identificador dise&#241;ado para los bancos, no para las personas: <em><strong>&#8220;nadie se sabe el suyo&#8221;</strong></em> <em>(o al menos, para eso no estan dise&#241;ados)</em>. Los sistemas modernos resuelven esto con un <strong>directorio</strong>, una base de datos que traduce algo que s&#237; te sabes &#8212;tu correo, tu celular, tu c&#233;dula&#8212; a una cuenta concreta.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Brasil lo llam&#243; <strong>DICT</strong> (<em>Diret&#243;rio de Identificadores de Contas Transacionais</em>). Colombia lo llam&#243; <strong>directorio centralizado de llaves</strong> y lo puso bajo el Banco de la Rep&#250;blica. Venezuela <strong>no tiene</strong>: en el Pago M&#243;vil, <em>t&#250;</em> eres el enrutador. Tecleas c&#233;dula, tel&#233;fono y &#8212;esto es lo importante&#8212; <strong>el banco de destino</strong>. Si el banco est&#225; mal, el pago no sale, o sale a donde no deb&#237;a.</p><p>De esa &#250;nica decisi&#243;n se derivan tres consecuencias que la gente siente todos los d&#237;as:</p><ul><li><p><strong>Confirmaci&#243;n antes de pagar.</strong> Con directorio, la app te muestra el nombre del destinatario <em>antes</em> de que confirmes. Sin directorio, confirmas a ciegas y el nombre aparece despu&#233;s, en el comprobante.</p></li><li><p><strong>Portabilidad.</strong> Con directorio, cambias de banco y te llevas la llave. Sin directorio, cambiar de banco significa avisarle a todo el mundo.</p></li><li><p><strong>Cobros autom&#225;ticos.</strong> Un directorio es la precondici&#243;n para que alguien te cobre de forma recurrente sin pedirte los datos cada vez.</p></li></ul><h2>4. Pix: el caso que todos copian</h2><p>El <strong>Banco Central do Brasil</strong> encendi&#243; Pix el <strong>16 de noviembre de 2020</strong>. Cinco a&#241;os y medio despu&#233;s, las cifras son de otra escala:</p><ul><li><p><strong>M&#225;s de 7.000 millones de transacciones</strong> en mayo de 2026, por encima de <strong>R$ 3 billones</strong> en el mes.</p></li><li><p>Casi <strong>80.000 millones de operaciones</strong> en todo 2025, con m&#225;s de <strong>R$ 35 billones</strong> movilizados.</p></li><li><p><strong>M&#225;s de 170 millones de personas f&#237;sicas</strong> lo han usado &#8212; en un pa&#237;s de unos 213 millones de habitantes.</p></li></ul><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>&#191;Por qu&#233; funcion&#243;? Tres decisiones, y ninguna es tecnol&#243;gica:</p><ol><li><p><strong>Obligatorio.</strong> Las instituciones grandes no pudieron elegir si participaban. No hubo &#171;efecto isla&#187;.</p></li><li><p><strong>Gratis para las personas.</strong> Sin comisi&#243;n, la resistencia a probarlo fue cero.</p></li><li><p><strong>Una marca, no una funci&#243;n.</strong> Pix no es &#171;transferencia inmediata del banco X&#187;: es <em>Pix</em>, en todos lados, con el mismo nombre y el mismo flujo.</p></li></ol><p>Vale la pena mencionar dos piezas que suelen pasar desapercibidas. El <strong>MED</strong> (<em>Mecanismo Especial de Devolu&#231;&#227;o</em>) es el procedimiento para devolver fondos cuando hubo fraude &#8212; la respuesta al problema de la irrevocabilidad. Y el <strong>Pix Autom&#225;tico</strong>, encendido en <strong>junio de 2025</strong>, es el que permite cobros recurrentes: el momento en que Pix dej&#243; de ser solo un instrumento de empuje. Volveremos a esto.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2>5. Bre-B: Colombia lleg&#243; tarde y arranc&#243; r&#225;pido</h2><p>Colombia ten&#237;a transferencias inmediatas desde antes &#8212;<em>Transfiya</em>, Nequi, Daviplata&#8212; pero cada una en su isla. <strong>Bre-B</strong>, del <strong>Banco de la Rep&#250;blica</strong>, es el sistema que las obliga a hablarse. El registro de llaves abri&#243; en <strong>julio de 2025</strong> y la operaci&#243;n plena arranc&#243; en <strong>octubre de 2025</strong>.</p><p>Los n&#250;meros del primer a&#241;o son notables &#8212; y, comparados con los de Pix en su mismo momento de vida, mejores:</p><ul><li><p><strong>108 millones de llaves registradas</strong>, al corte de junio de 2026.</p></li><li><p><strong>Unos 35 millones de personas vinculadas</strong> y <strong>782.218.571 operaciones acumuladas</strong> al 4 de mayo de 2026.</p></li><li><p>De <strong>1,5 a m&#225;s de 5 millones de operaciones diarias en siete meses</strong>, con picos por encima de 5,8 millones.</p></li><li><p>Tope por transacci&#243;n en 2026: <strong>COP 12.110.000</strong>, que es el equivalente a 1.000 UVB.</p></li><li><p>Registrar una llave y transferir con ella: <strong>sin costo</strong>.</p></li></ul><p>Las <strong>llaves</strong> pueden ser cinco cosas: n&#250;mero de documento, celular, correo electr&#243;nico, una alfanum&#233;rica que t&#250; eliges (la famosa arroba, <code>@tunombre</code>) y un <em>c&#243;digo de comercio</em> para negocios. <strong>Cada llave apunta a una sola cuenta, pero una cuenta puede tener varias llaves.</strong> Las cifras al d&#237;a viven en el tablero de indicadores del Banco de la Rep&#250;blica.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><blockquote><p>Un matiz que conviene tener a mano: los 108 millones de llaves <em>no</em> son 108 millones de personas. Una sola persona puede registrar documento, celular, correo y arroba &#8212; cuatro llaves, un ser humano. La cifra que importa es la de usuarios vinculados, que va por 35 millones.</p></blockquote><h2>6. Venezuela: Pago M&#243;vil, C2P y el d&#233;bito que casi nadie explica</h2><p>Aqu&#237; es donde la mayor&#237;a de las comparaciones se rompen, porque tratan &#171;Pago M&#243;vil&#187; como si fuera una sola cosa. No lo es. Venezuela tiene <strong>cuatro instrumentos</strong> que conviven, y la manera limpia de ordenarlos es preguntarse <em>qui&#233;n aprieta el bot&#243;n</em>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!3zu8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F600285f1-4723-4984-915d-16cc43af687b_2240x1200.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!3zu8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F600285f1-4723-4984-915d-16cc43af687b_2240x1200.png 424w, https://substackcdn.com/image/fetch/$s_!3zu8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F600285f1-4723-4984-915d-16cc43af687b_2240x1200.png 848w, https://substackcdn.com/image/fetch/$s_!3zu8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F600285f1-4723-4984-915d-16cc43af687b_2240x1200.png 1272w, https://substackcdn.com/image/fetch/$s_!3zu8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F600285f1-4723-4984-915d-16cc43af687b_2240x1200.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!3zu8!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F600285f1-4723-4984-915d-16cc43af687b_2240x1200.png" width="1200" height="642.8571428571429" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/600285f1-4723-4984-915d-16cc43af687b_2240x1200.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:780,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:339080,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/215757889?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F600285f1-4723-4984-915d-16cc43af687b_2240x1200.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="" srcset="https://substackcdn.com/image/fetch/$s_!3zu8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F600285f1-4723-4984-915d-16cc43af687b_2240x1200.png 424w, https://substackcdn.com/image/fetch/$s_!3zu8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F600285f1-4723-4984-915d-16cc43af687b_2240x1200.png 848w, https://substackcdn.com/image/fetch/$s_!3zu8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F600285f1-4723-4984-915d-16cc43af687b_2240x1200.png 1272w, https://substackcdn.com/image/fetch/$s_!3zu8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F600285f1-4723-4984-915d-16cc43af687b_2240x1200.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Figura 5. Empuje y jal&#243;n. Es la divisi&#243;n que ordena todo el sistema venezolano &#8212; y tambi&#233;n el brasile&#241;o y el colombiano.</em></figcaption></figure></div><h3>De empuje: lo inicia quien paga</h3><ul><li><p><strong>Pago M&#243;vil Interbancario (P2P).</strong> El que todo el mundo conoce. Arranc&#243; en <strong>2017</strong>, tras un piloto con diez bancos, bajo la supervisi&#243;n de la <strong>Sudeban</strong> y sobre la <em>C&#225;mara de Compensaci&#243;n Electr&#243;nica</em> del <strong>BCV</strong>. C&#233;dula, tel&#233;fono, banco, monto.</p></li><li><p><strong>Cr&#233;dito Inmediato (CI).</strong> La transferencia interbancaria que acredita el mismo d&#237;a. Sus modalidades incluyen cr&#233;dito ordinario, <em>pago de n&#243;mina</em>, fideicomisos y pagos de tarjeta de cr&#233;dito. Es el riel de las empresas.</p></li></ul><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h3>De jal&#243;n: lo inicia quien cobra, con permiso previo</h3><ul><li><p><strong>C2P (comercio a persona).</strong> El comercio pide c&#233;dula, tel&#233;fono y banco; al cliente le llega <strong>una clave por mensaje</strong> y la entrega en caja o la escribe en el checkout. Esa clave <em>es</em> la autorizaci&#243;n. Da trazabilidad y conciliaci&#243;n autom&#225;tica &#8212; lo que el P2P, con su captura de pantalla y su &#171;ya te pagu&#233;&#187;, nunca dio.</p></li><li><p><strong>D&#233;bito Inmediato (DI).</strong> Autorizas una vez y el cobro se repite: servicios, cuotas, suscripciones. Sus modalidades incluyen autorizaciones en l&#237;nea, claves de pago y <em>domiciliaciones</em>, y verifica la disponibilidad de fondos en el momento.</p></li></ul><p>Dicho de otro modo: <strong>el D&#233;bito Inmediato venezolano es el primo del Pix Autom&#225;tico brasile&#241;o</strong>, y existe desde hace a&#241;os. Es uno de esos casos donde el pa&#237;s lleg&#243; antes al concepto y despu&#233;s al reconocimiento &#8212; aunque realmente no ha llegado el reconocimiento adecuado a esta idea nacida de la gran necesidad.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h3>&#191;Cu&#225;nto se usa &#8212; y cu&#225;nto cuesta?</h3><p>Seg&#250;n cifras del BCV recogidas por la banca, el <strong>pago m&#243;vil representa el 41 % de las operaciones bancarias</strong> del pa&#237;s, con los puntos de venta en 47 %. La velocidad, reportada por la prensa especializada, pas&#243; de unas <strong>6.000 a unas 7.000 operaciones por minuto</strong> durante 2026.</p><p>Y aqu&#237; est&#225; la diferencia m&#225;s inc&#243;moda con Brasil y Colombia: <strong>en Venezuela, el pago m&#243;vil no es gratis.</strong> El BCV public&#243; en la <strong>Gaceta Oficial N.&#186; 46.427, del 31 de julio de 2026</strong>, un tarifario donde:</p><ul><li><p>El <strong>P2P interbancario</strong> entre personas naturales queda en <strong>0,30 %</strong>, con un cobro m&#237;nimo de <strong>14 bol&#237;vares</strong>.</p></li><li><p>El <strong>P2C</strong> entre bancos distintos puede llegar a <strong>1,50 %</strong> del monto.</p></li><li><p>Ese m&#237;nimo pas&#243; de <strong>2 a 14 bol&#237;vares</strong>: un alza del <strong>600 % </strong>&#8212; entendiendo la volatilidad del bol&#237;var venezolano.</p></li></ul><blockquote><p>Un cobro m&#237;nimo fijo es regresivo por construcci&#243;n, y la aritm&#233;tica lo ense&#241;a sola: 14 bol&#237;vares sobre un pago de 100 son un <strong>14 %</strong>; sobre uno de 10.000, un <strong>0,14 %</strong>. Cien veces m&#225;s caro para quien paga cien veces menos. En un pa&#237;s donde el pago m&#243;vil sustituy&#243; al efectivo para la compra diaria, eso no es un detalle de tarifario &#8212; es una decisi&#243;n sobre qui&#233;n paga la infraestructura.</p></blockquote><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Falta un contexto sin el cual nada de esto se entiende: <strong>Venezuela es una econom&#237;a fuertemente dolarizada en efectivo.</strong> El pago m&#243;vil no compite contra la tarjeta como en Brasil; compite contra un billete de d&#243;lar que circula de mano en mano. Es el riel digital del bol&#237;var, y arrastra consigo todo lo que le pasa al bol&#237;var.</p><h2>7. Entonces, &#191;son lo mismo?</h2><p>No. Comparten categor&#237;a y se parecen en la experiencia; se separan en casi todo lo dem&#225;s. <strong>Pix y Bre-B son &#8220;gemelos&#8221; (al menos en principio) con diez a&#241;os de diferencia</strong>: los dos tienen directorio, los dos son gratis, los dos obligan a las entidades a participar y los dos te ense&#241;an el nombre de quien va a recibir antes de que confirmes.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p><strong>El Pago M&#243;vil venezolano se parece a ambos en velocidad y en alcance, y se separa en las tres cosas que m&#225;s se notan</strong>: no hay directorio, no hay confirmaci&#243;n previa del nombre y no es gratis. Lo que s&#237; tiene &#8212;y a Bre-B todav&#237;a le falta&#8212; es el cobro recurrente funcionando.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!v_JX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F697d2734-6541-42f7-af09-c3f8cc4874d4_2400x1412.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!v_JX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F697d2734-6541-42f7-af09-c3f8cc4874d4_2400x1412.png 424w, https://substackcdn.com/image/fetch/$s_!v_JX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F697d2734-6541-42f7-af09-c3f8cc4874d4_2400x1412.png 848w, https://substackcdn.com/image/fetch/$s_!v_JX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F697d2734-6541-42f7-af09-c3f8cc4874d4_2400x1412.png 1272w, https://substackcdn.com/image/fetch/$s_!v_JX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F697d2734-6541-42f7-af09-c3f8cc4874d4_2400x1412.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!v_JX!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F697d2734-6541-42f7-af09-c3f8cc4874d4_2400x1412.png" width="1200" height="706.3186813186813" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/697d2734-6541-42f7-af09-c3f8cc4874d4_2400x1412.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:857,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:297135,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/215757889?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F697d2734-6541-42f7-af09-c3f8cc4874d4_2400x1412.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="" srcset="https://substackcdn.com/image/fetch/$s_!v_JX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F697d2734-6541-42f7-af09-c3f8cc4874d4_2400x1412.png 424w, https://substackcdn.com/image/fetch/$s_!v_JX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F697d2734-6541-42f7-af09-c3f8cc4874d4_2400x1412.png 848w, https://substackcdn.com/image/fetch/$s_!v_JX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F697d2734-6541-42f7-af09-c3f8cc4874d4_2400x1412.png 1272w, https://substackcdn.com/image/fetch/$s_!v_JX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F697d2734-6541-42f7-af09-c3f8cc4874d4_2400x1412.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Figura 6. Once preguntas, tres respuestas. La fila que lo explica casi todo es la tercera.</em></figcaption></figure></div><h2>8. Veinte a&#241;os de intentos</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!h6BY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4765ac88-9d00-4644-b58f-f0968a2e8957_2320x920.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!h6BY!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4765ac88-9d00-4644-b58f-f0968a2e8957_2320x920.png 424w, https://substackcdn.com/image/fetch/$s_!h6BY!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4765ac88-9d00-4644-b58f-f0968a2e8957_2320x920.png 848w, https://substackcdn.com/image/fetch/$s_!h6BY!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4765ac88-9d00-4644-b58f-f0968a2e8957_2320x920.png 1272w, https://substackcdn.com/image/fetch/$s_!h6BY!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4765ac88-9d00-4644-b58f-f0968a2e8957_2320x920.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!h6BY!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4765ac88-9d00-4644-b58f-f0968a2e8957_2320x920.png" width="1200" height="475.54945054945057" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4765ac88-9d00-4644-b58f-f0968a2e8957_2320x920.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:577,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:167894,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/215757889?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4765ac88-9d00-4644-b58f-f0968a2e8957_2320x920.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="" srcset="https://substackcdn.com/image/fetch/$s_!h6BY!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4765ac88-9d00-4644-b58f-f0968a2e8957_2320x920.png 424w, https://substackcdn.com/image/fetch/$s_!h6BY!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4765ac88-9d00-4644-b58f-f0968a2e8957_2320x920.png 848w, https://substackcdn.com/image/fetch/$s_!h6BY!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4765ac88-9d00-4644-b58f-f0968a2e8957_2320x920.png 1272w, https://substackcdn.com/image/fetch/$s_!h6BY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4765ac88-9d00-4644-b58f-f0968a2e8957_2320x920.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Figura 3. Llegar primero no es ganar.</em></figcaption></figure></div><p>La regi&#243;n no empez&#243; con Pix. <strong>M&#233;xico</strong> tiene <em>SPEI</em> desde <strong>2004</strong> &#8212;dos d&#233;cadas&#8212; y le sum&#243; <em>CoDi</em> (QR, 2019) y <em>DiMo</em> (pagos por n&#250;mero de celular, 2023) precisamente porque SPEI, siendo excelente infraestructura, nunca conquist&#243; el menudeo.</p><p><strong>Costa Rica</strong> encendi&#243; <em>SINPE M&#243;vil</em> en <strong>2015</strong> y hoy lo usa cerca del <strong>76 % de la poblaci&#243;n mayor de 15 a&#241;os</strong>, con unos 4,6 millones de suscripciones activas: la penetraci&#243;n m&#225;s alta de la regi&#243;n en proporci&#243;n.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p><strong>Argentina</strong> lanz&#243; <em>Transferencias 3.0</em> el <strong>29 de noviembre de 2021</strong>. <strong>Per&#250;</strong> oblig&#243; a <em>Yape</em> y <em>Plin</em> a interoperar desde <strong>2023</strong>.</p><p>La lecci&#243;n se repite: <strong>la infraestructura no basta.</strong> Lo que mueve la aguja es la combinaci&#243;n de obligatoriedad, gratuidad y un identificador que la gente ya se sabe de memoria.</p><h2>9. Penetraci&#243;n: los n&#250;meros, con sus asteriscos</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!IozT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feda58617-cafe-4c73-9be0-d4ea904c874f_2240x1240.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!IozT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feda58617-cafe-4c73-9be0-d4ea904c874f_2240x1240.png 424w, https://substackcdn.com/image/fetch/$s_!IozT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feda58617-cafe-4c73-9be0-d4ea904c874f_2240x1240.png 848w, https://substackcdn.com/image/fetch/$s_!IozT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feda58617-cafe-4c73-9be0-d4ea904c874f_2240x1240.png 1272w, https://substackcdn.com/image/fetch/$s_!IozT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feda58617-cafe-4c73-9be0-d4ea904c874f_2240x1240.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!IozT!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feda58617-cafe-4c73-9be0-d4ea904c874f_2240x1240.png" width="1200" height="664.2857142857143" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/eda58617-cafe-4c73-9be0-d4ea904c874f_2240x1240.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:806,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:230771,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/215757889?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feda58617-cafe-4c73-9be0-d4ea904c874f_2240x1240.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="" srcset="https://substackcdn.com/image/fetch/$s_!IozT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feda58617-cafe-4c73-9be0-d4ea904c874f_2240x1240.png 424w, https://substackcdn.com/image/fetch/$s_!IozT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feda58617-cafe-4c73-9be0-d4ea904c874f_2240x1240.png 848w, https://substackcdn.com/image/fetch/$s_!IozT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feda58617-cafe-4c73-9be0-d4ea904c874f_2240x1240.png 1272w, https://substackcdn.com/image/fetch/$s_!IozT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feda58617-cafe-4c73-9be0-d4ea904c874f_2240x1240.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Figura 4. La misma unidad para los tres &#8212; y las advertencias que vienen con ella.</em></figcaption></figure></div><p>Comparar estos sistemas es dif&#237;cil porque <strong>cada pa&#237;s publica una m&#233;trica distinta</strong>: Brasil informa transacciones por mes, Colombia operaciones por d&#237;a y llaves acumuladas, Venezuela porcentajes del total bancario.</p><p>Para poder ponerlos lado a lado, <strong>normalic&#233; todo a una sola unidad: operaciones diarias por cada 1.000 habitantes.</strong> La divisi&#243;n est&#225; impresa dentro de la figura para que cualquiera pueda rehacerla o discutirla.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Tres advertencias que hay que leer <em>antes</em> que el gr&#225;fico:</p><ol><li><p><strong>Bre-B cuenta solo lo que pasa por Bre-B.</strong> Un colombiano que paga de Nequi a Nequi no aparece: esa operaci&#243;n no cruza el sistema interoperado. El uso real de pagos digitales en Colombia es mayor que la barra.</p></li><li><p><strong>La cifra venezolana viene de prensa</strong>, no de una serie oficial publicada peri&#243;dicamente. Y la poblaci&#243;n del pa&#237;s es objeto de disputa metodol&#243;gica, as&#237; que el denominador tambi&#233;n tiene error.</p></li><li><p><strong>Una transacci&#243;n no es un peso.</strong> Muchos pagos peque&#241;os y pocos pagos grandes dan vol&#250;menes parecidos y econom&#237;as completamente distintas.</p></li></ol><p>Con todo eso dicho, el orden de magnitud s&#237; aguanta: <strong>Brasil est&#225; en otra liga</strong>, y <strong>Venezuela, por habitante, est&#225; muy por encima de lo que su tama&#241;o econ&#243;mico sugerir&#237;a</strong>. La raz&#243;n m&#225;s plausible no es tecnol&#243;gica: cuando el efectivo escasea y la inflaci&#243;n castiga al que lo guarda, digitalizarse deja de ser una comodidad y pasa a ser la &#250;nica forma pr&#225;ctica de comprar. La necesidad empuja m&#225;s r&#225;pido que cualquier campa&#241;a.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>P&#225;go M&#243;vil fue una iniciativa nacida luego de los mega apagones de Venezuela en 2017, que obligaron a la banca y el Banco Central de Venezuela o ofrecer soluciones &#225;giles e interoperables.</p><h2>10. Percepciones: lo que se cree y lo que es</h2><ul><li><p><strong>&#171;Pix es una app.&#187;</strong> No: es infraestructura p&#250;blica. Lo usas dentro de la app de tu banco, igual que usas la red el&#233;ctrica dentro de tu casa.</p></li><li><p><strong>&#171;Bre-B reemplaza a Nequi o Daviplata.&#187;</strong> Al contrario: las conecta. Sigues usando tu app de siempre; lo que cambia es hasta d&#243;nde alcanza.</p></li><li><p><strong>&#171;El Pago M&#243;vil venezolano es un invento improvisado.&#187;</strong> Lleva desde 2017 corriendo sobre la c&#225;mara de compensaci&#243;n del banco central, con normativa y supervisi&#243;n. Le falta un directorio, no seriedad. Y puede que incluso para algunos ojos, el que no tenga directorio lo hace mejor.</p></li><li><p><strong>&#171;Es gratis en todas partes.&#187;</strong> Gratis en Brasil y Colombia para personas naturales. En Venezuela se cobra, y desde 2026 bastante m&#225;s. Eso hace que el sistemma venezolano ya sea rentable, y no como Bre-b que tiene planes d&#233;, pero a&#250;n esta en &#8220;veremos&#8221;.</p></li><li><p><strong>&#171;Pix sirve en toda Latinoam&#233;rica.&#187;</strong> No. Es brasile&#241;o y liquida en reales. Lo que ves fuera de Brasil son pasarelas que lo intermedian. Aunque puede que en Venezuela operen los 3 sistemas, principalmente por las condiciones del pa&#237;s, y sobre todo en ciudades fronterizas.</p></li><li><p><strong>&#171;Es m&#225;s inseguro que una tarjeta.&#187;</strong> El riesgo se desplaza, no crece: menos fraude con datos robados, m&#225;s ingenier&#237;a social &#8212; te convencen de que <em>t&#250;</em> mandes el dinero. Por eso Brasil tuvo que inventar el MED.</p></li></ul><h2>11. &#191;Y si cruzo la frontera?</h2><p>Hoy, nada de esto funciona de un pa&#237;s a otro de manera oficial. <strong>Pix liquida en reales dentro de Brasil; Bre-B en pesos dentro de Colombia; el Pago M&#243;vil en bol&#237;vares dentro de Venezuela.</strong> Cuando ves &#171;acepta Pix&#187; en un comercio fuera de Brasil, casi siempre hay una pasarela que cobra en reales a una cuenta brasile&#241;a y luego hace otra cosa con ese dinero. No es interoperabilidad: es intermediaci&#243;n.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><blockquote><p><em>Pero, como les digo, lo m&#225;s probable es que no oficialmente ya operen Pix y Bre-b en Venezuela; de hecho, casas de cambio en ciudades de frontera operan los servicios, porque P&#225;go M&#243;vil a d&#237;a de hoy no compite con el uso de tarjetas, lo hace con divisas m&#225;s s&#243;lidas, incluso el real y los pesos colombianos.</em></p></blockquote><p>El intento serio de resolverlo se llama <strong>Nexus</strong>, del Banco de Pagos Internacionales: en vez de construir <em>n &#215; (n&#8722;1)</em> conexiones bilaterales entre pa&#237;ses, un est&#225;ndar &#250;nico al que cada sistema nacional se conecta una sola vez. Es la diferencia entre que cada pa&#237;s negocie con cada pa&#237;s, y que todos se enchufen al mismo tomacorriente.</p><p>A&#250;nque en mi opini&#243;n, cada vez m&#225;s se apuesta por el exchange, por lo que creo que este &#250;ltimo terminar&#225; conectandolos todos.</p><h2>12. &#191;Qu&#233; viene?</h2><ul><li><p><strong>El jal&#243;n gana terreno.</strong> Pix Autom&#225;tico es de 2025; Bre-B trabaja en su versi&#243;n para empresas. El cobro recurrente es donde est&#225; el dinero aburrido y constante: servicios, suscripciones, cuotas.</p></li><li><p><strong>Cr&#233;dito encima del riel.</strong> <em>Pix parcelado</em> ya existe; la tentaci&#243;n de poner financiaci&#243;n sobre una transferencia instant&#225;nea es enorme, y trae consigo los problemas del cr&#233;dito al consumo.</p></li><li><p><strong>Las tarjetas defienden el margen.</strong> En Brasil, Pix ya super&#243; a las tarjetas en n&#250;mero de operaciones. Esa pelea apenas empieza en Colombia.</p></li><li><p><strong>Venezuela tiene una tarea pendiente clara.</strong> No necesita otro instrumento: tiene empuje y jal&#243;n, P2P y C2P, cr&#233;dito y d&#233;bito inmediato. <strong>Necesita un directorio</strong> &#8212; y que el costo no expulse al pago peque&#241;o.</p></li></ul><h2>Preguntas que algunos amigos me hacen:</h2><p><strong>&#191;Bre-B es lo mismo que Pix?</strong><br>No, pero se le parece mucho a prop&#243;sito. Ambos son sistemas de pagos inmediatos con directorio de llaves, gratuitos y obligatorios para las entidades. Cambian el operador, el pa&#237;s, la moneda y el alcance funcional.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p><strong>&#191;El pago m&#243;vil venezolano es un sistema de pagos inmediatos?</strong><br>S&#237;, cumple las cuatro condiciones: inmediato, 24/7, interoperable e irrevocable. Lo que no tiene es directorio de llaves ni gratuidad.</p><p><strong>&#191;Puedo mandar dinero de Colombia a Venezuela con Bre-B?</strong><br>No. Bre-B opera dentro de Colombia y liquida en pesos colombianos. Algunas casas de cambio pueden cobrarte en Pesos dentro de Colombia y enviarte bol&#237;vares a una cuenta de banco en Venezuela, pero eso es otra historia.</p><p><strong>&#191;Cu&#225;l es la diferencia entre P2P y C2P?</strong><br>El P2P lo inicia quien paga; el C2P lo inicia el comercio y el cliente lo autoriza con una clave que recibe por mensaje. El segundo deja trazabilidad y permite conciliar ventas.</p><p><strong>&#191;Qu&#233; es el D&#233;bito Inmediato?</strong><br>El instrumento venezolano de cobro recurrente autorizado: domiciliaciones, claves de pago y autorizaciones en l&#237;nea, con verificaci&#243;n de fondos en el momento. Conceptualmente equivale al Pix Autom&#225;tico.</p><p><strong>&#191;Cu&#225;nto puedo enviar por Bre-B?</strong><br>Hasta <strong>COP 12.110.000</strong> por transacci&#243;n en 2026, que es el equivalente a 1.000 UVB. Cada entidad puede fijar topes m&#225;s bajos por seguridad.<a href="https://www.banrep.gov.co/es/bre-b/que-es"><sup>3</sup></a></p><h2>Dejo la m&#233;todolog&#237;a que us&#233; clara</h2><p>Las cifras de Pix provienen de las estad&#237;sticas del Banco Central do Brasil; las de Bre-B, de las publicaciones e indicadores del Banco de la Rep&#250;blica; las de Venezuela, de datos del BCV recogidos por la banca y de prensa especializada, porque no existe una serie p&#250;blica equivalente. <strong>Cada afirmaci&#243;n num&#233;rica lleva su enlace</strong> en el n&#250;mero volado que la sigue.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>El indicador de la <strong>Figura 4</strong> es una <strong>estimaci&#243;n propia</strong>, no un dato publicado por nadie: nace de dividir las cifras de operaciones de cada pa&#237;s entre su poblaci&#243;n, y su aritm&#233;tica completa est&#225; impresa dentro del gr&#225;fico justamente para que se pueda auditar y rebatir. Donde el dato es de prensa y no de fuente primaria, est&#225; dicho en el propio texto. <strong>Corte de la informaci&#243;n: septiembre de 2026.</strong></p><h2>Referencias &#8212; por si quieres profundizar</h2><ol><li><p>Banco Central do Brasil &#8212; <a href="https://www.bcb.gov.br/estabilidadefinanceira/pix">Pix, p&#225;gina oficial</a>.</p></li><li><p>Banco Central do Brasil &#8212; <a href="https://dadosabertos.bcb.gov.br/dataset/pix">Estat&#237;sticas do Pix</a>, portal de datos abiertos.</p></li><li><p>Banco de la Rep&#250;blica &#8212; <a href="https://www.banrep.gov.co/es/bre-b/que-es">Conozca Bre-B</a>.</p></li><li><p>Banco de la Rep&#250;blica &#8212; <a href="https://www.banrep.gov.co/es/bre-b/indicadores">Indicadores de Bre-B</a>.</p></li><li><p>Banco de la Rep&#250;blica &#8212; <a href="https://www.banrep.gov.co/es/noticias/semana-en-siete-meses-bre-b-triplico-sus-transacciones-diarias-de-15-a-5-millones-ya-hay-105-millones-de-llaves-registradas">&#171;En siete meses, Bre-B triplic&#243; sus transacciones diarias&#187;</a>.</p></li><li><p>Banco de la Rep&#250;blica &#8212; <a href="https://d1b4gd4m8561gs.cloudfront.net/sites/default/files/publicaciones/archivos/documento-tecnico-bre-b-febrero-2026.pdf">Documento t&#233;cnico de Bre-B</a> (febrero de 2026, PDF).</p></li><li><p>Banca y Negocios &#8212; <a href="https://www.bancaynegocios.com/asobanca-operaciones-con-pago-movil-representan-el-41-porciento-de-las-transacciones-bancarias-en-venezuela/">&#171;Operaciones con pago m&#243;vil representan el 41 % de las transacciones bancarias en Venezuela&#187;</a>.</p></li><li><p>El Nacional &#8212; <a href="https://www.elnacional.com/2026/08/aumento-de-600-en-la-comision-minima-del-pago-movil-golpea-el-bolsillo-de-los-sectores-mas-vulnerables/">&#171;Aumento de 600 % en la comisi&#243;n m&#237;nima del pago m&#243;vil&#187;</a>.</p></li><li><p>El Est&#237;mulo &#8212; <a href="https://elestimulo.com/elinteres/banca/2026-08-14/bcv-tarifas-operaciones-bancarias/">&#171;BCV actualiza tarifas de operaciones bancarias&#187;</a>.</p></li><li><p>La Prensa de Monagas &#8212; <a href="https://laprensademonagas.com/pago-movil-en-venezuela-crecio-de-6-mil-a-7-mil-operaciones-por-minuto-en-2026/">&#171;Pago m&#243;vil creci&#243; de 6 mil a 7 mil operaciones por minuto en 2026&#187;</a>.</p></li><li><p>Infobae &#8212; <a href="https://www.infobae.com/colombia/2026/05/06/bre-b-disparo-sus-transacciones-en-colombia-y-ya-mueve-hasta-5-millones-de-operaciones-diarias/">&#171;Bre-B dispar&#243; sus transacciones y ya mueve hasta 5 millones de operaciones diarias&#187;</a>.</p></li><li><p>Bank for International Settlements &#8212; <a href="https://www.bis.org/publ/bppdf/bispap152_b_rh.pdf">BIS Papers n.&#186; 152: </a><em><a href="https://www.bis.org/publ/bppdf/bispap152_b_rh.pdf">Faster digital payments</a></em> (PDF).</p></li><li><p>Bank for International Settlements &#8212; <a href="https://www.bis.org/about/bisih/topics/fmis/nexus.htm">Proyecto Nexus</a>.</p></li><li><p>Fintech News America &#8212; <a href="https://fintechnews.am/costa-rica/52549/fast-payment-system-sinpe-movil-driving-financial-inclusion-efficiency-in-costa-rica/">&#171;SINPE M&#243;vil driving financial inclusion in Costa Rica&#187;</a>.</p></li><li><p>Sudeban &#8212; <a href="https://sudeban.gob.ve/">Superintendencia de las Instituciones del Sector Bancario</a>.</p></li><li><p>Banco Central de Venezuela &#8212; <a href="https://www.bcv.org.ve/">sitio oficial</a>.</p></li><li><p>Banco Central de la Rep&#250;blica Argentina &#8212; <a href="https://www.bcra.gob.ar/">sitio oficial</a>.</p></li><li><p>Banco de M&#233;xico &#8212; <a href="https://www.banxico.org.mx/">sitio oficial</a>.</p></li><li><p>Banco Central de Costa Rica &#8212; <a href="https://www.bccr.fi.cr/">SINPE</a>.</p></li></ol>]]></content:encoded></item><item><title><![CDATA[Cerrar una etapa en Yummy: aprendizajes, tecnología, liderazgo y gratitud]]></title><description><![CDATA[Me voy con gratitud, con orgullo por lo construido y con una visi&#243;n mucho m&#225;s clara de lo que significa hacer tecnolog&#237;a dentro de una operaci&#243;n viva, exigente y en constante movimiento.]]></description><link>https://blog.carrillo.app/p/cerrar-una-etapa-en-yummy-aprendizajes</link><guid isPermaLink="false">https://blog.carrillo.app/p/cerrar-una-etapa-en-yummy-aprendizajes</guid><dc:creator><![CDATA[José Carrillo]]></dc:creator><pubDate>Mon, 14 Sep 2026 20:01:31 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!-ZDG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F01d4a046-ff7c-4332-9d06-05ddb02e439f_3112x1738.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-ZDG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F01d4a046-ff7c-4332-9d06-05ddb02e439f_3112x1738.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset image2-full-screen"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-ZDG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F01d4a046-ff7c-4332-9d06-05ddb02e439f_3112x1738.jpeg 424w, https://substackcdn.com/image/fetch/$s_!-ZDG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F01d4a046-ff7c-4332-9d06-05ddb02e439f_3112x1738.jpeg 848w, https://substackcdn.com/image/fetch/$s_!-ZDG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F01d4a046-ff7c-4332-9d06-05ddb02e439f_3112x1738.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!-ZDG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F01d4a046-ff7c-4332-9d06-05ddb02e439f_3112x1738.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-ZDG!,w_5760,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F01d4a046-ff7c-4332-9d06-05ddb02e439f_3112x1738.jpeg" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/01d4a046-ff7c-4332-9d06-05ddb02e439f_3112x1738.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;full&quot;,&quot;height&quot;:813,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:905428,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.carrillo.app/i/215112142?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F01d4a046-ff7c-4332-9d06-05ddb02e439f_3112x1738.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-fullscreen" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!-ZDG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F01d4a046-ff7c-4332-9d06-05ddb02e439f_3112x1738.jpeg 424w, https://substackcdn.com/image/fetch/$s_!-ZDG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F01d4a046-ff7c-4332-9d06-05ddb02e439f_3112x1738.jpeg 848w, https://substackcdn.com/image/fetch/$s_!-ZDG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F01d4a046-ff7c-4332-9d06-05ddb02e439f_3112x1738.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!-ZDG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F01d4a046-ff7c-4332-9d06-05ddb02e439f_3112x1738.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">El lugar donde todos se toman las fotos cuando van a la oficina</figcaption></figure></div><p>Hay etapas profesionales que no se miden solamente por el tiempo que duran, sino por la cantidad de problemas reales que te obligan a entender, la cantidad de personas con las que construyes y la forma en que sales de ellas: <em>con m&#225;s criterio, m&#225;s perspectiva y m&#225;s respeto por el trabajo bien hecho.</em></p><p>Hoy estoy <strong>cerrando mi ciclo en Yummy, una compa&#241;&#237;a que fue para m&#237; mucho m&#225;s que un lugar de trabajo</strong>. Fue un espacio de crecimiento t&#233;cnico, humano y profesional. <em>Un lugar donde tuve la oportunidad de construir soluciones con impacto real, participar en decisiones complejas, liderar iniciativas estrat&#233;gicas y aprender</em>, muchas veces, en escenarios donde no hab&#237;a respuestas simples.</p><p>Me voy con gratitud, con orgullo por lo construido y con una visi&#243;n mucho m&#225;s clara de lo que significa hacer tecnolog&#237;a dentro de una operaci&#243;n viva, exigente y en constante movimiento.</p><h2>Construir tecnolog&#237;a donde ocurre el negocio</h2><p>Durante mi paso por Yummy <strong>trabaj&#233; principalmente en retos asociados al equipo tecnol&#243;gico de finanzas, un equipo donde la tecnolog&#237;a no vive aislada</strong>: cada decisi&#243;n t&#233;cnica tiene relaci&#243;n directa con procesos financieros, conciliaciones, facturaci&#243;n, dispersi&#243;n, reporter&#237;a, integraciones internas, operaci&#243;n diaria y cumplimiento.</p><p>Eso cambia la forma en que uno entiende el software. <em>La velocidad y la forma en la que comienzas a ver el mundo, sobre todo en un pa&#237;s como Venezuela.</em></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>No se trata solo de crear servicios, endpoints o dashboards. <strong>Se trata de construir sistemas que soporten decisiones, que reduzcan fricci&#243;n operativa</strong>, que den trazabilidad, que permitan auditar, que conecten equipos <em>y que ayuden a que el negocio funcione con mayor claridad.</em></p><div class="twitter-embed" data-attrs="{&quot;url&quot;:&quot;https://t.co/3LuY2UsIuk\&quot;>https://t.co/3LuY2UsIuk</a></p>&amp;mdash; Vicente Zavarce (@metavarce) <a href=\&quot;https://x.com/metavarce/status/2082098165180973492?ref_src=twsrc%5Etfw\&quot;>July&quot;,&quot;full_text&quot;:&quot;Una empresa se puede medir con ventas, transacciones y crecimiento hasta el d&#237;a en que el pa&#237;s la necesita para otra cosa. Yummy se adapt&#243; a la emergencia con inteligencia artificial y mucho coraz&#243;n. Les dejo mi conversaci&#243;n con Forbes:\n\n&quot;,&quot;username&quot;:&quot;metavarce&quot;,&quot;name&quot;:&quot;Vicente Zavarce&quot;,&quot;profile_image_url&quot;:&quot;https://pbs.substack.com/profile_images/1977419588913557504/pRlCm8--_normal.jpg&quot;,&quot;date&quot;:&quot;2026-07-28T13:37:40.000Z&quot;,&quot;photos&quot;:[],&quot;quoted_tweet&quot;:{},&quot;reply_count&quot;:8,&quot;retweet_count&quot;:76,&quot;like_count&quot;:365,&quot;impression_count&quot;:8064,&quot;expanded_url&quot;:{&quot;url&quot;:&quot;https://forbescentroamerica.com/2026/07/28/vicente-zavarce-las-startups-estan-llamadas-a-resolver-los-grandes-desafios-de-la-region/&quot;,&quot;title&quot;:&quot;Vicente Zavarce: &#8216;Las startups est&#225;n llamadas a resolver los grandes desaf&#237;os de la regi&#243;n&#8217;&quot;,&quot;description&quot;:&quot;Tras convertir a Yummy en una plataforma de respuesta durante la emergencia provocada por los terremotos en Venezuela, el CEO de la compa&#241;&#237;a sostiene que la inteligencia artificial, el capital inteligente y el liderazgo ser&#225;n determinantes para construir la pr&#243;xima generaci&#243;n de empresas tecnol&#243;gicas en Centroam&#233;rica.&quot;,&quot;domain&quot;:&quot;forbescentroamerica.com&quot;,&quot;image&quot;:&quot;https://pbs.substack.com/news_img/2082098167743741952/8vpjeUin?format=jpg&amp;name=orig&quot;},&quot;video_url&quot;:null,&quot;video_preview_media_key&quot;:null,&quot;belowTheFold&quot;:true}" data-component-name="Twitter2ToDOM"></div><p>Tuve la oportunidad de participar en iniciativas alrededor de:</p><ul><li><p><strong>Modernizaci&#243;n de procesos financieros</strong>: procesos que actualmente no tienen nada que envidiarle a cualquier corporaci&#243;n internacional existente a d&#237;a de hoy.</p></li><li><p><strong>Integraciones con sistemas internos y externos</strong>: con lo &#250;ltimo en tecnolog&#237;a, pero sin dejar de ser estable, escalable y altamente operativo.</p></li><li><p><strong>Automatizaci&#243;n de flujos operativos</strong>: generando asistentes y operaciones automatizadas completamente, que antes requer&#237;an muchas horas hombre.</p></li><li><p><strong>Implementaci&#243;n y evoluci&#243;n de ERP</strong>: gestionando toda la cadena operativa y administrativa, con tecnolog&#237;a de vanguardia. Cuando se habla de Yummy, no son 100 o 200 operaciones aisladas al mes, son millones.</p></li><li><p><strong>Reporting financiero y herramientas de an&#225;lisis</strong>: integrales, que operan a un nivel de seguridad muy alto, con capacidad y disponibilidad 24/7.</p></li><li><p><strong>Conciliaci&#243;n y dispersi&#243;n de fondos</strong>: lo que puede parecer f&#225;cil, y que realmente es una de las cosas m&#225;s complejas de hacer, por el volumen de la operaci&#243;n.</p></li><li><p><strong>Observabilidad y trazabilidad de procesos cr&#237;ticos</strong>: nos pusimos la meta de poder detectar fallos de forma proactiva, documentarlo todo y generar luego de eso, incluso, sistemas de predicci&#243;n. Y s&#237;, se cumpli&#243;.</p></li><li><p><strong>Revisi&#243;n de arquitectura, seguridad y calidad</strong>: modernizando todos y cada uno de los servicios, ejecutando procesos modernos con arquitectura moderna y elastica.</p></li><li><p><strong>Gobernanza de datos y criterios de autoridad sobre la informaci&#243;n</strong>: Trabajando de la mano con otros equipos especializados en el tema, nos convertimos en referencia de c&#243;mo se pueden hacer las cosas cumpliendo estos criterios.</p></li><li><p><strong>Uso pr&#225;ctico de inteligencia artificial</strong>: haci&#233;ndola realmente &#250;til, no simplemente dici&#233;ndole a la IA <em>&#8220;construyeme un front bonito y seguro para ver el proceso de conciliaci&#243;n&#8220;</em>, sino integr&#225;ndola al desarrollo de un equipo altamente profesional y dedicado a su trabajo, no solo como asistente, sino como parte de las soluciones.</p></li></ul><p>Cada una de estas &#225;reas dej&#243; una ense&#241;anza distinta. Algunas fueron profundamente t&#233;cnicas; otras, m&#225;s organizacionales. Muchas fueron ambas al mismo tiempo.</p><h2>De resolver tickets a dise&#241;ar sistemas</h2><p>Uno de los aprendizajes m&#225;s importantes que me llevo es que un equipo t&#233;cnico madura cuando deja de pensar &#250;nicamente en entregables aislados y empieza a pensar en sistemas como soluciones.</p><blockquote><p><em>Un ticket puede cerrar una necesidad puntual. Un sistema bien dise&#241;ado cambia la forma en que el equipo opera.</em></p></blockquote><p>En Yummy pude trabajar en esa transici&#243;n: <strong>liderando a mi equipo para pasar de resolver problemas caso por caso a crear mecanismos m&#225;s repetibles, trazables y sostenibles; a soluciones</strong> sistematizadas y altamente operativas sin perder seguridad o confiabilidad.</p><p>Eso implic&#243; fortalecer metodolog&#237;as de planificaci&#243;n, an&#225;lisis de impacto, documentaci&#243;n t&#233;cnica, <em>criterios de aceptaci&#243;n, revisi&#243;n de arquitectura y validaci&#243;n antes de ejecutar</em>.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Un error al sumar <code>1+1</code> en cualquier equipo puede ser un simple bug, o como mucho implicar una p&#233;rdida de estabilidad en el sistema, <strong>incluso una ca&#237;da total; que, aun siendo muy grave, ese mismo error en finanzas puede hacer que no se puedan ejecutar operaciones financieras en toda una compa&#241;&#237;a</strong>; incluso puede ser motivo de sanci&#243;n administrativa por el regulador.</p><p>Un ejemplo claro fue la evoluci&#243;n hacia una forma m&#225;s estructurada de planificar iniciativas t&#233;cnicas: <em>antes de escribir c&#243;digo, entender el dominio, mapear dependencias, identificar riesgos, revisar impacto entre repositorios, definir escenarios de prueba y separar lo urgente de lo importante</em>.</p><p>Ese tipo de disciplina no hace m&#225;s lento al equipo. Bien aplicada, lo hace m&#225;s confiable. Y claro que no es solo eso, sino <strong>dale la confianza necesaria, y aprender a delegar</strong>, entender que<strong> </strong><em>no todo lo importante es urgente, y que no todo lo urgente es importante; lo urgente e importante se ejecuta al momento; lo urgente se planifica y lo importante se comunica</em>.</p><p>Porque cuando un cambio toca pagos, finanzas, facturaci&#243;n o conciliaci&#243;n, el costo de <em>&#8220;probar en producci&#243;n&#8221;</em> sin suficiente claridad no es solo t&#233;cnico. Puede convertirse en ruido operativo, reprocesos, inconsistencias de datos o p&#233;rdida de confianza entre &#225;reas o, como les reitero, sanciones muy fuertes por parte del regulador.</p><h2>Metodolog&#237;as que realmente aportan</h2><p>Una parte importante de mi paso por Yummy estuvo relacionada con impulsar mejores formas de trabajo. No metodolog&#237;as como ritual vac&#237;o, sino como herramientas pr&#225;cticas para reducir incertidumbre.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Entre las pr&#225;cticas que m&#225;s valor aportaron estuvieron:</p><ul><li><p><em>Planificaci&#243;n t&#233;cnica estructurada</em>, para convertir necesidades ambiguas en rutas de ejecuci&#243;n claras.</p></li><li><p><strong>Spec-Driven Development</strong>, usando especificaciones antes de implementar.</p></li><li><p><strong>Criterios de aceptaci&#243;n en Gherkin</strong>, para que negocio, QA y tecnolog&#237;a hablaran con mayor precisi&#243;n.</p></li><li><p><strong>Definition of Ready</strong> <strong>y Definition of Done</strong>, evitando iniciar trabajo incompleto o cerrar trabajo que a&#250;n no estaba realmente operativo.</p></li><li><p><strong>Revisi&#243;n de arquitectura</strong>, especialmente cuando una decisi&#243;n pod&#237;a afectar varios servicios.</p></li><li><p><strong>An&#225;lisis de impacto multi-repositorio</strong>, necesario en ecosistemas donde un cambio peque&#241;o puede tener consecuencias en varios flujos.</p></li><li><p><strong>KPIs de ingenier&#237;a</strong>, no como herramienta de presi&#243;n, sino como forma de entender tendencias, capacidad, foco y trade-offs.</p></li><li><p><strong>Retrospectivas basadas en hechos</strong>, para aprender de lo ocurrido sin convertir los problemas en culpa.</p></li><li><p><strong>Observabilidad como parte del dise&#241;o</strong>, no como algo que se agrega al final.</p></li><li><p>Automatizaci&#243;n de reportes y seguimiento, para liberar tiempo de coordinaci&#243;n y mejorar visibilidad.</p></li></ul><p><em>Una metodolog&#237;a solo sirve si ayuda a tomar mejores decisiones. Si solo agrega reuniones o documentos sin impacto, no sirve.</em> Esa diferencia fue algo que aprend&#237; hace a&#241;os y reforc&#233; con mucha claridad.</p><h2>Inteligencia artificial como capacidad adicional del equipo de desarrollo e ingenier&#237;a</h2><p>Otro <strong>eje importante fue el uso de herramientas de IA en el trabajo t&#233;cnico.</strong> No como reemplazo del criterio humano, sino como acelerador para tareas donde el contexto, la revisi&#243;n y la estructura importan: <em>an&#225;lisis de repositorios, generaci&#243;n de planes, revisi&#243;n de riesgos, documentaci&#243;n, validaci&#243;n de criterios, preparaci&#243;n de reportes, an&#225;lisis de impacto</em> y soporte a procesos de Tech Lead.</p><p>Uno de los trabajos que m&#225;s orgullo me deja fue contribuir al desarrollo y <em>uso de herramientas internas para AI</em>. Brindandole seguridad, confiabilidad, contexto y sobre todo limites claros de su uso e implementaci&#243;n.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Logrando una forma de organizar contexto, memoria, reglas, agentes, revisiones y documentaci&#243;n para que distintas <strong>herramientas de IA pudieran apoyar el trabajo t&#233;cnico sin depender de improvisaci&#243;n</strong>. Esto me confirm&#243; algo importante: la IA en ingenier&#237;a no se trata de pedirle &#8220;hazme esto&#8221; a una herramienta.</p><p>Se trata de dise&#241;ar un sistema de trabajo donde la IA tenga contexto, l&#237;mites, criterios de calidad y validaci&#243;n humana. <em>Y en estos dos a&#241;os con el impulso de la AI reforc&#233; algo que observava desde los salones de mi antigua alma mater</em>: la diferencia entre usar IA como juguete y usarla como capacidad real est&#225; en la disciplina con la que se integra al proceso.</p><p>Porque l<strong>a AI puede parecer muy moderna, pero su desarrollo comenzo casi desde los inicios de la computaci&#243;n moderna, si mal no recuerdo los a&#241;os 60&#8217;s</strong>. Solo que hace 15 a&#241;os, eran &#8220;algoritmos avanzados&#8220; los que se encargaban de ejecutar esas tareas.</p><h2>Aprender a pensar en trazabilidad</h2><p>En compa&#241;&#237;as con operaci&#243;n financiera, la velocidad importa, pero la trazabilidad importa igual o m&#225;s. <strong>Liderando un equipo t&#233;cnico en Yummy, desarrollando soluciones de alto nivel</strong> para el mercado venezolano, es donde m&#225;s se nota.</p><p>Hay procesos donde no basta con que algo <em>&#8220;funcione&#8221;</em>. Tambi&#233;n hay que poder explicar qu&#233; ocurri&#243;, cu&#225;ndo ocurri&#243;, por qu&#233; ocurri&#243;, qu&#233; sistema lo produjo y c&#243;mo se puede verificar.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Esa forma de pensar estuvo presente en muchos retos: conciliaciones, reportes, integraciones, dispersi&#243;n de fondos, dashboards, logs, validaciones y procesos de auditor&#237;a.</p><p><strong>Un ejemplo pr&#225;ctico:</strong> cuando un flujo financiero atraviesa varios sistemas, no alcanza con saber que el resultado final lleg&#243;. <em>Es necesario poder seguir la historia completa: desde el evento inicial, pasando por las transformaciones, validaciones, decisiones, estados intermedios y resultado final.</em></p><p>Esa trazabilidad reduce fricci&#243;n entre equipos. <em>Permite que soporte, finanzas, producto, data e ingenier&#237;a hablen sobre hechos y no sobre suposiciones.</em></p><h2>Gobernanza de datos: una de las discusiones m&#225;s valiosas</h2><p>Uno de los aprendizajes m&#225;s profundos estuvo alrededor de la gobernanza de datos: acalorado, pero gratificante cuando vez una implementaci&#243;n correcta, certificada y funcional en plena operaci&#243;n.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>En tecnolog&#237;a es com&#250;n escuchar frases como <em>&#8220;una sola fuente de verdad&#8221;</em>. Suena correcto, pero en dominios financieros la realidad suele ser m&#225;s compleja.</p><p>A veces el problema no es tener un solo n&#250;mero. <em>El problema es entender qu&#233; representa cada n&#250;mero, qui&#233;n lo produce, bajo qu&#233; regla, en qu&#233; momento, con qu&#233; responsabilidad y para qu&#233; decisi&#243;n se usa.</em></p><p>No todo dato tiene el mismo peso. No es lo mismo un dato anal&#237;tico que un dato contable. <em>No es lo mismo una m&#233;trica de observaci&#243;n que un registro que puede tener consecuencias fiscales, operativas o regulatorias.</em></p><p>Ese tipo de discusiones me ayud&#243; a reforzar una idea que me parece fundamental:</p><ul><li><p>Lo reversible se puede centralizar con mayor facilidad.</p></li><li><p>Lo irreversible debe quedarse cerca de quien lo firma, lo controla y responde por sus consecuencias.</p></li></ul><p>Esa frase resume mucho de lo que aprend&#237; sobre arquitectura, responsabilidad y operaci&#243;n.</p><h2>Tambi&#233;n hubo momentos dif&#237;ciles</h2><p>No quiero romantizar el proceso. No todo fue simple, ni perfecto, ni siempre c&#243;modo. Todos los procesos son complejos, a&#250;n m&#225;s si sin procesos humanos.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Hubo momentos de presi&#243;n alta, prioridades cambiantes, deuda t&#233;cnica, ambig&#252;edad, diferencias de criterio, urgencias operativas y decisiones tecnicas dif&#237;ciles. <strong>Tambi&#233;n hubo conversaciones donde era necesario defender una postura t&#233;cnica, &#243; reconocer errores, ajustar el enfoque o aceptar que una soluci&#243;n inicial no era suficiente</strong>, incluso enfrentar tus argumentos con los de la mismisima directiva.</p><p>Pero esos momentos tambi&#233;n fueron parte esencial del aprendizaje. <strong>Yummy no es una empresa m&#225;s, aqu&#237; te consigues al director de finanzas un viernes en la oficina y te invita un cafe</strong>, o vas a una reuni&#243;n despues del trabajo y puedes conversar tranquilamente con el CEO. <em>Pero, a mayor confianza, el mayor respeto posible; accesibilidad no siempre representa saltarte pasos necesarios para cumplir tus metas</em>, sino saber aprovechar esa accesibilidad para comunicar lo que sea necesario, en el momento necesario y de la forma correcta.</p><p>Liderar t&#233;cnicamente no es tener siempre la raz&#243;n. Es crear claridad cuando hay ruido. Es saber cu&#225;ndo empujar, cu&#225;ndo escuchar, cu&#225;ndo documentar, cu&#225;ndo escalar y cu&#225;ndo cambiar de opini&#243;n. Por eso es importante tener en cuenta que:</p><ul><li><p>Una buena discusi&#243;n t&#233;cnica no deber&#237;a tratarse de ganar un argumento, sino de encontrar una soluci&#243;n que reduzca riesgo y haga sentido para el negocio.</p></li><li><p>La comunicaci&#243;n efectiva, es tan importante como la arquitectura. Una soluci&#243;n t&#233;cnicamente correcta puede fallar si no est&#225; bien explicada, si no considera a las personas que la operan o si no reconoce las restricciones reales del entorno.</p></li></ul><h2>La respuesta ante momentos inesperados</h2><p>Tambi&#233;n me toc&#243; ver y participar en momentos donde la tecnolog&#237;a tuvo un rol distinto al habitual, bueno, donde la empresa tuvo un movimiento que nunca habia visto en otra empresa, con mis 13 a&#241;os en el sector TI.</p><div class="twitter-embed" data-attrs="{&quot;url&quot;:&quot;https://x.com/metavarce/status/2075944202135814240&quot;,&quot;full_text&quot;:&quot;Habl&#233; con Telemundo sobre lo que hemos vivido estas semanas. Seremos siempre la generaci&#243;n del terremoto del 2026. Pero tambi&#233;n seremos la generaci&#243;n que respondi&#243;, y la que se levanta junta &#127483;&#127466;&#9994; &quot;,&quot;username&quot;:&quot;metavarce&quot;,&quot;name&quot;:&quot;Vicente Zavarce&quot;,&quot;profile_image_url&quot;:&quot;https://pbs.substack.com/profile_images/1977419588913557504/pRlCm8--_normal.jpg&quot;,&quot;date&quot;:&quot;2026-07-11T14:04:01.000Z&quot;,&quot;photos&quot;:[{&quot;img_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!kQpy!,w_1028,c_limit,f_auto,q_auto:best,fl_progressive:steep/l_play_button_usfui2,w_88,e_colorize:0/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F__ss-rehost__tw-video-preview-13_2075943802968092672.jpg&quot;,&quot;link_url&quot;:&quot;https://t.co/vCvEMoWTzG&quot;}],&quot;quoted_tweet&quot;:{},&quot;reply_count&quot;:17,&quot;retweet_count&quot;:331,&quot;like_count&quot;:1303,&quot;impression_count&quot;:116425,&quot;expanded_url&quot;:null,&quot;video_url&quot;:&quot;https://video.twimg.com/amplify_video/2075943802968092672/vid/avc1/1280x720/Qfs47xa-FGHuFndu.mp4&quot;,&quot;video_preview_media_key&quot;:&quot;13_2075943802968092672&quot;,&quot;belowTheFold&quot;:true}" data-component-name="Twitter2ToDOM"></div><blockquote><p><em>Ver como durante un terremoto, toda la directiva de la empresa, llamo personalmente a cada uno de los empleados, de todos los niveles, personalmente para ver si estaban bien. Y no una, sino dos veces. <strong><span>&#161;ES IMPRESIONANTE!</span></strong></em></p></blockquote><p>Durante situaciones de contingencia nacional, qued&#243; claro que <em>(seg&#250;n mi criterio)</em> <strong>la empresa de tecnolog&#237;a m&#225;s innovadora de Venezuela</strong>, y una de las tecnologicas m&#225;s importantes del pa&#237;s, colocaba su equipo, infrestructura y tecnolog&#237;a completa; a disposici&#243;n de los ciudadanos.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Cuando todos preguntamos si podiamos desconectarnos ese d&#237;a para ir a ayudar, nos dijeron que podiamos ayudar desde Yummy. <em>Y para alguien a +1.000 km del desastre, es algo que realmente fue &#250;til</em>. Noches sin dormir, dias de preocupaci&#243;n y aun con traumas desarrollamos soluciones altamente operativas en horas.</p><div class="twitter-embed" data-attrs="{&quot;url&quot;:&quot;https://x.com/metavarce/status/2073120109262983674&quot;,&quot;full_text&quot;:&quot;Basado en data de viajes de Yummy en La Guaira, en este mapa podemos ver las zonas m&#225;s afectadas basado en cantidad de viajes antes y despu&#233;s del terremoto con el hex&#225;gono como origen del viaje. \n\nUna absoluta tragedia la cantidad de hex&#225;gonos en cero &#128148; &quot;,&quot;username&quot;:&quot;metavarce&quot;,&quot;name&quot;:&quot;Vicente Zavarce&quot;,&quot;profile_image_url&quot;:&quot;https://pbs.substack.com/profile_images/1977419588913557504/pRlCm8--_normal.jpg&quot;,&quot;date&quot;:&quot;2026-07-03T19:02:05.000Z&quot;,&quot;photos&quot;:[{&quot;img_url&quot;:&quot;https://pbs.substack.com/media/HMUzwCjWAAAZrxE.jpg&quot;,&quot;link_url&quot;:&quot;https://t.co/wLBuRi3ifK&quot;}],&quot;quoted_tweet&quot;:{},&quot;reply_count&quot;:17,&quot;retweet_count&quot;:515,&quot;like_count&quot;:1909,&quot;impression_count&quot;:110722,&quot;expanded_url&quot;:null,&quot;video_url&quot;:null,&quot;video_preview_media_key&quot;:null,&quot;belowTheFold&quot;:true}" data-component-name="Twitter2ToDOM"></div><p>Contruyendo respuesta, coordinaci&#243;n, visibilidad y soporte cuando el contexto lo exige. <strong>Ese tipo de experiencias recuerdan que detr&#225;s de cada sistema hay personas.</strong> Y que la tecnolog&#237;a, cuando est&#225; bien orientada, puede ser una herramienta concreta para ayudar, ordenar informaci&#243;n y responder mejor.</p><p>Me llevo ese aprendizaje con especial respeto.</p><h3>Lo que me llevo de Yummy</h3><p>Me llevo muchas cosas, no voy a negar que buenas y no tan buenas, pero esas ultimas son tan pocas que realmente s&#233; que no afectar&#225;n en lo m&#225;s minimo, porque as&#237; es Yummy, siempre evoluciona y se adapta para cumplir con lo que realmente importa.</p><ol><li><p>Me llevo una comprensi&#243;n m&#225;s profunda de sistemas financieros y operativos.</p></li><li><p>Me llevo experiencia liderando iniciativas con impacto real.</p></li><li><p>Me llevo mejores criterios para arquitectura, automatizaci&#243;n y datos.</p></li><li><p>Me llevo aprendizajes sobre IA aplicada a ingenier&#237;a.</p></li><li><p>Me llevo conversaciones dif&#237;ciles que me hicieron crecer.</p></li><li><p>Me llevo equipos, personas y momentos que marcaron mi forma de trabajar.</p></li></ol><p>Pero, sobre todo, me llevo una idea muy clara: la tecnolog&#237;a valiosa no es la que se ve m&#225;s sofisticada desde afuera, sino la que resuelve problemas reales, <strong>y esto es sumamente importante en un pa&#237;s tan roto como mi querida Venezuela</strong>. La tenolog&#237;a esta para reducir incertidumbre y permite que otros trabajenmejor.</p><h2>Gracias</h2><p>Gracias a todas las personas con las que compart&#237; este camino en Yummy: <em>la directiva, ingenier&#237;a, producto, finanzas, operaciones, data, liderazgo, soporte y todos los equipos con los que tuve la oportunidad de colaborar, y hasta los que no</em>.</p><p><strong>Gracias por los retos, por la confianza, por las conversaciones, por los aprendizajes y tambi&#233;n por los momentos complejos</strong>. Todo eso forma parte de lo que uno se lleva.</p><p>Cierro esta etapa con gratitud y con orgullo por lo construido.</p><p>Y abro la siguiente con m&#225;s experiencia, m&#225;s criterio y m&#225;s ganas de seguir construyendo tecnolog&#237;a con impacto real.</p>]]></content:encoded></item><item><title><![CDATA[¿Tu base de datos sigue tardando más de 20 minutos en responder? Conoce CQRS]]></title><description><![CDATA[De 20 minutos a 30 segundos &#8212;sin tocar una sola l&#237;nea. C&#243;mo separar lecturas de escrituras en una arquitectura CQRS optimiza tu performance.]]></description><link>https://blog.carrillo.app/p/tu-base-de-datos-sigue-tardando-mas</link><guid isPermaLink="false">https://blog.carrillo.app/p/tu-base-de-datos-sigue-tardando-mas</guid><dc:creator><![CDATA[José Carrillo]]></dc:creator><pubDate>Sun, 07 Jun 2026 00:38:50 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Mf09!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F941be53a-2402-4c9d-8e6b-05ec8d53e20a_2816x1536.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Mf09!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F941be53a-2402-4c9d-8e6b-05ec8d53e20a_2816x1536.png" data-component-name="Image2ToDOM"><div class="image2-inset image2-full-screen"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Mf09!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F941be53a-2402-4c9d-8e6b-05ec8d53e20a_2816x1536.png 424w, https://substackcdn.com/image/fetch/$s_!Mf09!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F941be53a-2402-4c9d-8e6b-05ec8d53e20a_2816x1536.png 848w, https://substackcdn.com/image/fetch/$s_!Mf09!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F941be53a-2402-4c9d-8e6b-05ec8d53e20a_2816x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!Mf09!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F941be53a-2402-4c9d-8e6b-05ec8d53e20a_2816x1536.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Mf09!,w_5760,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F941be53a-2402-4c9d-8e6b-05ec8d53e20a_2816x1536.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/941be53a-2402-4c9d-8e6b-05ec8d53e20a_2816x1536.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;full&quot;,&quot;height&quot;:794,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:5895216,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://carrilloapps.substack.com/i/200945747?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F941be53a-2402-4c9d-8e6b-05ec8d53e20a_2816x1536.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-fullscreen" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Mf09!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F941be53a-2402-4c9d-8e6b-05ec8d53e20a_2816x1536.png 424w, https://substackcdn.com/image/fetch/$s_!Mf09!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F941be53a-2402-4c9d-8e6b-05ec8d53e20a_2816x1536.png 848w, https://substackcdn.com/image/fetch/$s_!Mf09!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F941be53a-2402-4c9d-8e6b-05ec8d53e20a_2816x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!Mf09!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F941be53a-2402-4c9d-8e6b-05ec8d53e20a_2816x1536.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Portada para el art&#237;culo generada con Inteligencia Artificial</figcaption></figure></div><p>Llegaste al l&#237;mite. Tienes el query m&#225;s optimizado que has escrito en tu vida: &#237;ndices compuestos, particiones por fecha, CTEs anidados, vistas materializadas. Y aun as&#237;, ese reporte de balance financiero aparece en pantalla despu&#233;s de 20 minutos. Tu CEO lo abre cada lunes por la ma&#241;ana. Cada lunes, un Slack o correo electr&#243;nico inc&#243;modo.</p><p>Este no es un problema de c&#243;digo. Es un problema de arquitectura. Y la buena noticia es que tiene soluci&#243;n &#8212;una soluci&#243;n que tiene nombre, historia y que hoy vive en producci&#243;n en empresas desde startups hasta Amazon.</p><p>Se llama <strong>CQRS</strong>. Y hoy te cuento, &#191;qu&#233; es y c&#243;mo funciona? As&#237; se aplica en un sistema financiero real para lograr una mejora de m&#225;s de 50 veces en el tiempo de respuesta de nuestros reportes cr&#237;ticos.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2><strong>1. El problema real detr&#225;s del query lento</strong></h2><p>Antes de hablar de la soluci&#243;n, entendamos el problema correctamente. Porque no es solo que &#8220;el query es lento&#8221;.</p><p>Cuando tu base de datos supera los <strong>100 GB</strong>, t&#233;cnicamente est&#225;s en territorio de big data. Y el problema con big data no es almacenarlo; es que las bases de datos transaccionales tradicionales fueron dise&#241;adas para una cosa muy espec&#237;fica, y esa cosa no es generar reportes anal&#237;ticos sobre millones de registros hist&#243;ricos en tiempo real.</p><h3><strong>Lo que tu BD transaccional hace bien</strong></h3><ul><li><p>Registrar una venta nueva al instante</p></li><li><p>Actualizar el saldo de un usuario</p></li><li><p>Buscar un registro exacto por ID</p></li><li><p>Garantizar que dos procesos no choquen (ACID)</p></li><li><p>Operaciones de milisegundos en filas individuales</p></li></ul><h3><strong>Lo que te est&#225; pidiendo el negocio</strong></h3><ul><li><p>Balance Sheet de los &#250;ltimos 12 meses</p></li><li><p>Revenue por categor&#237;a, por regi&#243;n, por hora</p></li><li><p>Conciliaciones cruzando millones de transacciones</p></li><li><p>Reportes que unen 40+ tablas</p></li><li><p>An&#225;lisis sobre a&#241;os de datos hist&#243;ricos</p></li></ul><p>Est&#225;s forzando a tu base de datos a hacer algo para lo que no fue dise&#241;ada. Y el resultado es predecible: contenci&#243;n de locks, I/O saturado, timeouts y un reporte que tarda m&#225;s que una reuni&#243;n de roadmap.</p><h3>La ra&#237;z del problema</h3><p>Est&#225;s usando la misma base de datos para <em>escribir</em> operaciones transaccionales en tiempo real <em>y</em> para <em>leer</em> reportes anal&#237;ticos masivos. Estas dos cargas de trabajo tienen necesidades radicalmente opuestas &#8212;y est&#225;n peleando por los mismos recursos.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2><strong>2. &#191;Qu&#233; es CQRS?</strong></h2><p><strong>CQRS</strong> son las siglas de <em>Command Query Responsibility Segregation</em>. En espa&#241;ol: <strong>Segregaci&#243;n de responsabilidades entre comandos y consultas</strong>.</p><p>El concepto fue formalizado por el arquitecto de software <strong>Greg Young</strong> alrededor de 2010, inspir&#225;ndose en el principio m&#225;s simple de <strong>CQS</strong> (Command Query Separation) de Bertrand Meyer, que dice:</p><p><em>&#8220;Un m&#233;todo deber&#237;a ser un comando que realiza una acci&#243;n, o una consulta que retorna datos &#8212;nunca ambos.&#8221;</em></p><p>CQRS lleva esta idea al nivel arquitect&#243;nico. No solo separamos los m&#233;todos: separamos los <strong>modelos de datos, las bases de datos y los sistemas enteros</strong> seg&#250;n si su prop&#243;sito es escribir o leer.</p><h3>Un ejemplo practico</h3><p>Imagina que tienes una sola caja registradora que sirve para cobrarles a los clientes y para generar el reporte contable de fin de mes. CQRS dice: usa una caja para cobrar (operaciones en vivo) y usa un sistema separado &#8212;optimizado para ello&#8212; para generar los reportes. Cada uno hace lo suyo, y los dos lo hacen mejor.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2><strong>3. La analog&#237;a que lo explica todo</strong></h2><p><em>Piensa en un restaurante de alta rotaci&#243;n.</em></p><p>En la cocina, hay un sistema de comandas: cada mesero escribe el pedido, el chef lo ejecuta. Aqu&#237; la prioridad es <strong>velocidad, exactitud y consistencia</strong>. Si dos mesas piden el mismo plato, los pedidos no pueden mezclarse. Esto es el modelo de escritura: transaccional, secuencial, fuerte en garant&#237;as.</p><p>Ahora imagina que el due&#241;o quiere saber cu&#225;l fue el plato m&#225;s vendido el &#250;ltimo trimestre, en qu&#233; mesa se genera m&#225;s ticket promedio y a qu&#233; hora hay m&#225;s rotaci&#243;n. Si le pregunta al chef en medio del servicio, el restaurante colapsa. Por eso existe la <strong>oficina del contador</strong>: toma los mismos datos (las comandas del d&#237;a), los procesa en otro lugar y genera los reportes sin interrumpir la cocina.</p><p>CQRS es exactamente eso: la cocina sigue funcionando a m&#225;xima velocidad, y la oficina anal&#237;tica trabaja con una copia de los datos &#8212;optimizada para responder preguntas complejas.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2><strong>4. La arquitectura en detalle</strong></h2><p>Veamos c&#243;mo se ve esto en la pr&#225;ctica con el flujo completo de datos.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!w8zP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52212cb2-1ff6-4c1e-82d1-07198bf20728_2816x1536.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!w8zP!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52212cb2-1ff6-4c1e-82d1-07198bf20728_2816x1536.png 424w, https://substackcdn.com/image/fetch/$s_!w8zP!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52212cb2-1ff6-4c1e-82d1-07198bf20728_2816x1536.png 848w, https://substackcdn.com/image/fetch/$s_!w8zP!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52212cb2-1ff6-4c1e-82d1-07198bf20728_2816x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!w8zP!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52212cb2-1ff6-4c1e-82d1-07198bf20728_2816x1536.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!w8zP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52212cb2-1ff6-4c1e-82d1-07198bf20728_2816x1536.png" width="1456" height="794" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/52212cb2-1ff6-4c1e-82d1-07198bf20728_2816x1536.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:794,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:5349952,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://carrilloapps.substack.com/i/200945747?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52212cb2-1ff6-4c1e-82d1-07198bf20728_2816x1536.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!w8zP!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52212cb2-1ff6-4c1e-82d1-07198bf20728_2816x1536.png 424w, https://substackcdn.com/image/fetch/$s_!w8zP!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52212cb2-1ff6-4c1e-82d1-07198bf20728_2816x1536.png 848w, https://substackcdn.com/image/fetch/$s_!w8zP!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52212cb2-1ff6-4c1e-82d1-07198bf20728_2816x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!w8zP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52212cb2-1ff6-4c1e-82d1-07198bf20728_2816x1536.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Arquitectura CQRS &#8212; Separaci&#243;n de Comandos y Consultas</figcaption></figure></div><h3><em>El lado de escritura: Commands</em></h3><p>Todo lo que <em>modifica</em> el estado del sistema pasa por aqu&#237;. Un pago registrado, una factura emitida, un usuario actualizado. Estos son <strong>comandos</strong>: tienen intenci&#243;n clara y el sistema garantiza que se ejecutan correctamente, de forma at&#243;mica y consistente.</p><p>La base de datos de escritura es una BD transaccional cl&#225;sica &#8212;t&#237;picamente <strong>PostgreSQL o MySQL</strong>. Est&#225; optimizada para escrituras r&#225;pidas, integridad referencial y concurrencia segura. Aqu&#237; viven tus garant&#237;as ACID.</p><h3><em>El lado de lectura: Queries</em></h3><p>Todo lo que solo <em>consulta</em> datos vive aqu&#237;. Un reporte de balance, el revenue por categor&#237;a, una conciliaci&#243;n hist&#243;rica. Estas son <strong>consultas</strong>: no modifican nada &#8212;y necesitan hacerlo sobre grandes vol&#250;menes de datos sin interferir con la operaci&#243;n.</p><p>La base de datos de lectura es una BD anal&#237;tica, orientada a columnas &#8212;como <strong>ClickHouse, BigQuery, Redshift o DuckDB</strong>. Puede hacer en segundos lo que una BD transaccional har&#237;a en minutos, porque fue dise&#241;ada exactamente para eso.</p><h3><em>El puente: Change Data Capture (CDC)</em></h3><p>El mecanismo que mantiene ambas bases de datos sincronizadas se llama <strong>CDC</strong>. Cada vez que algo cambia en la BD de escritura, ese cambio se captura y se replica en la BD de lectura &#8212;en tiempo casi real, sin impactar el rendimiento del sistema principal.</p><div class="callout-block" data-callout="true"><p><em><strong>&#191;C&#243;mo funciona CDC t&#233;cnicamente?</strong></em></p><p>PostgreSQL, por ejemplo, mantiene un &#8220;diario de bit&#225;cora&#8221; llamado WAL (Write-Ahead Log). Antes de aplicar cualquier cambio, lo registra ah&#237;. <strong>CDC conecta una herramienta (Debezium, AWS DMS, ClickPipes)</strong> a ese diario y transmite los cambios hacia la BD de lectura de forma continua. Es como fotocopiar cada comanda antes de enviarla a cocina.</p></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2><strong>5. Un caso real: de 27 minutos a 30 segundos</strong></h2><p>Trabajando en un sistema core bancario de puntaje crediticio, nos encontramos con este problema de frente. El reporte de <strong>Balance Sheet</strong> cruzaba decenas de tablas y agregaba a&#241;os de datos hist&#243;ricos sobre una base de datos PostgreSQL que tambi&#233;n estaba sirviendo todas las operaciones transaccionales en vivo.</p><p>Tiempo de generaci&#243;n antes de CQRS: <strong>27 minutos</strong>.</p><ul><li><p><strong>27 min </strong>antes &#8212; OLTP solo</p></li><li><p><strong>30 seg </strong>despu&#233;s &#8212; CQRS</p></li><li><p><strong>54&#215;</strong> en mejora de performance</p></li></ul><p>La soluci&#243;n fue implementar CQRS sobre la infraestructura existente: replicar las tablas relevantes hacia una base de datos anal&#237;tica columnar mediante CDC y redirigir las consultas de reportes para que se ejecutaran ah&#237; &#8212;sin tocar el sistema de escritura ni el c&#243;digo de negocio.</p><div class="callout-block" data-callout="true"><p><em><strong>Resultado en producci&#243;n</strong></em></p><p>El <strong>Balance Sheet que tardaba 27 minutos ahora carga en 30 segundos</strong>. La instancia transaccional dej&#243; de saturarse con queries anal&#237;ticos. Los desarrolladores del equipo pueden ejecutar consultas ad hoc sin riesgo de bloquear la operaci&#243;n. Y el reporte que el C-Level necesitaba cada lunes dej&#243; de ser motivo de conversaci&#243;n inc&#243;moda.</p></div><h3><em>El tipo de query que cambi&#243; todo</em></h3><pre><code><code>-- La misma query. Diferente motor. Eso es CQRS.

SELECT
    account_id,
    sum(debit)           AS total_debit,
    sum(credit)          AS total_credit,
    sum(debit - credit)  AS balance
FROM account_move_line
WHERE date &gt;= '2024-01-01'
  AND company_id = 1
GROUP BY account_id
ORDER BY account_id;

-- En PostgreSQL (OLTP):   ~27 minutos
-- En BD columnar (OLAP):  ~30 segundos</code></code></pre><p>El query no cambi&#243; una sola l&#237;nea. Lo que cambi&#243; fue <em>sobre qu&#233; motor</em> corr&#237;a.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2><strong>6. &#191;Cu&#225;ndo s&#237; y cu&#225;ndo no aplicar CQRS?</strong></h2><p>CQRS no es una bala de plata. Es una herramienta poderosa con un costo real de complejidad operacional. Usarla mal puede crearte m&#225;s problemas de los que resuelve.</p><p><strong>&#10003; &#218;salo cuando...</strong></p><ul><li><p>Tus reportes tardan m&#225;s de lo aceptable y optimizar el query ya no ayuda</p></li><li><p>Tu BD transaccional se satura cuando alguien ejecuta un reporte pesado</p></li><li><p>Tienes m&#225;s de ~50&#8211;100 GB de datos con crecimiento constante</p></li><li><p>Los patrones de lectura y escritura son radicalmente distintos</p></li><li><p>Puedes tolerar datos con un peque&#241;o delay (segundos o minutos)</p></li><li><p>Tienes capacidad para operar y monitorear dos bases de datos</p></li></ul><p><strong>&#10007; No lo uses cuando...</strong></p><ul><li><p>Tu app es simple y tu BD es menor de 10&#8211;20 GB</p></li><li><p>Necesitas consistencia instant&#225;nea al 100% en todo momento</p></li><li><p>Tu equipo no tiene experiencia en sistemas distribuidos</p></li><li><p>Est&#225;s en etapa de validaci&#243;n de producto (premature optimization)</p></li><li><p>No tienes observabilidad para detectar problemas de sincronizaci&#243;n</p></li></ul><div class="callout-block" data-callout="true"><p><em><strong>El costo real de implementaci&#243;n</strong></em></p><p>Pagas con <strong>consistencia eventual</strong>: hay un peque&#241;o delay entre que algo se escribe en la BD transaccional y cuando aparece en la BD de lectura. Para reportes hist&#243;ricos o anal&#237;ticos, esto es completamente aceptable. Para un saldo en tiempo real que mueve dinero en producci&#243;n, puede no serlo. Conoce tu caso de uso antes de decidir.</p></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2><strong>7. &#191;C&#243;mo empezar sin romper producci&#243;n?</strong></h2><p>La belleza de CQRS es que puedes adoptarlo <strong>incrementalmente</strong>. No necesitas reescribir tu sistema. El camino de menor riesgo:</p><ul><li><p><strong>Identifica tu candidato piloto.</strong> El query m&#225;s lento, m&#225;s cr&#237;tico, con mayor impacto en el negocio. Ese es tu punto de entrada.</p></li><li><p><strong>Levanta una BD anal&#237;tica.</strong> ClickHouse, BigQuery, Redshift, DuckDB: los managed services reducen la operaci&#243;n inicial a casi cero. Empieza con una instancia peque&#241;a.</p></li><li><p><strong>Configura el pipeline CDC.</strong> Debezium, AWS DMS, ClickPipes, Airbyte. Replica solo las tablas que necesita tu query piloto &#8212; no toda la BD de golpe.</p></li><li><p><strong>Redirige ese &#250;nico query.</strong> El resto de tu sistema no cambia. Solo el reporte piloto apunta a la BD de lectura.</p></li><li><p><strong>Mide y valida.</strong> Compara tiempos. Verifica que los datos coinciden entre ambas bases. Documenta el delta de sincronizaci&#243;n.</p></li><li><p><strong>Expande gradualmente.</strong> Agrega m&#225;s queries y m&#225;s tablas seg&#250;n el ROI real que vayas viendo. No migres todo de una vez.</p></li></ul><h3>Ejemplo, para que me entiendas</h3><p>La migraci&#243;n incremental reduce el riesgo a casi cero. En ning&#250;n paso modificas el sistema de escritura ni tocas la fuente de verdad. El rollback es trivial: si algo falla en la BD de lectura, simplemente vuelves a apuntar el query al sistema original. Es una de las pocas apuestas arquitect&#243;nicas donde el downside est&#225; completamente acotado.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2><strong>En mi experiencia</strong></h2><p>Si tu reporte tarda 20 minutos, el problema no es el query. El problema es que est&#225;s usando una herramienta de construcci&#243;n para hacer trabajo de an&#225;lisis. CQRS es el reconocimiento arquitect&#243;nico de que <strong>leer y escribir son problemas fundamentalmente diferentes</strong> &#8212;y merecen herramientas diferentes.</p><p>No es magia. Es separaci&#243;n de responsabilidades aplicada a escala de datos. Y cuando lo ves funcionar &#8212;cuando ese reporte que torturaba los lunes de tu C-Level o Stakeholder aparece en 30 segundos&#8212; entiendes por qu&#233; es uno de los patrones m&#225;s influyentes de la ingenier&#237;a de software moderna.</p><p>El siguiente paso es tuyo. Identifica ese query e identifica de qu&#233; tabla o base de datos estamos hablando. Empieza peque&#241;o. Mide todo; eso te ayudar&#225; a dar una idea si el escalamiento necesita segregaci&#243;n de responsabilidades o simple optimizaci&#243;n.</p><h3>&#191;Tienes preguntas?</h3><p>Si est&#225;s evaluando implementar CQRS en tu stack &#8212;sea cual sea el motor anal&#237;tico que consideras&#8212; deja tu pregunta en los comentarios. En el pr&#243;ximo art&#237;culo entro a los detalles de configurar CDC desde PostgreSQL: el WAL, los replication slots y los gotchas que nadie te cuenta hasta que est&#225;s en producci&#243;n.</p>]]></content:encoded></item><item><title><![CDATA[El día que borré una base de datos sin backup]]></title><description><![CDATA[S&#233; que suena dram&#225;tico, y lo es. Borrar una base de datos sin respaldo es realmente destruir todo un producto, y te cuento lo que hice.]]></description><link>https://blog.carrillo.app/p/el-dia-que-borre-una-base-de-datos</link><guid isPermaLink="false">https://blog.carrillo.app/p/el-dia-que-borre-una-base-de-datos</guid><dc:creator><![CDATA[José Carrillo]]></dc:creator><pubDate>Fri, 08 May 2026 18:02:31 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!ul5n!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F575c08a5-0eb4-44c7-9302-d21551c80552_2816x1242.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ul5n!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F575c08a5-0eb4-44c7-9302-d21551c80552_2816x1242.png" data-component-name="Image2ToDOM"><div class="image2-inset image2-full-screen"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ul5n!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F575c08a5-0eb4-44c7-9302-d21551c80552_2816x1242.png 424w, https://substackcdn.com/image/fetch/$s_!ul5n!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F575c08a5-0eb4-44c7-9302-d21551c80552_2816x1242.png 848w, https://substackcdn.com/image/fetch/$s_!ul5n!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F575c08a5-0eb4-44c7-9302-d21551c80552_2816x1242.png 1272w, https://substackcdn.com/image/fetch/$s_!ul5n!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F575c08a5-0eb4-44c7-9302-d21551c80552_2816x1242.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ul5n!,w_5760,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F575c08a5-0eb4-44c7-9302-d21551c80552_2816x1242.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/575c08a5-0eb4-44c7-9302-d21551c80552_2816x1242.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;full&quot;,&quot;height&quot;:1242,&quot;width&quot;:2816,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:6705298,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://carrilloapps.substack.com/i/196905082?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5268df94-cadf-4f6e-8496-4638889125a1_2816x1536.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-fullscreen" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ul5n!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F575c08a5-0eb4-44c7-9302-d21551c80552_2816x1242.png 424w, https://substackcdn.com/image/fetch/$s_!ul5n!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F575c08a5-0eb4-44c7-9302-d21551c80552_2816x1242.png 848w, https://substackcdn.com/image/fetch/$s_!ul5n!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F575c08a5-0eb4-44c7-9302-d21551c80552_2816x1242.png 1272w, https://substackcdn.com/image/fetch/$s_!ul5n!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F575c08a5-0eb4-44c7-9302-d21551c80552_2816x1242.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Aunque no fue mi primera &#8220;computadora&#8220; como tal, si fue mi primera laptop, pero hago enfasis en la marca porque si fue la marca de mi primera PC personal.</figcaption></figure></div><p>Hoy ya <em>hace m&#225;s de 13 a&#241;os que inici&#233; mi carrera profesional</em> como desarrollador de software; como podr&#225;s calcular, <strong>hace 13 a&#241;os, la informaci&#243;n no era tan libre como lo es ahora</strong>, era mucho m&#225;s dif&#237;cil encontrar informaci&#243;n sobre sistemas y programaci&#243;n en general.</p><p><strong>Eso sumado al nivel de penetraci&#243;n que ten&#237;a el internet y el hecho de que tener una computadora en casa, para la mayor&#237;a de familias, era algo realmente dif&#237;cil.</strong> <em>Por sus precios, disponibilidad</em> y, si era como en mi caso, por la zona donde viv&#237;as, quiz&#225;s era m&#225;s dif&#237;cil a&#250;n.</p><h2>&#191;Pero&#8230; c&#243;mo es que borraste una base de datos completa sin antes hacer backup?</h2><p>Hace 13 a&#241;os, <strong>cuando se pensaba en desarrollar un sitio web, muy probablemente se pensaba en usar WordPress o Joomla</strong> para desarrollarlo; era raro y hasta extra&#241;o el sitio web que <em>no operaba con alguno de estos CMS</em>.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Justo para esa &#233;poca, <strong>se populariz&#243; el uso de hosting compartido, que no era m&#225;s que un servidor que corr&#237;a un software (cPanel en la mayor&#237;a de los casos)</strong> que permit&#237;a <em>asignar recursos a diferentes usuarios dentro de un mismo servidor</em>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!tGMV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F627cfc04-d0fb-4c14-af1c-da6dcaeda1cd_780x945.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!tGMV!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F627cfc04-d0fb-4c14-af1c-da6dcaeda1cd_780x945.png 424w, https://substackcdn.com/image/fetch/$s_!tGMV!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F627cfc04-d0fb-4c14-af1c-da6dcaeda1cd_780x945.png 848w, https://substackcdn.com/image/fetch/$s_!tGMV!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F627cfc04-d0fb-4c14-af1c-da6dcaeda1cd_780x945.png 1272w, https://substackcdn.com/image/fetch/$s_!tGMV!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F627cfc04-d0fb-4c14-af1c-da6dcaeda1cd_780x945.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!tGMV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F627cfc04-d0fb-4c14-af1c-da6dcaeda1cd_780x945.png" width="780" height="945" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/627cfc04-d0fb-4c14-af1c-da6dcaeda1cd_780x945.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:945,&quot;width&quot;:780,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:357623,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://carrilloapps.substack.com/i/196905082?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F627cfc04-d0fb-4c14-af1c-da6dcaeda1cd_780x945.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!tGMV!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F627cfc04-d0fb-4c14-af1c-da6dcaeda1cd_780x945.png 424w, https://substackcdn.com/image/fetch/$s_!tGMV!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F627cfc04-d0fb-4c14-af1c-da6dcaeda1cd_780x945.png 848w, https://substackcdn.com/image/fetch/$s_!tGMV!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F627cfc04-d0fb-4c14-af1c-da6dcaeda1cd_780x945.png 1272w, https://substackcdn.com/image/fetch/$s_!tGMV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F627cfc04-d0fb-4c14-af1c-da6dcaeda1cd_780x945.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">cPanel Accelerated 2 - Ya esta era una versi&#243;n con Backups</figcaption></figure></div><blockquote><p>Tener una cuenta cPanel era como tener un apartamento alquilado en un edificio; <strong>una empresa te ofrec&#237;a un segmento peque&#241;o dentro de un servidor dedicado o VPS que ellos administraban, y t&#250; compart&#237;as recursos con otros usuarios</strong>, como la IP, RAM, storage (entre otras cosas) y <em>pod&#237;as alojar all&#237; tu sitio web con LAMP (Linux, Apache, MySQL y PHP)</em> sin mayor problema.</p></blockquote><h3>&#191;Por qu&#233; no hice backup?</h3><p>Esto tiene muchas posibles respuestas, <em>y los que vivieron esa &#233;poca lo pueden tener m&#225;s claro</em>, pero los que no tuvieron la oportunidad, en esa &#233;poca los backups eran:</p><ol><li><p><strong>Era muy costoso;</strong> tener una cuenta con unos pocos megas ya era algo est&#225;ndar y, <em>cuando se ten&#237;a presupuesto, se contrataba m&#225;s almacenamiento para poder alojar pesados archivos Flash u otros archivos multimedia</em>.</p></li><li><p><strong>No todos los proveedores lo ofrec&#237;an; </strong>de hecho, el tener <em>opciones de backup (bien sea manual o autom&#225;tico) no estaba disponible en las primeras versiones de algunos paneles de gesti&#243;n (como cPanel)</em>, por lo que muchos lo que hac&#237;an era descargarse un .sql de toda la base de datos y copiaban el c&#243;digo mediante FTP.</p></li><li><p><strong>El flujo de desarrollo no ten&#237;a stages;</strong> hoy en d&#237;a es imposible pensar en alg&#250;n sistema que no tenga tan siquiera un ambiente adicional al de producci&#243;n. Pero en esa &#233;poca, hablando claramente: <em>si no te alcanzaba para un sistema de backup, menos para una cuenta adicional donde tener una r&#233;plica para desarrollo.</em></p></li><li><p><strong>Falta de inter&#233;s en presencia web: </strong>Aunque puede que hoy sea diferente en muchos sentidos, <em>hace 13 a&#241;os tener un sitio web era &#8220;un lujo&#8221; de algunos negocios que pod&#237;an permitirse tener presencia en internet</em>. Los costos asociados a tener y mantener un sitio web hac&#237;an que muchos prefirieran publicitarse en radio, televisi&#243;n o incluso P&#225;ginas Amarillas y Gu&#237;as Telef&#243;nicas.</p></li></ol><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2><strong>&#191;Qu&#233; sitio web era&#8230; y c&#243;mo lo restablec&#237;?</strong></h2><p>El sitio web era de una estaci&#243;n de radio en la que trabajaba en ese entonces; <em>vale destacar que desde los 8 a&#241;os hasta los 23 a&#241;os mi vida estuvo muy ligada a la radio</em>, televisi&#243;n y medios de comunicaci&#243;n masiva.</p><p>Recuerdo que esos eran de los pocos clientes que exist&#237;an para este tipo de tecnolog&#237;a para ese tiempo, <strong>ya que con el auge de los sitios web, los servicios de streaming para estaciones de radio tambi&#233;n se popularizaron mucho</strong>.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Principalmente, <em>las estaciones de radio miraban de cerca la posibilidad de extender su cobertura y ampliar su masa de oyentes y clientes</em> mediante estos canales digitales, no solo a nivel de streaming, sino tambi&#233;n en las noticias que se pod&#237;an publicar all&#237;.</p><h2>&#191;Por qu&#233; borr&#233; la base de datos?</h2><p>Recuerdo que fue porque el cliente lo necesitaba; ten&#237;a otra p&#225;gina web alojada en su cuenta de cPanel. En ese tiempo, algunas personas hac&#237;an este tipo de cosas: <em>un usuario contrataba una cuenta para 2 o 3 sitios web en cPanel</em> y pod&#237;a desarrollar varias p&#225;ginas web dentro del mismo alojamiento.</p><blockquote><p>Esto puede sonar contradictorio, pero <strong>por eso digo &#8220;algunos&#8221;, y estas personas ten&#237;an muchos motivos para tener cuentas con la posibilidad de tener 2 o 3 sitios web</strong>. Recuerdo que en ese entonces, <em>esto lo hac&#237;a porque con el proveedor que ten&#237;a ofrec&#237;a cuentas con streaming incluido para los que pagaran este tipo de cuenta</em>. Y s&#237;, era m&#225;s valioso que tuvieran un backup y no 6 p&#225;ginas, pero &#191;qu&#233; les puedo decir?, as&#237; eran esos tiempos.</p></blockquote><p>En este caso puntual, la estaci&#243;n de radio ten&#237;a una web principal que yo desarroll&#233; y necesitaban una segunda <em>web para usarla de sitio web exclusivo para m&#243;viles (recuerden que eran a&#241;os previos al 3G, y los famosos dominios m.turadio.com, lo normal de la &#233;poca)</em>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!SwP4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c9f87a7-c564-4059-b173-0bca1f501752_994x710.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!SwP4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c9f87a7-c564-4059-b173-0bca1f501752_994x710.png 424w, https://substackcdn.com/image/fetch/$s_!SwP4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c9f87a7-c564-4059-b173-0bca1f501752_994x710.png 848w, https://substackcdn.com/image/fetch/$s_!SwP4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c9f87a7-c564-4059-b173-0bca1f501752_994x710.png 1272w, https://substackcdn.com/image/fetch/$s_!SwP4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c9f87a7-c564-4059-b173-0bca1f501752_994x710.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!SwP4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c9f87a7-c564-4059-b173-0bca1f501752_994x710.png" width="994" height="710" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1c9f87a7-c564-4059-b173-0bca1f501752_994x710.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:710,&quot;width&quot;:994,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:49699,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://carrilloapps.substack.com/i/196905082?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c9f87a7-c564-4059-b173-0bca1f501752_994x710.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!SwP4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c9f87a7-c564-4059-b173-0bca1f501752_994x710.png 424w, https://substackcdn.com/image/fetch/$s_!SwP4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c9f87a7-c564-4059-b173-0bca1f501752_994x710.png 848w, https://substackcdn.com/image/fetch/$s_!SwP4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c9f87a7-c564-4059-b173-0bca1f501752_994x710.png 1272w, https://substackcdn.com/image/fetch/$s_!SwP4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c9f87a7-c564-4059-b173-0bca1f501752_994x710.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Ya no recuerdo la versi&#243;n exacta, pero as&#237; m&#225;s o menos se miraba la versi&#243;n de PHPMyAdmin que se usaba como cliente en esa &#233;poca en cPanel.</figcaption></figure></div><h3>&#191;D&#243;nde surgi&#243; el problema?</h3><p>Esta nueva web que yo realic&#233; no necesitaba una web exclusiva para celulares m&#243;viles, porque la que yo desarroll&#233; ya ten&#237;a soporte para eso; <strong>yo analizaba los headers y, seg&#250;n el navegador y OS, entregaba una web u otra desde el mismo WordPress, y eso era muy potente para la &#233;poca</strong>. Ya que no necesitaba subdominios o cosas adicionales, incluso se adaptaba seg&#250;n el navegador o resoluci&#243;n de pantalla.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!uVww!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b480cc6-04c3-43df-b9c0-2a8af1543869_1536x1070.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!uVww!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b480cc6-04c3-43df-b9c0-2a8af1543869_1536x1070.jpeg 424w, https://substackcdn.com/image/fetch/$s_!uVww!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b480cc6-04c3-43df-b9c0-2a8af1543869_1536x1070.jpeg 848w, https://substackcdn.com/image/fetch/$s_!uVww!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b480cc6-04c3-43df-b9c0-2a8af1543869_1536x1070.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!uVww!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b480cc6-04c3-43df-b9c0-2a8af1543869_1536x1070.jpeg 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!uVww!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b480cc6-04c3-43df-b9c0-2a8af1543869_1536x1070.jpeg" width="1536" height="1070" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6b480cc6-04c3-43df-b9c0-2a8af1543869_1536x1070.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1070,&quot;width&quot;:1536,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:236196,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://carrilloapps.substack.com/i/196905082?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0514fa70-0d5b-4b0b-8192-60adc9884e64_1536x1536.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!uVww!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b480cc6-04c3-43df-b9c0-2a8af1543869_1536x1070.jpeg 424w, https://substackcdn.com/image/fetch/$s_!uVww!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b480cc6-04c3-43df-b9c0-2a8af1543869_1536x1070.jpeg 848w, https://substackcdn.com/image/fetch/$s_!uVww!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b480cc6-04c3-43df-b9c0-2a8af1543869_1536x1070.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!uVww!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b480cc6-04c3-43df-b9c0-2a8af1543869_1536x1070.jpeg 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">En un estudio de radio como operador y animador cuando ten&#237;a como 19 a&#241;os</figcaption></figure></div><p>Recuerden que <strong>en ese entonces el rey de los navegadores en m&#243;viles era Opera Mini</strong>, y los exploradores de los nuevos <em>Android (en ese &#233;poca nuevos a&#250;n) eran muy diferentes a Opera Mini</em>, y eso hac&#237;a las diferencias entre las webs; casi que se desarrollaba una web para cada navegador y dispositivo.</p><p>El borrado ocurri&#243; justamente porque en las bases de datos en cPanel ten&#237;an nombres similares, algo como: <code>turadio_web101radio</code> y la otra base de datos era algo como <code>turadio_w3b101radio</code>. <strong>Ya que para ese entonces se usaba una herramienta llamada Softaculous</strong>, <em>que a&#250;n hoy en d&#237;a existe y es usada para generar las instancias de WordPress</em> y otras herramientas.</p><p>No solo yo la usaba, sino quiz&#225;s quien hizo esa primera versi&#243;n de la web, y por eso quiz&#225;s <strong>se gener&#243; similar el nombre de las bases de datos</strong>. Lo que me confundi&#243; y termin&#233; borrando la base de datos equivocada.</p><div class="poll-embed" data-attrs="{&quot;id&quot;:509390}" data-component-name="PollToDOM"></div><h2>&#191;Fue muy costoso reestablecerlo?</h2><p>Aqu&#237; viene el giro de la historia, porque la verdad <strong>no fue tan complejo, y aunque en ese entonces yo acostumbraba a trabajar 100% live</strong>, es decir, todos los cambios se realizaban directamente sobre el sitio web en producci&#243;n, <em>este era un proyecto que ten&#237;a relativamente poco funcionando</em>. Cerca de 3 meses para ese momento, si mal no recuerdo bien.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!AwMx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66759903-fab4-4b85-b204-631a118dc355_2048x1048.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!AwMx!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66759903-fab4-4b85-b204-631a118dc355_2048x1048.jpeg 424w, https://substackcdn.com/image/fetch/$s_!AwMx!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66759903-fab4-4b85-b204-631a118dc355_2048x1048.jpeg 848w, https://substackcdn.com/image/fetch/$s_!AwMx!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66759903-fab4-4b85-b204-631a118dc355_2048x1048.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!AwMx!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66759903-fab4-4b85-b204-631a118dc355_2048x1048.jpeg 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!AwMx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66759903-fab4-4b85-b204-631a118dc355_2048x1048.jpeg" width="2048" height="1048" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/66759903-fab4-4b85-b204-631a118dc355_2048x1048.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1048,&quot;width&quot;:2048,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:257979,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://carrilloapps.substack.com/i/196905082?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd1e9267-9a7e-4b4d-9bee-004b9e1bea7f_2048x1536.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!AwMx!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66759903-fab4-4b85-b204-631a118dc355_2048x1048.jpeg 424w, https://substackcdn.com/image/fetch/$s_!AwMx!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66759903-fab4-4b85-b204-631a118dc355_2048x1048.jpeg 848w, https://substackcdn.com/image/fetch/$s_!AwMx!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66759903-fab4-4b85-b204-631a118dc355_2048x1048.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!AwMx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66759903-fab4-4b85-b204-631a118dc355_2048x1048.jpeg 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Lamentablemente, no tengo fotos de mi primera laptop. Luego tuve que venderla y comenzar desde cero con una laptop de las que entregaban por el gobierno</figcaption></figure></div><p>En ese entonces <strong>yo usaba un viejo laptop VIT (Venezolana de Industria Tecnol&#243;gica) para desarrollar, y en ese i3 de 2-3.&#170; generaci&#243;n con XAMPP</strong> correctamente (s&#237;, olv&#237;date de Docker, en ese entonces XAMPP era la forma y el m&#233;todo ideal) ejecutaba el desarrollo base de plantillas y plugins.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><blockquote><p>A los 17 a&#241;os, realmente ya ten&#237;a como 10 a&#241;os programando. <strong>Recuerdo que mi primer &#8220;sistema&#8221; estaba escrito en C, y era una calculadora desde terminal que logr&#233; copiar de una enciclopedia vieja y desarrollar en una IBM con Windows 2000</strong> que ten&#237;a en mi casa. <em>En esa enciclopedia se explicaba algo de sistemas, y en ella estaban capturas de pantalla de c&#243;mo hacerla</em>, pero no se confundan, no estaba todo el c&#243;digo, solo capturas de algunos segmentos.</p></blockquote><p>As&#237; que siempre ten&#237;a una &#8220;base&#8221; de los datos a modo de demostraci&#243;n en mi laptop, as&#237; que eso sirvi&#243; mucho. Pero creo que m&#225;s que eso, sirvieron much&#237;simo algunas acciones que tuve, como:</p><ul><li><p><strong>Comunicar correcta y eficientemente lo que pas&#243;: </strong>Recuerdo<strong> </strong>que en ese momento me dije algo como: &#8220;No<em> importa lo que pase, los llamo y les digo que borre la base de datos&#8221;.</em></p></li><li><p><strong>Serenidad y control de da&#241;os:</strong> No se debe confundir estar sereno con &#8220;no importa&#8221;; son dos cosas totalmente diferentes. Cuando est&#225;s sereno, puedes medir y tomar acciones de forma m&#225;s correcta; <em>eso facilita el control de da&#241;os y poder dar soluciones realmente eficientes.</em></p></li><li><p><strong>Compromiso con una soluci&#243;n real:</strong> porque justamente no todas las soluciones son las m&#225;s eficientes o indicadas para una soluci&#243;n real; por eso es importante tener claro lo que se quiere lograr y, seg&#250;n eso, desarrollar una forma de hacerlo funcionar.</p></li><li><p><strong>Asumir consecuencias: Creo</strong> que sin esto no hubiera podido llegar a donde estoy, <em>pero recuerdo que en ese momento lo primero que ten&#237;a claro era que iba a tomar las consecuencias</em> de lo que pas&#243; y solucionarlo.</p></li></ul><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h4>La primera desvelada profesional que tuve</h4><p>S&#237;, no les voy a mentir diciendo que m&#225;gicamente pude hacer algo que solucion&#243; todo y resolvi&#243; el problema; eso no pas&#243; y, por ganar m&#225;s lectores, no dir&#233; lo contrario. <em>Recuerdo que fue la primera vez como programador ya profesionalmente; me qued&#233; toda la noche despierto</em> restableciendo todo.</p><p>Y no se confundan, digo que fue la primera vez porque antes lo hice, pero solo por diversi&#243;n, y <strong>en esta ocasi&#243;n fue porque ten&#237;a claro que era un compromiso profesional</strong> que cumplir antes con quien me contrat&#243; para desarrollar su sitio web.</p><p><strong>Terminando de ajustar y reconstruir todo unas 10 horas luego</strong>, ya que todos los archivos y scripts quedaron intactos, <em>pero temas relativos a ajustes, configuraciones y personalizaciones se perdieron.</em></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2>Cosas que cambiaron desde ese d&#237;a</h2><p>Muchas, la verdad, no les voy a mentir, creo que, adem&#225;s de anecd&#243;tica, esa experiencia fue traum&#225;tica, y la forma en la que desarrollaba cambi&#243; desde ese d&#237;a.</p><p>Fueron varias, pero pueden detallarse en:</p><ul><li><p><strong>Sin documentaci&#243;n, es imposible avanzar:</strong> s&#233; que es quiz&#225;s algo burocr&#225;tico, pero esto es indispensable en todo proceso. <em>Si quieres que algo salga bien, primero documenta</em>; eso te sirve para aclarar tus ideas y dejar claro c&#243;mo van a ser las cosas desde el inicio.</p></li><li><p><strong>Todo Plan A debe tener un Plan B:</strong> no importa el cambio que realices, siempre tienes que tener la noci&#243;n clara de lo que puede llegar a fallar, y <em>debes tomarte el tiempo de tener un plan de respaldo</em> en caso de que no salga como esperas.</p></li><li><p><strong>Conf&#237;a en ti siempre: </strong>si te fijas, solo ten&#237;a 17 a&#241;os, y excluirme en eso posiblemente no me hubiera llevado a donde estoy, <em>porque sin compromiso y profesionalismo es imposible que alguien crea en ti.</em> Nadie creer&#225; en ti si t&#250; mismo no lo haces primero, bajo cualquier circunstancia.</p></li></ul><p>Pero eso nada m&#225;s no es suficiente; <strong>recuerda siempre estar en lugares donde puedes cometer errores sin miedo a perder tu empleo</strong> solo por eso, y s&#237;, esto tiene asteriscos, no es que todo lo que hagas va a estar mal, pero <em>es importante que siempre comuniques las cosas de forma clara y eficiente</em>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!jTnx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42823b61-6d86-4361-85e5-c9cafb13cdc0_2048x1223.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!jTnx!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42823b61-6d86-4361-85e5-c9cafb13cdc0_2048x1223.jpeg 424w, https://substackcdn.com/image/fetch/$s_!jTnx!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42823b61-6d86-4361-85e5-c9cafb13cdc0_2048x1223.jpeg 848w, https://substackcdn.com/image/fetch/$s_!jTnx!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42823b61-6d86-4361-85e5-c9cafb13cdc0_2048x1223.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!jTnx!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42823b61-6d86-4361-85e5-c9cafb13cdc0_2048x1223.jpeg 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!jTnx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42823b61-6d86-4361-85e5-c9cafb13cdc0_2048x1223.jpeg" width="2048" height="1223" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/42823b61-6d86-4361-85e5-c9cafb13cdc0_2048x1223.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1223,&quot;width&quot;:2048,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:324286,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://carrilloapps.substack.com/i/196905082?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca9967a9-c79c-4949-8996-74b83c66d287_2048x1542.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!jTnx!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42823b61-6d86-4361-85e5-c9cafb13cdc0_2048x1223.jpeg 424w, https://substackcdn.com/image/fetch/$s_!jTnx!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42823b61-6d86-4361-85e5-c9cafb13cdc0_2048x1223.jpeg 848w, https://substackcdn.com/image/fetch/$s_!jTnx!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42823b61-6d86-4361-85e5-c9cafb13cdc0_2048x1223.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!jTnx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42823b61-6d86-4361-85e5-c9cafb13cdc0_2048x1223.jpeg 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Mi Setup actual - Tengo varios equipos, pero la principal es una Asus Tuf Gaming y una MacBook Air con procesar Apple Silicon y un monitor extra.</figcaption></figure></div><p>Si est&#225;s comunicando todo oportunamente, y siguiendo todo seg&#250;n la documentaci&#243;n y convenciones, lo esperado es que, si algo llega a fallar, puedas tener la oportunidad de identificar el fallo, documentarlo y adquirir la experiencia suficiente para que este tipo de cosas no pasen nuevamente.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p>]]></content:encoded></item><item><title><![CDATA[Recibe dinero desde Europa fácil, rápido y SIN COSTO (Guía Facebank)]]></title><description><![CDATA[Ahora puedes recibir Euros desde tu cuenta de Facebank en Puerto Rico. Tienes IBAN y son totalmente gratis hasta los 2.000 D&#243;lares.]]></description><link>https://blog.carrillo.app/p/recibe-dinero-desde-europa-facil</link><guid isPermaLink="false">https://blog.carrillo.app/p/recibe-dinero-desde-europa-facil</guid><dc:creator><![CDATA[José Carrillo]]></dc:creator><pubDate>Fri, 08 May 2026 13:55:01 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!fAHo!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6332568-7a53-4075-854c-be3fdb3cad6a_2490x1389.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!fAHo!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6332568-7a53-4075-854c-be3fdb3cad6a_2490x1389.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fAHo!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6332568-7a53-4075-854c-be3fdb3cad6a_2490x1389.jpeg 424w, https://substackcdn.com/image/fetch/$s_!fAHo!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6332568-7a53-4075-854c-be3fdb3cad6a_2490x1389.jpeg 848w, https://substackcdn.com/image/fetch/$s_!fAHo!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6332568-7a53-4075-854c-be3fdb3cad6a_2490x1389.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!fAHo!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6332568-7a53-4075-854c-be3fdb3cad6a_2490x1389.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!fAHo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6332568-7a53-4075-854c-be3fdb3cad6a_2490x1389.jpeg" width="728" height="406" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b6332568-7a53-4075-854c-be3fdb3cad6a_2490x1389.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;normal&quot;,&quot;height&quot;:812,&quot;width&quot;:1456,&quot;resizeWidth&quot;:728,&quot;bytes&quot;:2777270,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://carrilloapps.substack.com/i/196903897?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6332568-7a53-4075-854c-be3fdb3cad6a_2490x1389.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!fAHo!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6332568-7a53-4075-854c-be3fdb3cad6a_2490x1389.jpeg 424w, https://substackcdn.com/image/fetch/$s_!fAHo!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6332568-7a53-4075-854c-be3fdb3cad6a_2490x1389.jpeg 848w, https://substackcdn.com/image/fetch/$s_!fAHo!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6332568-7a53-4075-854c-be3fdb3cad6a_2490x1389.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!fAHo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6332568-7a53-4075-854c-be3fdb3cad6a_2490x1389.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Facebank es uno de los bancos m&#225;s utilizados por freelancers de toda Latinoam&#233;rica, no solo por su facilidad de uso, amplias caracter&#237;sticas y formato 100% digital. Sino porque ha demostrado ser un banco estable y confiable para todos sus clientes en los diferentes pa&#237;ses de Latinoam&#233;rica.</p><p>Este banco destaca por un soporte muy bueno, seg&#250;n mi experiencia personal. Ofrece un servicio base de cuentas bancarias, ahorro y cr&#233;dito importante, pero sin lugar a dudas su estabilidad y servicio como PipolPay lo hacen destacar.</p><h3>El gran beneficio: Euros a tu cuenta en D&#243;lares</h3><p>Hasta hace poco, mover dinero desde Europa hacia bancos americanos o con base en Puerto Rico sol&#237;a implicar comisiones altas de bancos intermediarios y swaps de divisas poco favorables.</p><p>Con esta nueva actualizaci&#243;n:</p><ul><li><p><strong>Sin costo:</strong> Las transferencias por montos iguales o inferiores a <strong>2,000&#8364;</strong> no tienen costo de recepci&#243;n por parte de Facebank.</p></li><li><p><strong>Conversi&#243;n autom&#225;tica:</strong> El dinero se acredita directamente en tu cuenta en <strong>D&#243;lares (USD)</strong>.</p></li><li><p><strong>Rapidez:</strong> El tiempo estimado de acreditaci&#243;n es de hasta <strong>2 d&#237;as h&#225;biles</strong>.</p></li></ul><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p><h3>&#191;C&#243;mo recibir tu pago? (Datos necesarios)</h3><p>Para que la transferencia llegue correctamente y no sea rebotada (lo cual podr&#237;a generar cargos adicionales), debes proporcionar los siguientes datos a la persona o empresa que env&#237;a el dinero:</p><ol><li><p><strong>Beneficiario:</strong> Prisma FACEBANK.</p></li><li><p><strong>IBAN:</strong> (Este dato lo encuentras dentro de tu banca en l&#237;nea o app de Facebank espec&#237;fica para Europa).</p></li><li><p><strong>Concepto de la transferencia (CRUCIAL):</strong> Aqu&#237; es donde muchos fallan. Debes indicar exactamente:</p><ul><li><p><strong>FFC</strong> + Tu Nombre Completo + Tu n&#250;mero de cuenta Facebank.</p></li><li><p><em>Ejemplo:</em> <code>FFC Juan P&#233;rez 6352XXXXXX</code></p></li></ul></li></ol><blockquote><p><strong>Nota de seguridad:</strong> Aseg&#250;rate de completar estos datos correctamente en el campo de &#8220;informaci&#243;n adicional&#8221; o &#8220;concepto&#8221; para evitar demoras en el proceso.</p></blockquote><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Compartir Jos&#233; Carrillo&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.carrillo.app/?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Compartir Jos&#233; Carrillo</span></a></p><h3><strong>Pros (Ventajas)</strong></h3><ul><li><p><strong>Ahorro en montos bajos:</strong> La ausencia de comisiones para transferencias menores a <strong>2,000&#8364;</strong> es ideal para pagos recurrentes peque&#241;os.</p></li><li><p><strong>Eficiencia de costos:</strong> Al <strong>eliminar intermediarios</strong>, se reducen las tarifas ocultas que suelen aplicar los bancos corresponsales.</p></li><li><p><strong>Optimizaci&#243;n para Freelancers:</strong> Es una soluci&#243;n perfecta para quienes trabajan con clientes en la <strong>Zona Euro</strong> (Espa&#241;a, Alemania, Francia, etc.), facilitando el cobro de honorarios.</p></li><li><p><strong>Simplicidad operativa:</strong> Menos actores involucrados suele traducirse en una mayor rapidez en la acreditaci&#243;n de los fondos.</p></li></ul><h3><strong>Contras (Desventajas o Limitaciones)</strong></h3><ul><li><p><strong>Costo escalable:</strong> Si el monto supera los <strong>2,000&#8364;</strong>, se aplica un tarifario adicional, lo que puede reducir la competitividad del servicio para operaciones grandes.</p></li><li><p><strong>Restricci&#243;n geogr&#225;fica estricta:</strong> El hecho de que deba provenir <strong>exclusivamente de bancos europeos</strong> limita su uso para clientes en EE. UU., Asia o Latinoam&#233;rica.</p></li><li><p><strong>Rigidez en la informaci&#243;n:</strong> Existe una dependencia cr&#237;tica del campo <strong>&#8220;Concepto&#8221;</strong>. Un error manual en este apartado puede derivar en retrasos, rebotes de fondos o procesos de soporte tediosos.</p></li><li><p><strong>Limitaci&#243;n de red:</strong> Al no usar canales tradicionales (o al saltarse intermediarios), se pierde la flexibilidad de recibir fondos de entidades fuera del circuito europeo especificado.</p></li></ul><h3>Mi an&#225;lisis como experto</h3><p>Este movimiento de Facebank busca competir directamente con plataformas como Wise o Revolut, ofreciendo la ventaja de tener el dinero en una instituci&#243;n bancaria establecida y conectada al sistema americano. Para quienes desarrollamos proyectos o gestionamos servicios internacionales a Europa, reducir la fricci&#243;n de los pagos transatl&#225;nticos es fundamental para la escalabilidad.</p><p>Si tienes clientes en la Uni&#243;n Europea, esta es, sin duda, una de las opciones m&#225;s rentables a d&#237;a de hoy.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscr&#237;bete ahora&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.carrillo.app/subscribe?"><span>Suscr&#237;bete ahora</span></a></p><h3>&#191;Necesitas ayuda configurando tu cuenta?</h3><p>Si ya eres usuario de Facebank y no encuentras tus datos para recibir transferencias SEPA (Europa), d&#233;jamelo en los comentarios y puedo preparar un tutorial r&#225;pido de d&#243;nde encontrar tu IBAN en la plataforma.</p><p><strong>&#191;Ya probaste esta funci&#243;n? &#191;Qu&#233; tal fue tu experiencia con la tasa de cambio? &#161;Te leo!</strong></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p>]]></content:encoded></item><item><title><![CDATA[¿Programador o desarrollador de software?]]></title><description><![CDATA[En mi experiencia, esta distinci&#243;n es el primer muro f&#237;sico con el que choca un profesional cuando llega a una compa&#241;&#237;a real. Aqu&#237; te explico por qu&#233;.]]></description><link>https://blog.carrillo.app/p/programador-o-desarrollador-de-software</link><guid isPermaLink="false">https://blog.carrillo.app/p/programador-o-desarrollador-de-software</guid><dc:creator><![CDATA[José Carrillo]]></dc:creator><pubDate>Fri, 08 May 2026 13:48:26 GMT</pubDate><enclosure url="https://substackcdn.com/image/youtube/w_728,c_limit/7s2HGWiKfkU" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div id="youtube2-7s2HGWiKfkU" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;7s2HGWiKfkU&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/7s2HGWiKfkU?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><p>Si est&#225;s dando tus primeros pasos en el mundo de la tecnolog&#237;a, es muy probable que uses los t&#233;rminos &#8220;programar&#8221; y &#8220;desarrollar software&#8221; como si fueran sin&#243;nimos. Pero, si queremos hablar con propiedad y proyectar una carrera s&#243;lida, debemos entender que <strong>no son lo mismo</strong>.</p><p>En mi experiencia, esta distinci&#243;n es el primer muro f&#237;sico con el que choca un profesional cuando llega a una compa&#241;&#237;a real. Aqu&#237; te explico por qu&#233;.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Este Substack est&#225; apoyado por los lectores. Para recibir nuevos posts y apoyar mi trabajo, considera convertirte en un suscriptor de contenido gratis o un suscriptor de pago.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2>El Programador: El artesano del c&#243;digo</h2><p>La capacidad principal de un programador es <strong>escribir c&#243;digo</strong>. Es quien tiene la destreza t&#233;cnica para realizar pruebas, optimizar funciones y llevar ese c&#243;digo a un alto nivel de ejecuci&#243;n. Es una pieza indispensable, pero es solo una parte del rompecabezas.</p><h2>El Desarrollador de Software: El arquitecto del sistema</h2><p>Un desarrollador va mucho m&#225;s all&#225; de &#8220;picar c&#243;digo&#8221;. Es alguien que entiende el ciclo completo desde la concepci&#243;n de la idea. Para ser un desarrollador integral, debes dominar conceptos que ocurren &#8220;detr&#225;s de escena&#8221;:</p><ul><li><p><strong>Arquitectura y Bases de Datos:</strong> C&#243;mo se estructura y se almacena la informaci&#243;n.</p></li><li><p><strong>Ciberseguridad y Autenticaci&#243;n:</strong> Proteger la integridad del sistema.</p></li><li><p><strong>Resiliencia:</strong> La capacidad de un sistema para tolerar fallos sin que ocurra una ca&#237;da cr&#237;tica que deje inoperativo, por ejemplo, a un banco.</p></li></ul><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscr&#237;bete ahora&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.carrillo.app/subscribe?"><span>Suscr&#237;bete ahora</span></a></p><h2>La paradoja del Senior: Menos c&#243;digo, m&#225;s pensamiento</h2><p>Algo que sorprende a muchos es que, a medida que avanzas en tu carrera, <strong>programas menos</strong>.</p><ul><li><p>En un nivel <strong>Junior</strong>, el porcentaje de codificaci&#243;n es alto porque est&#225;s experimentando.</p></li><li><p>En un nivel <strong>Senior</strong>, el tiempo dedicado a escribir c&#243;digo puede bajar hasta un <strong>20%</strong>.</p></li><li><p>Como <strong>L&#237;der T&#233;cnico</strong>, ese porcentaje se reduce a&#250;n m&#225;s debido a las responsabilidades de liderazgo y estrategia.</p></li></ul><p>El resto del tiempo se invierte en leer documentaci&#243;n, dise&#241;ar soluciones, participar en metodolog&#237;as &#225;giles (como Scrum) y planificar con el equipo (PMs, QAs, TLs).</p><h2>Mi consejo si est&#225;s empezando</h2><p>No caigas en la trampa de la &#8220;deuda t&#233;cnica eterna&#8221; por no documentar o no planificar. Si quieres destacar:</p><ol><li><p><strong>Aprende a leer c&#243;digo ajeno:</strong> Antes de escribir el tuyo, entiende c&#243;mo resuelven problemas los dem&#225;s.</p></li><li><p><strong>Planifica antes de actuar:</strong> No lances la primera l&#237;nea de c&#243;digo sin tener claras las bases y la escalabilidad.</p></li><li><p><strong>Entiende el negocio:</strong> Un desarrollador que comprende el producto es mucho m&#225;s valioso que uno que solo sigue instrucciones t&#233;cnicas.</p></li></ol><p>Como suelo decir: <strong>No es lo mismo saber hacer flechas que ser selecci&#243;n nacional de tiro con arco</strong>. Programar es una herramienta; desarrollar es el arte completo.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Este Substack est&#225; apoyado por los lectores. Para recibir nuevos posts y apoyar mi trabajo, considera convertirte en un suscriptor de contenido gratis o un suscriptor de pago.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Inicialización de pagos: El nuevo reto de Bre-b en Colombia]]></title><description><![CDATA[El dinero que se mueve solo: Open Banking, Bre-B y la revoluci&#243;n de los pagos instant&#225;neos desde la inicializaci&#243;n de pagos en Colombia.]]></description><link>https://blog.carrillo.app/p/inicializacion-de-pagos-el-nuevo</link><guid isPermaLink="false">https://blog.carrillo.app/p/inicializacion-de-pagos-el-nuevo</guid><dc:creator><![CDATA[José Carrillo]]></dc:creator><pubDate>Thu, 07 May 2026 16:51:14 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!fW68!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15809d2c-33b4-4854-894d-9aa694bd4e56_2560x1396.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!fW68!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15809d2c-33b4-4854-894d-9aa694bd4e56_2560x1396.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fW68!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15809d2c-33b4-4854-894d-9aa694bd4e56_2560x1396.jpeg 424w, https://substackcdn.com/image/fetch/$s_!fW68!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15809d2c-33b4-4854-894d-9aa694bd4e56_2560x1396.jpeg 848w, https://substackcdn.com/image/fetch/$s_!fW68!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15809d2c-33b4-4854-894d-9aa694bd4e56_2560x1396.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!fW68!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15809d2c-33b4-4854-894d-9aa694bd4e56_2560x1396.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!fW68!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15809d2c-33b4-4854-894d-9aa694bd4e56_2560x1396.jpeg" width="1456" height="794" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/15809d2c-33b4-4854-894d-9aa694bd4e56_2560x1396.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:794,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:435242,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://carrilloapps.substack.com/i/196798934?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15809d2c-33b4-4854-894d-9aa694bd4e56_2560x1396.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!fW68!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15809d2c-33b4-4854-894d-9aa694bd4e56_2560x1396.jpeg 424w, https://substackcdn.com/image/fetch/$s_!fW68!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15809d2c-33b4-4854-894d-9aa694bd4e56_2560x1396.jpeg 848w, https://substackcdn.com/image/fetch/$s_!fW68!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15809d2c-33b4-4854-894d-9aa694bd4e56_2560x1396.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!fW68!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15809d2c-33b4-4854-894d-9aa694bd4e56_2560x1396.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Imagina poder pagar una cuenta en un restaurante o transferir dinero a un amigo en segundos, sin importar el banco de cada uno, las 24 horas del d&#237;a, solo con tu n&#250;mero de celular, correo electr&#243;nico o un nombre de usuario. <strong>Esto ya es realidad en pa&#237;ses como Brasil y Colombia gracias a innovaciones como PIX y BRE-B</strong>, impulsadas por tecnolog&#237;as como el open banking y open finance.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Durante d&#233;cadas, el procesamiento de pagos digitales estuvo dominado por un modelo relativamente simple: <em>un usuario paga con una tarjeta y una red de intermediarios procesa la transacci&#243;n. Visa, Mastercard, procesadores, adquirentes y emisores participan en la operaci&#243;n.</em> Operaciones que pueden llevar d&#237;as en terminarse; incluso para hacer una simple transferencia, se depend&#237;a en gran medida de la interoperabilidad de distintas operaciones, incluso entre un mismo pa&#237;s.</p><p><strong>Durante d&#233;cadas, el sistema financiero global funcion&#243; bajo un modelo de &#8220;silos aut&#243;nomos y cerrados&#8221;.</strong> Tu dinero y, m&#225;s importante a&#250;n, <em>tus datos financieros, viv&#237;an encerrados en la b&#243;veda digital de tu banco</em>. Si otra aplicaci&#243;n quer&#237;a interactuar con ese dinero, el proceso era lento, costoso y estaba lleno de peajes tecnol&#243;gicos.</p><p>Ese modelo fue relativamente exitoso, pero tambi&#233;n tiene limitaciones claras, que a 2026 son m&#225;s visibles que nunca:</p><ul><li><p>Costos elevados de procesamiento</p></li><li><p>Tiempos de liquidaci&#243;n de uno a tres d&#237;as</p></li><li><p>Dependencias de redes privadas</p></li><li><p>Baja inclusi&#243;n financiera en algunos mercados</p></li></ul><h2>&#191;Qu&#233; es Open Banking y Open Finance?</h2><p>El <em>open banking no es m&#225;s que una herramienta que permite a los bancos compartir datos de cuentas y datos de pagos de forma segura con terceros autorizados, usando APIs estandarizadas.</em> <strong>Esto habilita servicios como la iniciaci&#243;n de pagos directos desde apps externas</strong>, mejorando la competencia y la innovaci&#243;n.</p><h3 style="text-align: center;">Antes de continuar recuerda suscribirte</h3><p style="text-align: center;">Con esta acci&#243;n me ayudas a seguir generando contenido especializado con este que estas mirando ahora con mayor frecuencia y detalle al respecto.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscr&#237;bete ahora&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.carrillo.app/subscribe?"><span>Suscr&#237;bete ahora</span></a></p><p><em>Open finance va un poco m&#225;s all&#225;:</em> <strong>extiende el intercambio de datos a seguros, inversiones y pensiones, creando ecosistemas financieros completos centrados en el usuario.</strong> En Latinoam&#233;rica, open finance est&#225; en auge, con Colombia volvi&#233;ndolo obligatorio en 2026 para estandarizar APIs y pagos. <em>A diferencia del open banking (enfocado en pagos y cuentas)</em>, open finance crea productos personalizados, como saldos agregados de m&#250;ltiples bancos en una sola app.</p><p>Todo esto ha dado origen a que en los &#250;ltimos a&#241;os haya surgido una alternativa poderosa: <strong>los pagos A2A (Account-to-Account)</strong>. En <em>lugar de pasar por redes de tarjetas, el dinero se mueve directamente entre cuentas bancarias. </em>Siendo una de las claves de esta tecnol&#243;gia la inicializaci&#243;n de pagos dentro del Open Banking.</p><p>Y es aqu&#237; donde entran sistemas como:</p><ul><li><p><strong>Pix</strong> en Brasil</p></li><li><p><strong>Bre-B</strong> en Colombia</p></li><li><p><strong>UPI</strong> en India</p></li><li><p><strong>SEPA Instant</strong> en Europa</p></li><li><p><strong>FedNow</strong> en USA</p></li></ul><p>Todos comparten una idea central: <em>crear infraestructuras p&#250;blicas de pagos instant&#225;neos interoperables</em>.</p><h2>La Iniciaci&#243;n de Pagos (PIS): Elimina al intermediario</h2><p>Dentro del Open Banking, hay un superpoder espec&#237;fico llamado I<strong>niciaci&#243;n de Pagos (o PIS, por sus siglas en ingl&#233;s: Payment Initiation Services)</strong>. Y esta es posiblemente una de las formas menos explotadas del Open Banking, sobre todo en Colombia, donde todo lo relativo a estas tecnolog&#237;as es muy nuevo. Esto funciona m&#225;s o menos as&#237;:</p><blockquote><p>Hist&#243;ricamente, los pagos en l&#237;nea han sido dominados por las tarjetas de cr&#233;dito y d&#233;bito. El modelo de las tarjetas funciona &#8220;jalando&#8221; el dinero. Cuando compras algo, el comercio le pide a su procesador que &#8220;jale&#8221; el dinero de la red de la tarjeta (Visa, Mastercard...), que a su vez le pide a tu banco que lo apruebe. Hay al menos cuatro intermediarios en esa cadena, y cada uno cobra una comisi&#243;n. Adem&#225;s, este proceso de liquidaci&#243;n puede tardar d&#237;as en completarse a nivel contable.</p></blockquote><p>La <strong>Iniciaci&#243;n de Pagos</strong> cambia las reglas del juego a un modelo de &#8220;empuje&#8221; (Push) de <strong>Cuenta a Cuenta (A2A)</strong>:</p><ol><li><p>La Solicitud: Est&#225;s en el checkout de una tienda o en una pasarela de pagos.</p></li><li><p>La Iniciaci&#243;n: La pasarela de pagos, actuando como un iniciador (PISP), se conecta v&#237;a API directamente con tu banco.</p></li><li><p>La autorizaci&#243;n: Tu banco te pide (quiz&#225;s con tu huella dactilar en tu celular) que apruebes enviar el dinero.</p></li><li><p>La ejecuci&#243;n: El banco &#8220;empuja&#8221; el dinero directamente a la cuenta del vendedor a trav&#233;s de rieles de pago en tiempo real.</p></li></ol><p><strong>&#191;El resultado?</strong> El dinero viaja en segundos de la <strong>Cuenta A a la Cuenta B</strong>, los costos de procesamiento se desploman <em>al eliminar a los intermediarios tradicionales, y el riesgo de fraude disminuye dr&#225;sticamente</em> porque la autenticaci&#243;n se hace directamente en el entorno seguro de tu propio banco. <strong>La infraestructura tecnol&#243;gica necesaria para soportar esto requiere una escalabilidad masiva</strong>, capaz de procesar miles de transacciones concurrentes por segundo sin un solo fallo de base de datos.</p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/p/inicializacion-de-pagos-el-nuevo?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Compartir&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">&#191;Te parece interesante este contenido? No pierdas la oportunidad de compartirlo.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/p/inicializacion-de-pagos-el-nuevo?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Compartir&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.carrillo.app/p/inicializacion-de-pagos-el-nuevo?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Compartir</span></a></p></div><h3>Anatom&#237;a de los pagos inmediatos: Tabla comparativa global</h3><p>Antes de sumergirnos en los servidores y el c&#243;digo, veamos c&#243;mo se posicionan los grandes jugadores del mundo con respecto a infraestructura. Esta tabla resume las diferencias clave entre los sistemas de los que hemos hablado:</p><h3>Comparativa de Sistemas de Pagos Inmediatos (RTP)</h3><ul><li><p><strong>Pix (Brasil)</strong></p><ul><li><p><strong>Arquitectura:</strong> Centralizada bajo el Directorio DICT del Banco Central.</p></li><li><p><strong>Liquidaci&#243;n:</strong> Realizada en menos de 10 segundos.</p></li><li><p><strong>Iniciaci&#243;n:</strong> Multimodal a trav&#233;s de Llaves (alias), c&#243;digos QR y NFC.</p></li><li><p><strong>Interoperabilidad:</strong> Total, garantizada por mandato regulatorio.</p></li><li><p><strong>Costo:</strong> Gratuito para personas naturales.</p></li></ul></li><li><p><strong>Bre-B (Colombia)</strong></p><ul><li><p><strong>Arquitectura:</strong> SPI y Directorio Central orquestado por el Banco de la Rep&#250;blica.</p></li><li><p><strong>Liquidaci&#243;n:</strong> Objetivo de menos de 20 segundos por transacci&#243;n.</p></li><li><p><strong>Iniciaci&#243;n:</strong> Basada en llaves, c&#243;digos QR y URLs de pago.</p></li><li><p><strong>Interoperabilidad:</strong> Total y obligatoria por regulaci&#243;n.</p></li><li><p><strong>Costo:</strong> Bajo costo o gratuito seg&#250;n la normativa vigente.</p></li></ul></li><li><p><strong>FedNow (EE. UU.)</strong></p><ul><li><p><strong>Arquitectura:</strong> Operada directamente por la Red de la Reserva Federal.</p></li><li><p><strong>Liquidaci&#243;n:</strong> Liquidaci&#243;n bruta en tiempo real (segundos).</p></li><li><p><strong>Iniciaci&#243;n:</strong> Integraci&#243;n directa a trav&#233;s de canales bancarios.</p></li><li><p><strong>Interoperabilidad:</strong> Fragmentada, ya que la adopci&#243;n es voluntaria para los bancos.</p></li><li><p><strong>Costo:</strong> Var&#237;a seg&#250;n las pol&#237;ticas de cada entidad bancaria.</p></li></ul></li><li><p><strong>PSD2 / SEPA Inst (Europa)</strong></p><ul><li><p><strong>Arquitectura:</strong> Sistema descentralizado con infraestructura RT1/TIPS.</p></li><li><p><strong>Liquidaci&#243;n:</strong> Confirmaci&#243;n en menos de 10 segundos.</p></li><li><p><strong>Iniciaci&#243;n:</strong> Uso obligatorio de APIs estandarizadas (PISP).</p></li><li><p><strong>Interoperabilidad:</strong> Total bajo mandato de la Uni&#243;n Europea.</p></li><li><p><strong>Costo:</strong> Depende de la estrategia comercial de cada banco.</p></li></ul></li></ul><h2>Pix: el experimento financiero m&#225;s exitoso de Am&#233;rica Latina</h2><p>Si hay un sistema que ha demostrado el potencial de este modelo, es <strong>Pix, desarrollado por el Banco Central de Brasil</strong>. Pix fue lanzado en 2020 y permite realizar transferencias instant&#225;neas las 24 horas del d&#237;a, todos los d&#237;as del a&#241;o.</p><div class="poll-embed" data-attrs="{&quot;id&quot;:508707}" data-component-name="PollToDOM"></div><p><em>Las transacciones se liquidan en cuesti&#243;n de segundos mediante el Sistema de Pagos Instant&#225;neos (SPI) operado por el banco central brasile&#241;o. </em>En el sistema Pix, cada usuario puede registrar una clave Pix, que funciona como un alias de su cuenta bancaria, y puede ser:</p><ul><li><p>N&#250;mero de tel&#233;fono</p></li><li><p>Correo electr&#243;nico</p></li><li><p>N&#250;mero de identificaci&#243;n fiscal</p></li><li><p>Clave aleatoria</p></li><li><p>QR din&#225;mico</p></li></ul><p>Estas claves permiten enviar dinero sin necesidad de conocer el n&#250;mero de cuenta, siendo su flujo t&#237;pico de una transacci&#243;n Pix extremadamente simple:</p><ol><li><p><strong>Usuario A:</strong> abre su app bancaria</p></li><li><p>Introduce la clave Pix del receptor</p></li><li><p>Confirma el monto</p></li><li><p>SPI liquida la operaci&#243;n</p></li><li><p><strong>Usuario B: </strong>recibe el dinero inmediatamente</p></li></ol><p>Las transacciones suelen completarse en menos de 10 segundos, y es por eso que su adopci&#243;n ha sido masiva. <strong>Pix super&#243; al efectivo y a las tarjetas como medio de pago m&#225;s usado en Brasil</strong> y maneja trillones de reales al a&#241;o. Brasil lidera con APIs GraphQL, webhooks y Kubernetes para escalabilidad, integrando PIX en agregadores que muestran saldos de 15 bancos.</p><p>Este &#233;xito tiene varias razones:</p><ul><li><p>Costo cero para usuarios</p></li><li><p>Interoperabilidad obligatoria</p></li><li><p>Infraestructura p&#250;blica</p></li><li><p>Experiencia de usuario extremadamente simple</p></li></ul><h3><strong>&#191;C&#243;mo se inicializan pagos en Pix?</strong></h3><p>Inicializar pagos en Pix sigue un flujo simple, y al usar est&#225;ndares tecnol&#243;gicos como Open Banking y Open Finance, la inicializaci&#243;n de pagos en otros pa&#237;ses que implementan la tecnolog&#237;a deber&#237;a ser, cuando menos, similar:</p><ol><li><p><strong>Autenticaci&#243;n:</strong> Usuario confirma identidad v&#237;a app bancaria (biometr&#237;a o PIN).</p></li><li><p><strong>Consentimiento:</strong> Acepta compartir datos v&#237;a API (ej. PSD2-style en open banking).</p></li><li><p><strong>Procesamiento:</strong> Sistema central valida fondos, liquida en tiempo real.</p></li><li><p><strong>Confirmaci&#243;n:</strong> Notificaci&#243;n push instant&#225;nea.</p></li></ol><p>Para este fin, en <strong>Pix con Open Finance, se utilizan flujos embebidos sin redirects que mejoran la conversi&#243;n m&#243;vil</strong>. T&#233;cnicamente, involucra rate limiting, monitoreo real-time y certificados digitales, pero para usuarios es tan f&#225;cil como escanear un QR. Brasil lidera con APIs GraphQL, webhooks y Kubernetes para escalabilidad, integrando PIX en agregadores que muestran saldos de 15 bancos.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Pix demostr&#243; que los bancos centrales pueden crear plataformas tecnol&#243;gicas tan eficientes como las redes privadas, y ha logrado una alta penetraci&#243;n justamente <em>porque en Brasil, a diferencia de Colombia, no existen impuestos o tasas a las transferencias bancarias, como sucede en Colombia con el famoso 4x1000.</em></p><h2>Bre-B: el equivalente colombiano inspirado en Pix</h2><p>Colombia est&#225; construyendo su propia infraestructura de pagos instant&#225;neos con <strong>Bre-B, desarrollado por el Banco de la Rep&#250;blica y el apoyo de algunas instituciones privadas como Bancolombia, Redeban y otros grandes jugadores</strong>. Bre-B es un sistema interoperable que permite enviar dinero entre entidades financieras en tiempo real, sin importar el banco o billetera digital del usuario.</p><p>La l&#243;gica de funcionamiento es muy similar a Pix, los usuarios registran una llave, que puede ser:</p><ul><li><p>N&#250;mero de celular</p></li><li><p>Documento de identidad <em>(o n&#250;mero de identificaci&#243;n fiscal para empresas)</em></p></li><li><p>Correo electr&#243;nico</p></li><li><p>Identificador alfanum&#233;rico</p></li></ul><p>Una vez registrada la llave, <em>enviar dinero es tan simple como introducirla en la aplicaci&#243;n del banco</em>. El sistema fue dise&#241;ado para resolver uno de los problemas hist&#243;ricos del sistema financiero colombiano: la falta de interoperabilidad entre proveedores. <strong>Pero su adopci&#243;n total se ha visto marcadamente menos pronunciada que en Brasil por cosas como los impuestos a transacciones interbancarias como el 4X100</strong>.</p><h3 style="text-align: center;">Antes de continuar recuerda suscribirte</h3><p style="text-align: center;">Con esta acci&#243;n me ayudas a seguir generando contenido especializado con este que estas mirando ahora con mayor frecuencia y detalle al respecto.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscr&#237;bete ahora&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.carrillo.app/subscribe?"><span>Suscr&#237;bete ahora</span></a></p><p>Sin embargo, antes de Bre-B, muchas soluciones funcionaban en silos, y aunque lleg&#243; a existir una soluci&#243;n de operatividad interbancaria llamada TransfiYa, esta era de origen privado, el consorcio ACH. Que lleg&#243; a materializarse en algunas:</p><ul><li><p><strong>Billeteras digitales:</strong> como Movii, Nequi, Daviplata, Dale! entre otras m&#225;s.</p></li><li><p><strong>Bancos:</strong> siendo los principales Bancolombia y Davivienda, pero integrando un alto porcentaje de usuarios en su conjunto.</p></li></ul><p>Bre-B crea un directorio centralizado de llaves y un mecanismo de liquidaci&#243;n instant&#225;nea, permitiendo que todas las entidades se conecten a una infraestructura com&#250;n.</p><p>Esto significa que una transferencia puede completarse en segundos entre cualquier entidad participante.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!hV7v!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5548b784-6300-41db-b99e-daf84b2ad725_2560x1396.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!hV7v!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5548b784-6300-41db-b99e-daf84b2ad725_2560x1396.jpeg 424w, https://substackcdn.com/image/fetch/$s_!hV7v!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5548b784-6300-41db-b99e-daf84b2ad725_2560x1396.jpeg 848w, https://substackcdn.com/image/fetch/$s_!hV7v!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5548b784-6300-41db-b99e-daf84b2ad725_2560x1396.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!hV7v!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5548b784-6300-41db-b99e-daf84b2ad725_2560x1396.jpeg 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!hV7v!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5548b784-6300-41db-b99e-daf84b2ad725_2560x1396.jpeg" width="1456" height="794" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5548b784-6300-41db-b99e-daf84b2ad725_2560x1396.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:794,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:586830,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://carrilloapps.substack.com/i/196798934?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5548b784-6300-41db-b99e-daf84b2ad725_2560x1396.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!hV7v!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5548b784-6300-41db-b99e-daf84b2ad725_2560x1396.jpeg 424w, https://substackcdn.com/image/fetch/$s_!hV7v!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5548b784-6300-41db-b99e-daf84b2ad725_2560x1396.jpeg 848w, https://substackcdn.com/image/fetch/$s_!hV7v!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5548b784-6300-41db-b99e-daf84b2ad725_2560x1396.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!hV7v!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5548b784-6300-41db-b99e-daf84b2ad725_2560x1396.jpeg 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Diagrama 1 &#8212; Arquitectura en capas del ecosistema Bre-B</figcaption></figure></div><p>Bre-B no es un solo sistema: es una capa de interoperabilidad que act&#250;a como hub central entre los sistemas de pago de bajo valor (SPBV) ya existentes en Colombia. <strong>El Banco de la Rep&#250;blica opera el n&#250;cleo del directorio de llaves y los est&#225;ndares de mensajer&#237;a, mientras las entidades administradoras de sistemas de pago de bajo valor (EASPBV) como Transfiya, Entrecuentas (Redeban),</strong> Visionamos y Credibanco act&#250;an como nodos de conexi&#243;n.</p><h3>Diagrama de flujo de un pago Bre-B: los 9 pasos</h3><p>Desde que el usuario pulsa &#8220;Pagar&#8221; hasta que el destinatario recibe la notificaci&#243;n, ocurren al menos 9 operaciones t&#233;cnicas distintas en menos de 10 segundos. <strong>Este es el flujo completo, diferenciando el caso P2P (persona a persona) del caso PISP (pago desde un tercero)</strong>:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!HTa-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c8914f8-1a8e-4e73-93b1-51e138f068db_2560x1396.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!HTa-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c8914f8-1a8e-4e73-93b1-51e138f068db_2560x1396.png 424w, https://substackcdn.com/image/fetch/$s_!HTa-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c8914f8-1a8e-4e73-93b1-51e138f068db_2560x1396.png 848w, https://substackcdn.com/image/fetch/$s_!HTa-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c8914f8-1a8e-4e73-93b1-51e138f068db_2560x1396.png 1272w, https://substackcdn.com/image/fetch/$s_!HTa-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c8914f8-1a8e-4e73-93b1-51e138f068db_2560x1396.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!HTa-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c8914f8-1a8e-4e73-93b1-51e138f068db_2560x1396.png" width="1456" height="794" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6c8914f8-1a8e-4e73-93b1-51e138f068db_2560x1396.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:794,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:3507142,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://carrilloapps.substack.com/i/196798934?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c8914f8-1a8e-4e73-93b1-51e138f068db_2560x1396.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!HTa-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c8914f8-1a8e-4e73-93b1-51e138f068db_2560x1396.png 424w, https://substackcdn.com/image/fetch/$s_!HTa-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c8914f8-1a8e-4e73-93b1-51e138f068db_2560x1396.png 848w, https://substackcdn.com/image/fetch/$s_!HTa-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c8914f8-1a8e-4e73-93b1-51e138f068db_2560x1396.png 1272w, https://substackcdn.com/image/fetch/$s_!HTa-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c8914f8-1a8e-4e73-93b1-51e138f068db_2560x1396.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Diagrama 2 &#8212; Flujo de mensajer&#237;a de un pago P2P Bre-B</figcaption></figure></div><h3>&#191;C&#243;mo deber&#237;a ser un flujo detallado con PISP (Iniciaci&#243;n por tercero)?</h3><p>Cuando el pago es iniciado por una aplicaci&#243;n de tercero (un e-commerce, una fintech, una app de mensajer&#237;a), se agrega una capa de consentimiento regulada por la Circular 004/2024 de la SFC:</p><ol><li><p><strong>Comercio/App:</strong> El usuario elige &#8220;Pagar con cuenta bancaria&#8221; en el checkout. La app del tercero crea una solicitud de consentimiento con monto, descripci&#243;n y TTL (tiempo de vida).</p><ul><li><p><code>POST /open-finance/v1/payment-consents &#8212; {amount, description, expiresIn}</code></p></li></ul></li><li><p><strong>SFC/Directorio:</strong> El Tercero Receptor de Datos (TRD) est&#225; inscrito en el Directorio de Participantes administrado por la SFC. Se valida su identidad con mTLS + certificado digital emitido por entidad certificadora homologada.</p></li><li><p><strong>App usuario:</strong> El usuario es redirigido (o la app embebe un WebView/SDK) hacia la interfaz de su banco para autenticaci&#243;n fuerte (SCA: biometr&#237;a + factor adicional). La pantalla es 100% del banco, nunca del tercero.</p></li><li><p><strong>Banco pagador:</strong> El banco valida la identidad, debita la cuenta y emite la instrucci&#243;n de pago hacia el nodo EASPBV correspondiente con el mensaje ISO 20022 pacs.008.</p><ul><li><p><code>Authorization Code Flow &#8594; access_token &#8594; POST /payments</code></p></li></ul></li><li><p><strong>Bre-B Core:</strong> El motor de enrutamiento resuelve la llave destino en el DICT-CO, identifica el banco receptor y encamina el mensaje. La liquidaci&#243;n ocurre en el Sistema de Compensaci&#243;n Electr&#243;nica (CEC) del BanRep.</p></li><li><p><strong>Comercio/App:</strong> El banco del pagador emite un webhook al PISP con el estado del pago. El comercio actualiza el estado del pedido en tiempo real. El usuario ve la confirmaci&#243;n sin haber salido del flujo de compra.</p><ul><li><p><code>POST [webhook_url] &#8212; {status: "ACSC", endToEndId, timestamp}</code></p></li></ul></li></ol><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!stAf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35ab17df-7913-41b1-a6c5-4233868a0f6e_2560x1396.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!stAf!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35ab17df-7913-41b1-a6c5-4233868a0f6e_2560x1396.png 424w, https://substackcdn.com/image/fetch/$s_!stAf!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35ab17df-7913-41b1-a6c5-4233868a0f6e_2560x1396.png 848w, https://substackcdn.com/image/fetch/$s_!stAf!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35ab17df-7913-41b1-a6c5-4233868a0f6e_2560x1396.png 1272w, https://substackcdn.com/image/fetch/$s_!stAf!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35ab17df-7913-41b1-a6c5-4233868a0f6e_2560x1396.png 1456w" sizes="auto, 100vw"><img src="https://substackcdn.com/image/fetch/$s_!stAf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35ab17df-7913-41b1-a6c5-4233868a0f6e_2560x1396.png" width="1456" height="794" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/35ab17df-7913-41b1-a6c5-4233868a0f6e_2560x1396.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:794,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:4461660,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://carrilloapps.substack.com/i/196798934?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35ab17df-7913-41b1-a6c5-4233868a0f6e_2560x1396.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!stAf!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35ab17df-7913-41b1-a6c5-4233868a0f6e_2560x1396.png 424w, https://substackcdn.com/image/fetch/$s_!stAf!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35ab17df-7913-41b1-a6c5-4233868a0f6e_2560x1396.png 848w, https://substackcdn.com/image/fetch/$s_!stAf!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35ab17df-7913-41b1-a6c5-4233868a0f6e_2560x1396.png 1272w, https://substackcdn.com/image/fetch/$s_!stAf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35ab17df-7913-41b1-a6c5-4233868a0f6e_2560x1396.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Benchmarking t&#233;cnico: Bre-B vs. el mundo</figcaption></figure></div><h3>Comparaci&#243;n t&#233;cnica profunda: est&#225;ndares y seguridad</h3><p>Esta comparativa demuestra que los modelos de Colombia y Brasil est&#225;n adoptando los est&#225;ndares de seguridad m&#225;s rigurosos (FAPI 2.0/1.0) y la mensajer&#237;a m&#225;s robusta (ISO 20022). Esto posiciona a la regi&#243;n como un referente en modernizaci&#243;n financiera frente a la fragmentaci&#243;n que todav&#237;a enfrenta el ecosistema europeo.</p><h4><strong>Bre-B / Open Finance Colombia</strong></h4><ul><li><p><strong>Protocolo API:</strong> REST/JSON basado en el est&#225;ndar ISO 20022.</p></li><li><p><strong>Autenticaci&#243;n:</strong> OAuth 2.0 con especificaci&#243;n FAPI 2.0.</p></li><li><p><strong>Seguridad:</strong> mTLS obligatorio para todas las conexiones.</p></li><li><p><strong>Firma de Mensajes:</strong> Utiliza JWS (RS256/PS256).</p></li><li><p><strong>Consentimiento:</strong> Expl&#237;cito, trazable y revocable por el usuario.</p></li><li><p><strong>Infraestructura:</strong> Directorio centralizado bajo la SFC (en construcci&#243;n) y Sandbox regulado en desarrollo.</p></li><li><p><strong>Mensajer&#237;a:</strong> Est&#225;ndar ISO 20022.</p></li><li><p><strong>Estado de Pagos:</strong> Recurrentes (PISP) y transfronterizos no disponibles actualmente.</p></li></ul><h4><strong>Pix / Open Finance Brasil</strong></h4><ul><li><p><strong>Protocolo API:</strong> REST/JSON + ISO 20022.</p></li><li><p><strong>Autenticaci&#243;n:</strong> OAuth 2.0 + FAPI 1.0 Advanced.</p></li><li><p><strong>Seguridad:</strong> mTLS obligatorio.</p></li><li><p><strong>Firma de Mensajes:</strong> JWS (PS256).</p></li><li><p><strong>Consentimiento:</strong> Expl&#237;cito, granular y con tiempo de vida (TTL) definido.</p></li><li><p><strong>Infraestructura:</strong> Directorio centralizado (BCB &#8212; DICT) y Sandbox regulado operativo.</p></li><li><p><strong>Mensajer&#237;a:</strong> ISO 20022 (espec&#237;ficamente pacs.008, 002 y 004).</p></li><li><p><strong>Estado de Pagos:</strong> Pix Autom&#225;tico programado para 2025; pagos transfronterizos en fase exploratoria.</p></li></ul><h4><strong>UPI India</strong></h4><ul><li><p><strong>Protocolo API:</strong> REST con una combinaci&#243;n propia de XML/JSON.</p></li><li><p><strong>Autenticaci&#243;n:</strong> Sistema propio (UPI 2.0) con PIN.</p></li><li><p><strong>Seguridad:</strong> TLS 1.2 o superior.</p></li><li><p><strong>Firma de Mensajes:</strong> Firma propiedad de la NPCI.</p></li><li><p><strong>Consentimiento:</strong> Impl&#237;cito mediante el uso del PIN de UPI.</p></li><li><p><strong>Infraestructura:</strong> Directorio centralizado (NPCI) y Sandbox disponible.</p></li><li><p><strong>Mensajer&#237;a:</strong> H&#237;brido entre ISO 8583 y JSON propio.</p></li><li><p><strong>Estado de Pagos:</strong> Soporta UPI AutoPay y pagos transfronterizos activos en m&#225;s de 20 pa&#237;ses.</p></li></ul><h4><strong>Open Banking UK</strong></h4><ul><li><p><strong>Protocolo API:</strong> REST/JSON bajo el est&#225;ndar OBIE.</p></li><li><p><strong>Autenticaci&#243;n:</strong> FAPI 1.0 Advanced.</p></li><li><p><strong>Seguridad:</strong> mTLS m&#225;s certificados eIDAS.</p></li><li><p><strong>Firma de Mensajes:</strong> JWS (PS256).</p></li><li><p><strong>Consentimiento:</strong> Expl&#237;cito con renovaci&#243;n obligatoria cada 90 d&#237;as.</p></li><li><p><strong>Infraestructura:</strong> Directorio centralizado (OBIE Directory) y Sandbox funcional.</p></li><li><p><strong>Mensajer&#237;a:</strong> JSON propio definido por OBIE.</p></li><li><p><strong>Estado de Pagos:</strong> Soporta VRP (Variable Recurring Payments) y transferencias SEPA/SWIFT.</p></li></ul><h4><strong>PSD2 Europa</strong></h4><ul><li><p><strong>Protocolo API:</strong> REST/JSON (altamente fragmentado entre bancos).</p></li><li><p><strong>Autenticaci&#243;n:</strong> OAuth 2.0 (sin requerimiento estricto de FAPI).</p></li><li><p><strong>Seguridad:</strong> TLS 1.2+ (mTLS solo recomendado).</p></li><li><p><strong>Firma de Mensajes:</strong> JWS (opcional seg&#250;n la entidad bancaria).</p></li><li><p><strong>Consentimiento:</strong> Expl&#237;cito con autenticaci&#243;n reforzada (SCA) cada 90 d&#237;as.</p></li><li><p><strong>Infraestructura:</strong> Fragmentada por pa&#237;s; cada banco gestiona su propio Sandbox.</p></li><li><p><strong>Mensajer&#237;a:</strong> M&#250;ltiples est&#225;ndares (STET, Berlin Group o propios).</p></li><li><p><strong>Estado de Pagos:</strong> Recurrentes en dise&#241;o (PSD3) y SEPA Instant para transfronterizos.</p></li></ul><h2>&#191;C&#243;mo deber&#237;a ser conectar tu aplicaci&#243;n o negocio a Bre-B?</h2><p><em>Dependiendo de tu rol en el ecosistema, la ruta de implementaci&#243;n var&#237;a significativamente.</em> Existen tres perfiles principales: Entidad Financiera (banco, billetera), EASPBV (nodo conector) y <strong>Tercero Receptor de Datos / PISP (fintech, comercio, app)</strong>. A continuaci&#243;n, la hoja de ruta para el perfil m&#225;s relevante para nuevos actores: el PISP/TRD.</p><div class="install-substack-app-embed install-substack-app-embed-web" data-component-name="InstallSubstackAppToDOM"><img class="install-substack-app-embed-img" src="https://substackcdn.com/image/fetch/$s_!F3EK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2ce2670-78fa-4235-9710-6b23923068fa_815x815.jpeg"><div class="install-substack-app-embed-text"><div class="install-substack-app-header">Obt&#233;n m&#225;s de Jos&#233; Carrillo en la app de Substack</div><div class="install-substack-app-text">Disponible para iOS y Android</div></div><a href="https://substack.com/app/app-store-redirect?utm_campaign=app-marketing&amp;utm_content=author-post-insert&amp;utm_source=carrilloapps" target="_blank" class="install-substack-app-embed-link"><button class="install-substack-app-embed-btn button primary">Descargar la app</button></a></div><blockquote><p>Estado actual (marzo 2026): La iniciaci&#243;n de pagos por terceros (PISP) en Colombia est&#225; en fase de regulaci&#243;n. La Circular 004/2024 estableci&#243; las bases de Open Finance, pero el decreto que habilitar&#225; el PISP obligatorio (URF, 2025) est&#225; en proceso de implementaci&#243;n con cronograma de 12 meses desde su promulgaci&#243;n formal. Los pasos aqu&#237; descritos mezclan lo que ya est&#225; activo y lo que est&#225; en la hoja de ruta inminente.</p></blockquote><h3>Esto deber&#237;a pasar, paso a paso:</h3><ol><li><p><strong>Definir el modelo de participaci&#243;n:</strong> Determina si actuar&#225;s como Proveedor de Servicios de Iniciaci&#243;n de Pagos (PISP) &#8212;que ordena pagos&#8212; o como Agregador de Informaci&#243;n (AISP) &#8212;que solo lee datos de cuentas. <em>Para Bre-B, el caso de uso es PISP. Si no est&#225;s vigilado por la SFC, necesitar&#225;s operar a trav&#233;s de un Tercero de Confianza (EASPBV certificada: ACH Colombia, Redeban, Credibanco)</em>.</p><ul><li><p>El modelo indirecto (v&#237;a EASPBV) es la ruta pr&#225;ctica para startups y comercios hoy. El modelo directo requiere registro en el Directorio de Participantes de la SFC.</p></li></ul></li><li><p><strong>Revisi&#243;n regulatoria y constituci&#243;n legal:</strong> Si act&#250;as como PISP directo, necesitas inscripci&#243;n formal en el Directorio de Participantes de la SFC. <em>Requisitos previos: personer&#237;a jur&#237;dica constituida en Colombia, pol&#237;ticas documentadas de tratamiento de datos personales (Ley 1581/2012 y Ley 1266/2008)</em>, pol&#237;tica de ciberseguridad alineada con la Circular B&#225;sica Jur&#237;dica de la SFC, y suscripci&#243;n al marco de consentimiento del ecosistema.</p><ul><li><p>Para PISP indirecto (v&#237;a nodo): firma de contrato comercial y t&#233;cnico con el EASPBV elegido (ej. ACH Colombia / Transfiya, Credibanco). Ellos act&#250;an como tu puerta de entrada y validan tu cumplimiento.</p></li></ul></li><li><p><strong>Obtenci&#243;n de certificados digitales homologados: </strong>Todas las comunicaciones entre tu sistema y el ecosistema Open Finance / Bre-B deben ir firmadas y cifradas con certificados emitidos por Entidades de Certificaci&#243;n Digital habilitadas en Colombia:</p><ul><li><p>Camerfirma Colombia &#8212; C&#225;mara de Comercio de Bogot&#225; (token + HSM)</p></li><li><p>GSE (Gesti&#243;n de Seguridad Electr&#243;nica) &#8212; token + servidor HSM</p></li><li><p>Andes SCD &#8212; Certificaci&#243;n digital en token</p></li><li><p>Certic&#225;mara &#8212; Entidad de certificaci&#243;n SIC-homologada</p></li><li><p>Necesitar&#225;s: un certificado de autenticaci&#243;n de cliente (mTLS) para las llamadas a APIs, y un certificado de firma de mensajes (JWS) para firmar los payloads ISO 20022.</p></li></ul></li><li><p><strong>Configuraci&#243;n de la infraestructura t&#233;cnica base:</strong> El stack t&#233;cnico m&#237;nimo para participar en el ecosistema.</p><ul><li><p><em>Seguridad:</em></p><ul><li><p>TLS 1.3 en todos los endpoints expuestos</p></li><li><p>mTLS para llamadas hacia APIs de bancos / EASPBV</p></li><li><p>HSM o equivalente para almacenamiento de claves privadas</p></li><li><p>Rotaci&#243;n de certificados: m&#225;x. 1 a&#241;o (Circular 004)</p></li></ul></li><li><p><em>API Gateway:</em></p><ul><li><p>OAuth 2.0 Authorization Server (ej: Keycloak, Auth0, AWS Cognito)</p></li><li><p>FAPI 2.0 Security Profile (recomendado; FAPI 1.0 Adv. como m&#237;nimo)</p></li><li><p>Rate limiting + circuit breakers</p></li></ul></li><li><p><em>Mensajer&#237;a:</em></p><ul><li><p>ISO 20022 parser/builder (librer&#237;a: isoxml, Prowide, etc.)</p></li><li><p>JWS signing con RS256 o PS256</p></li><li><p>Idempotency keys en todos los POST de pago</p></li></ul></li><li><p><em>Trazabilidad:</em></p><ul><li><p>endToEndId &#250;nico por transacci&#243;n (UUID v4)</p></li><li><p>Logs inmutables (audit trail) &#8212; retenci&#243;n m&#237;n. 5 a&#241;os</p></li><li><p>Webhook receptor con retry exponencial + dead-letter queue</p></li></ul></li></ul></li><li><p><strong>Integraci&#243;n con el nodo EASPBV o con las APIs bancarias:</strong> V&#237;a ACH Colombia / Transfiya: ofrecen un SDK y documentaci&#243;n API REST. El flujo para pago P2P incluye: resoluci&#243;n de llave (<code>GET /alias/{key}</code>), creaci&#243;n de orden de pago (<code>POST /transfers</code>), y consulta de estado (<code>GET /transfers/{id}</code>).</p><ul><li><p><strong>V&#237;a Credibanco:</strong> integraci&#243;n orientada a e-commerce y comercios f&#237;sicos, con soporte QR. Dock (su socio tecnol&#243;gico) provee la plataforma cloud-native que simplifica la integraci&#243;n.</p></li></ul></li><li><p><strong>Implementar el flujo de consentimiento del usuario:</strong> La Gu&#237;a de Experiencia de Usuario publicada por la SFC (disponible en <a href="http://finanzasabiertas.superfinanciera.gov.co">finanzasabiertas.superfinanciera.gov.co</a>) <em>establece lineamientos obligatorios para la pantalla de consentimiento: lenguaje claro, datos m&#237;nimos necesarios, duraci&#243;n del consentimiento visible y mecanismo de revocaci&#243;n accesible</em>. No es opcional: el incumplimiento es sancionable.</p><ol><li><p>El flujo m&#237;nimo de consentimiento para un PISP: (1) Presentar claramente &#8220;qui&#233;n pide el acceso y para qu&#233;&#8221;, (2) El usuario selecciona el banco donde est&#225; su cuenta, (3) Redirecci&#243;n segura al banco para autenticaci&#243;n fuerte (SCA), (4) Retorno a tu app con el token de autorizaci&#243;n, (5) Ejecuci&#243;n del pago, (6) Notificaci&#243;n de resultado.</p></li></ol></li><li><p><strong>Pruebas en sandbox y certificaci&#243;n t&#233;cnica:</strong> Cada EASPBV mantiene su propio ambiente de pruebas. <em>Con respecto a Open Finance, la SFC tiene un sandbox temporal en fase de construcci&#243;n.</em> Los casos de prueba obligatorios incluyen: <strong>pago exitoso, pago rechazado por fondos insuficientes, llave no encontrada, timeout del banco, intento de pago duplicado (idempotency), y revocaci&#243;n de consentimiento en tr&#225;nsito</strong>.</p><ol><li><p>Adicionalmente, <strong>la Circular 009/2025 estableci&#243; que las entidades deben completar sus ajustes de arquitectura, seguridad y tecnolog&#237;a</strong>. Para TRDs nuevos, el EASPBV, que act&#250;a como Tercero de Confianza, realiza una validaci&#243;n t&#233;cnica de onboarding antes de habilitar el acceso a producci&#243;n.</p></li></ol></li><li><p><strong>Go-live y monitoreo continuo:</strong> En producci&#243;n, el monitoreo es parte del cumplimiento regulatorio. <em>Debes tener: alertas en tiempo real para transacciones fallidas, tasas de &#233;xito por banco (&gt;95% es el benchmark del sector), latencia P95 por endpoint, y un proceso documentado de gesti&#243;n de incidentes con notificaci&#243;n a la SFC en eventos mayores.</em> <strong>Los logs deben conservarse por un m&#237;nimo de 5 a&#241;os.<br></strong></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Suscribirse&quot;,&quot;language&quot;:&quot;es&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">S&#233; parte de los que apoyan con su suscripci&#243;n m&#225;s contenido especializado como este.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Escribe tu correo electr&#243;nico..." tabindex="-1"><input type="submit" class="button primary" value="Suscribirse"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div></li></ol><h2>Certificaciones necesarias para operar dentro de Bre-b</h2><p>Operar en el ecosistema de Open Finance y Bre-B en Colombia requiere el cumplimiento que combina registros regulatorios, certificaciones t&#233;cnicas internacionales y adherencia a normas de seguridad de la informaci&#243;n. Las certificaciones necesarias son:</p><ol><li><p><strong>Registro Directorio de Participantes SFC: </strong>Emitido por la Superintendencia Financiera de Colombia, la inscripci&#243;n obligatoria para operar como TRD (Tercero Receptor de Datos) o PISP en el ecosistema. La SFC administra el directorio y define los requisitos. Aplica el marco del Decreto 1297/2022 y la Circular 004/2024.</p></li><li><p><strong>Registro RNNP / SIC:</strong> Emitido por la Superintendencia de Industria y Comercio, el Registro Nacional de Bases de Datos ante la SIC. Obligatorio para cualquier entidad que trate datos personales de colombianos. Base legal: Ley 1581/2012 y Decreto 1074/2015. Incluye pol&#237;tica de privacidad, aviso de privacidad y contratos de encargo de tratamiento.</p></li><li><p><strong>Certificado Digital mTLS + Firma JWS:</strong> Emitido por Camerfirma (GSE, Certic&#225;mara o Andes SCD) el Certificado X.509 es emitido por entidad de certificaci&#243;n digital homologada en Colombia. Requerido para autenticaci&#243;n mutua en las APIs del ecosistema. Vigencia m&#225;xima: 1 a&#241;o. Requiere HSM para las claves privadas en entornos de producci&#243;n.</p></li><li><p><strong>Habilitaci&#243;n EASPBV </strong><em><strong>(si aplica)</strong></em><strong>:</strong> Emitido por el Banco de la Rep&#250;blica para entidades que quieran operar como nodo conector del sistema (EASPBV). Requiere autorizaci&#243;n del BanRep, capital m&#237;nimo demostrado, infraestructura t&#233;cnica certificada y plan de continuidad de negocio en un proceso de 6&#8211;12 meses.</p></li><li><p><strong>Vigilancia SFC (entidades reguladas):</strong> Emitido por la Superintendencia Financiera para bancos, billeteras electr&#243;nicas (SEDPE), compa&#241;&#237;as de financiamiento y fintechs con captaci&#243;n. Requiere autorizaci&#243;n de funcionamiento, relaciones de solvencia, y cumplimiento de la Circular B&#225;sica Contable y Financiera. No aplica a todos los participantes.</p></li></ol><p>Esto sin incluir las certificaciones t&#233;cnicas internacionales (fuertemente recomendadas), como:</p><ol><li><p><strong>ISO/IEC 27001:2022:</strong> Sistema de Gesti&#243;n de Seguridad de la Informaci&#243;n. La Circular 004/2024 exige controles alineados con esta norma. No es obligatoria la certificaci&#243;n formal, pero s&#237; la implementaci&#243;n de sus controles. Para TRDs directos, la certificaci&#243;n es virtualmente requisito de facto para el onboarding con bancos.</p></li><li><p><strong>PCI DSS v4.0:</strong> Si tu plataforma tambi&#233;n procesa tarjetas o almacena datos de tarjeta (CHD), PCI DSS es obligatorio. Para iniciaci&#243;n de pagos Bre-B puro, no aplica directamente, pero la mayor&#237;a de los integradores de pagos lo tienen como est&#225;ndar de referencia para la evaluaci&#243;n de riesgo.</p></li><li><p><strong>FAPI 2.0 Conformance (OpenID):</strong> Financial-grade API Security Profile. Es el est&#225;ndar de seguridad de OAuth 2.0 para APIs financieras que exige la SFC. La certificaci&#243;n formal de conformidad con OpenID Foundation demuestra que tu servidor de autorizaci&#243;n cumple el perfil FAPI 2.0, lo que simplifica la negociaci&#243;n t&#233;cnica con bancos.</p></li><li><p><strong>SOC 2 Type II:</strong> Auditor&#237;a de controles de seguridad, disponibilidad, integridad de procesamiento y confidencialidad. Muy solicitado por bancos colombianos en sus procesos de due diligence para fintechs que quieren integrar sus APIs. No es regulatorio, pero es el est&#225;ndar de facto del sector.</p></li><li><p><strong>ISO 22301 &#8212; Continuidad de negocio:</strong> La SFC exige planes documentados de continuidad de operaciones para entidades del ecosistema de pagos. La norma ISO 22301 es el marco de referencia. Para EASPBV, el BanRep exige disponibilidad m&#237;nima documentada del 99.9%.</p></li></ol><p><em>Teniendo en cuenta todo lo anterior, crear una infraestructura de este nivel es construir una autopista digital.</em> Es complejo, requiere certificaciones rigurosas y una arquitectura de nube tolerante a fallos. Sin embargo, el esfuerzo t&#233;cnico se justifica por el resultado: <strong>tomar un sistema financiero hist&#243;ricamente lento y fragmentado y convertirlo en una herramienta &#225;gil</strong> que empodera la econom&#237;a de toda una regi&#243;n, conectando cuentas corporativas extranjeras con el talento local en cuesti&#243;n de segundos.</p><p>Este tipo de implementaciones es viable y ser&#237;a sumamente productivo, sobre todo para pasarelas de pago que ya operan en el pa&#237;s, y cuentan con gran parte de los requisitos t&#233;cnicos y legales para comenzar a ejecutar este tipo de servicios a usuarios finales naturales o jur&#237;dicos. S&#233; que este tema puede ser extenso y sobre todo te agradezco leer hasta aqu&#237;; la invitaci&#243;n es a dejar tu comentario y compartir.</p><div class="poll-embed" data-attrs="{&quot;id&quot;:508711}" data-component-name="PollToDOM"></div><h2>Referencias documentales de este art&#237;culo</h2><p>Este cronograma refleja el paso de un modelo de adopci&#243;n voluntaria (iniciado en 2022) hacia un esquema de <strong>obligatoriedad</strong> que alcanzar&#225; su madurez entre 2025 y 2026. Para los equipos t&#233;cnicos, el reto inmediato es el cumplimiento de la Circular 009 de 2025, que establece las bases de seguridad necesarias para la interoperabilidad total que propone Bre-B.</p><h4><strong>Ministerio de Hacienda y Cr&#233;dito P&#250;blico (MinHacienda / URF)</strong></h4><ul><li><p><strong><a href="https://www.suin-juriscol.gov.co/viewDocument.asp?id=30044535">Decreto 1297 de 2022</a>:</strong> Reglamentaci&#243;n de la arquitectura de finanzas abiertas (Open Finance) e interoperabilidad en el sistema financiero.</p></li><li><p><strong><a href="https://www.urf.gov.co/">Unidad de Proyecci&#243;n Normativa y Estudios de Regulaci&#243;n Financiera (URF)</a>:</strong> Proyectos normativos para la transici&#243;n hacia la obligatoriedad del ecosistema Open Finance (H1 2026).</p></li></ul><p><strong>Superintendencia Financiera de Colombia (SFC)</strong></p><ul><li><p><strong><a href="https://www.google.com/search?q=https://www.superfinanciera.gov.co/jsp/101115">Circular Externa 004 de 2024</a>:</strong> Est&#225;ndares t&#233;cnicos, tecnol&#243;gicos y de seguridad para la implementaci&#243;n de APIs.</p></li><li><p><strong><a href="https://www.google.com/search?q=https://www.superfinanciera.gov.co/jsp/101115">Circular Externa 009 de 2025</a>:</strong> Instrucciones sobre el cumplimiento de arquitectura de seguridad y est&#225;ndares t&#233;cnicos m&#237;nimos.</p></li><li><p><strong><a href="https://www.google.com/search?q=https://www.superfinanciera.gov.co/jsp/101103">Normativa de Open Finance</a>:</strong> Compendio de instrucciones para entidades vigiladas sobre la adopci&#243;n de finanzas abiertas.</p></li></ul><p><strong>Banco de la Rep&#250;blica (BanRep)</strong></p><ul><li><p><strong><a href="https://www.google.com/search?q=https://www.banrep.gov.co/es/reglamentacion-temas/3642">Circular Reglamentaria Externa DSP-465</a>:</strong> Operaci&#243;n del Sistema de Pagos Inmediatos (SPI) y registro de llaves en Bre-B.</p></li><li><p><strong><a href="https://www.banrep.gov.co/es/sistemas-pago">Sistemas de Pago - Bre-B</a>:</strong> Informaci&#243;n general sobre la infraestructura de pagos de bajo valor y el go-live transaccional.</p></li><li><p><strong><a href="https://www.google.com/search?q=https://www.banrep.gov.co/es/eventos-sistemas-pago">Foros de Sistemas de Pago</a>:</strong> Documentaci&#243;n t&#233;cnica y presentaciones sobre la hoja de ruta de interoperabilidad y QR.</p></li></ul>]]></content:encoded></item><item><title><![CDATA[¿Por qué la inteligencia artificial va a dejar sin trabajo a muchos programadores?]]></title><description><![CDATA[La inteligencia artificial es, a d&#237;a de hoy, una herramienta sumamente potente que permite extender las capacidades de cualquier profesional. Y eso en s&#237; mismo no es algo malo.]]></description><link>https://blog.carrillo.app/p/por-que-la-inteligencia-artificial</link><guid isPermaLink="false">https://blog.carrillo.app/p/por-que-la-inteligencia-artificial</guid><dc:creator><![CDATA[José Carrillo]]></dc:creator><pubDate>Thu, 07 May 2026 14:53:33 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!9mcH!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71eba4ec-efda-42df-b48b-a16553596949_2560x1396.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9mcH!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71eba4ec-efda-42df-b48b-a16553596949_2560x1396.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9mcH!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71eba4ec-efda-42df-b48b-a16553596949_2560x1396.jpeg 424w, https://substackcdn.com/image/fetch/$s_!9mcH!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71eba4ec-efda-42df-b48b-a16553596949_2560x1396.jpeg 848w, https://substackcdn.com/image/fetch/$s_!9mcH!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71eba4ec-efda-42df-b48b-a16553596949_2560x1396.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!9mcH!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71eba4ec-efda-42df-b48b-a16553596949_2560x1396.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9mcH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71eba4ec-efda-42df-b48b-a16553596949_2560x1396.jpeg" width="1456" height="794" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/71eba4ec-efda-42df-b48b-a16553596949_2560x1396.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:794,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:508462,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://carrilloapps.substack.com/i/196787179?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71eba4ec-efda-42df-b48b-a16553596949_2560x1396.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!9mcH!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71eba4ec-efda-42df-b48b-a16553596949_2560x1396.jpeg 424w, https://substackcdn.com/image/fetch/$s_!9mcH!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71eba4ec-efda-42df-b48b-a16553596949_2560x1396.jpeg 848w, https://substackcdn.com/image/fetch/$s_!9mcH!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71eba4ec-efda-42df-b48b-a16553596949_2560x1396.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!9mcH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71eba4ec-efda-42df-b48b-a16553596949_2560x1396.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>La <em>inteligencia artificial</em> no es una tecnolog&#237;a nueva; de hecho, surgi&#243; en 1956 desde el <strong>Dartmouth Summer Research Project on Artificial Intelligence</strong>, realizado en <strong>Dartmouth College, </strong>una universidad privada de artes liberales e investigaci&#243;n ubicada en Hanover, Nuevo Hampshire, Estados Unidos.</p><p>La idea, en principio, y en t&#233;rminos f&#225;ciles de entender, era que <em>&#8220;cada aspecto del aprendizaje o cualquier otra caracter&#237;stica de la inteligencia puede describirse con tal precisi&#243;n que una m&#225;quina puede ser construida para simularlo&#8221;.</em></p><h3>En la actualidad</h3><p>El <strong>resurgimiento moderno de la IA</strong> se asocia principalmente a un paper de 2017 de <strong>Google </strong>titulado<strong> Attention Is All You Need. </strong>Ese paper introdujo la arquitectura <strong>Transformer</strong>, que cambi&#243; completamente c&#243;mo se entrenan los modelos de lenguaje.</p><p>Todo lo dem&#225;s inici&#243; en 2018 con BART <em>(padre del actual Gemini)</em> y luego en 2019 con la salida de GPT-2, hasta el 2022 cuando OpenAI lanza ChatGPT. La primera <em>inteligencia artificial</em> realmente completa y funcional, con la que se pod&#237;a conversar mediante lenguaje natural en un chat.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Suscr&#237;bete y recibe contenido especial todos los d&#237;as, ap&#243;yame y se parte de mi comunidad.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h3>&#191;Por qu&#233; la inteligencia artificial es tan importante?</h3><p>Sucede que desde 2022 la <em>inteligencia artificial</em> no ha dejado de crecer, evolucionar y aumentar su capacidad. <em>Eso no es un secreto oculto para nadie</em>, tanto, que se han escuchado casos donde incluso se ha usado para consulta por profesionales altamente calificados como jueces e incluso m&#233;dicos.</p><p>Eso en s&#237; mismo no es algo malo. <strong>La inteligencia artificial es, a d&#237;a de hoy, una herramienta sumamente potente</strong> que permite extender las capacidades de cualquier profesional.</p><p>Eso hace que, para muchos oficios, la inteligencia artificial se convierta en un punto cr&#237;tico de aprendizaje. <em>Empleos como los de traductores a d&#237;a de hoy no se ven tan necesarios,</em> sobre todo porque hasta las inteligencias artificiales m&#225;s b&#225;sicas son capaces de hacer traducciones altamente exactas y adecuadas de muchos idiomas.</p><p>Estas traducciones, por poner un ejemplo, van desde el mismo idioma pero con diferente acento o dialecto, hasta idiomas altamente completos como el japon&#233;s y el mandar&#237;n, o idiomas m&#225;s universales como el ingl&#233;s, de forma simple y directa.</p><h3>&#191;Y por qu&#233; son los programadores los que se van a quedar sin empleo?</h3><p>As&#237; como el ejemplo anterior de los traductores (que es un ejemplo muy frecuente en este tipo de debates), otros oficios son vistos como <em>&#8220;prontos a desaparecer&#8221;</em>, pero &#191;es esto posible?</p><p>Bueno, <strong>desde mi punto de vista, NO</strong>. No creo que esto pase. P<em>ero es naturaleza humana buscar posibles puntos de destrucci&#243;n y alertarse, por ello</em>. Y no est&#225; mal, pero tampoco es bueno dejarse llevar por el descontrol masivo sin tener un contexto adecuado.</p><p>Cuando se habla de trabajos altamente especializados, estos no van a desaparecer, es pr&#225;cticamente imposible y te doy un ejemplo:</p><p>En muchos pa&#237;ses del mundo, de primer, segundo y tercer mundo. Existe el <strong>&#8220;Originalism&#8221;</strong> o <strong>&#8220;interpretaci&#243;n aut&#233;ntica&#8221;. Donde, si una ley es (principalmente) antigua o desconocida, se puede consultar con el propio legislador; puede aclarar su significado</strong>, porque fue quien la cre&#243;.</p><p>En estos casos, siempre se necesita interpretaci&#243;n directa de un humano. <em>Por lo que la inteligencia artificial se vuelve una herramienta muy potente para entender contextos generales</em>; sin embargo, espec&#237;ficamente, en casos como este, se necesita (seg&#250;n sea el caso) un traductor o int&#233;rprete.</p><h4>Entonces, &#191;por qu&#233; surge este mito?</h4><p>Puede ser por la alta capacidad de las inteligencias artificiales en generar c&#243;digo; <strong>son capaces de hacerlo, pero en teor&#237;a un chimpanc&#233; tambi&#233;n podr&#237;a escribir la Biblia</strong> seg&#250;n el <a href="https://es.wikipedia.org/wiki/Teorema_del_mono_infinito">teorema del mono infinito</a>.</p><p>Aqu&#237; la pregunta es: <strong>&#191;realmente estamos en ese punto donde la inteligencia artificial nos puede reemplazar?, y la respuesta pr&#225;ctica es NO</strong>. Mi observaci&#243;n al respecto es que, <em>en el momento en que la inteligencia artificial sea capaz de hacer eso, el mundo colapsar&#225; sobre s&#237; mismo</em>.</p><blockquote><p>En un mundo donde todos los trabajos los puede hacer una inteligencia artificial sin intervenci&#243;n humana y con alta eficiencia, &#191;qu&#233; sentido tiene la humanidad si todo lo puede hacer una inteligencia artificial?</p></blockquote><p>Pues, quien no se adapta est&#225; condenado a la extinci&#243;n; no lo digo yo, <a href="https://es.wikipedia.org/wiki/Origen_del_hombre#:~:text=Teor%C3%ADa%20de%20la%20evoluci%C3%B3n%20por%20selecci%C3%B3n%20natural,la%20selecci%C3%B3n%20natural%20y%20la%20selecci%C3%B3n%20sexual.">lo dijo Darwin</a>. Y hoy m&#225;s que nunca tiene un gran sentido.</p><h4>Pero, &#191;qu&#233; podemos hacer?</h4><p>Como te dije, adaptarnos. <em>La inteligencia artificial es una herramienta excepcional, altamente capaz (aunque su eficiencia no es &#243;ptima),</em> que nos permite ir m&#225;s all&#225;, con mayor capacidad.</p><p>Mira que los ciclos se repiten; <em>con la invenci&#243;n de la computadora se cre&#237;a que no era necesario ya un matem&#225;tico o f&#237;sico</em>. Lo que antes era algo altamente reservado como el estudio de estas ciencias puras y su especializaci&#243;n, a d&#237;a de hoy es considerado un requerimiento obligatorio y universal desde ni&#241;os en la escuela.</p><p>Como programador y profesional altamente calificado, mi recomendaci&#243;n es: <strong>&#161;Ad&#225;ptate! Si dejas pasar la oportunidad de hacerlo, estar&#225;s condenado a perder tu trabajo</strong>, pero no por la inteligencia artificial, sino por alguien que s&#237; es capaz de usarla de forma eficiente.</p><blockquote><p>Cuanto m&#225;s especializado est&#233;s en un &#225;rea en particular, entender&#225;s que la inteligencia artificial sabe menos de lo que creemos.</p></blockquote><h3>&#191;Cu&#225;ntos empleos se van a perder por la inteligencia artificial en el sector tecnol&#243;gico?</h3><p>Muchos, realmente, se van a perder muchos empleos; eso no es algo que est&#233; en discusi&#243;n. Pero lo que tambi&#233;n pasar&#225; es que se generar&#225;n muchos m&#225;s, incluso m&#225;s de los que se van a perder.</p><p>Yo particularmente, <em>conozco personas que han perdido su trabajo como dise&#241;adores y desarrolladores de sitios web en WordPress</em> por el hipe que tiene la inteligencia artificial. <strong>Pero en su totalidad, esos mismos amigos ahora hacen flujos completos, altamente complejos en N8N</strong> usando inteligencia artificial para todo tipo de cosas.</p><p>Incluso, ahora ganan m&#225;s que antes y tienen ingresos de forma estable y constante, y claramente son m&#225;s que antes. Pero ellos se adaptaron; solo conozco a una persona que no lo hizo y realmente cambi&#243; de carrera. Sin embargo, bueno, no lo juzgo, realmente no le gustaba programar; ahora est&#225; haciendo lo que le gusta como Trader, e incluso &#233;l usa un bot de inteligencia artificial.</p><p>Ya para finalizar, solo te puedo decir: <em>Comienza hoy mismo a aprender a usar la inteligencia artificial a tu favor, porque si no, alguien la usar&#225; en tu contra. </em>Muchas gracias por tu atenci&#243;n, espero que este post sea de tu agrado y no dudes en dejar tu comentario y compartir.</p><h2>Ap&#243;yame para seguir generando contenido</h2><p>Suscr&#237;bete y recibe contenido nuevo de forma prioritaria, p&#250;blico contenido nuevo con mucha frecuencia y suscribiendote me permites llegar a m&#225;s personas.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.carrillo.app/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.carrillo.app/subscribe?"><span>Subscribe now</span></a></p><p></p>]]></content:encoded></item></channel></rss>