
Qué es ClickHouse: características e instalación paso a paso (guía 2026)
Publicado el:
Tiempo de lectura: 16 min
Tema: Tecnologia
Autor: Leandro Valencia
Guía práctica de ClickHouse para makers: qué es, por qué es tan rápido, sus características clave y cómo instalarlo en 5 minutos con curl o Docker.
Tabla de Contenidos
- Mi opinión: cuándo ClickHouse es la decisión correcta y cuándo no
- Errores que vas a cometer (yo los cometí)
- Conclusión
Qué es ClickHouse (sin marketing)
ClickHouse es una base de datos analítica columnar de código abierto, escrita en C++, diseñada para ejecutar consultas de agregación sobre volúmenes grandes de datos a velocidades que parecen un error de medición.
La palabra clave es analítica. En jerga de bases de datos, esto significa OLAP (Online Analytical Processing), en oposición a OLTP (Online Transaction Processing), que es lo que hacen PostgreSQL o MySQL.
La diferencia importa más de lo que parece:
OLTP (Postgres, MySQL, SQLite) está optimizado para leer y escribir filas individuales muy rápido. "Dame el usuario 4821". "Actualiza el estado de este pedido". Miles de operaciones pequeñas por segundo, con transacciones y consistencia fuerte.
OLAP (ClickHouse, DuckDB, BigQuery) está optimizado para leer muchas filas pero pocas columnas. "Dame la suma de ingresos por país en los últimos 90 días". No le importa una fila concreta; le importa barrer millones de filas y reducirlas a un número.
Si quieres el contexto completo de esta categoría —historia, casos de uso y el mapa de proveedores— lo desarrollo en qué son las bases de datos OLAP.
La clave técnica que lo permite es el almacenamiento columnar. Una base de datos por filas guarda los datos así en disco:
[id:1, país:ES, ingresos:42, timestamp:...][id:2, país:MX, ingresos:17, timestamp:...]
Si quieres sumar la columna ingresos, tienes que leer todo, incluyendo el país y el timestamp que no te importan. ClickHouse guarda cada columna en su propio archivo:
ingresos: [42, 17, 88, 12, ...]
país: [ES, MX, ES, AR, ...]
Para sumar ingresos solo lees ese archivo. Si tu tabla tiene 40 columnas y tu consulta usa 2, estás leyendo el 5% de los datos. Ahí empieza la magia, y todo lo demás la amplifica.
Por qué es tan rápido: los cuatro motivos reales
1. Compresión brutal. Cuando guardas valores del mismo tipo juntos y además ordenados, los patrones se repiten y los algoritmos de compresión se vuelven muy eficientes. La documentación de ClickHouse muestra ratios de compresión que van de 2x en texto libre hasta más de 1.000x en columnas de baja cardinalidad bien ordenadas. Menos bytes en disco = menos I/O = consultas más rápidas.
2. Índice primario disperso. ClickHouse no crea un índice B-tree con una entrada por fila. Crea un índice disperso: una entrada cada 8.192 filas (un "gránulo"). Esto significa unos pocos megabytes de índice por terabyte de datos, que caben en RAM sin despeinarse. La contrapartida es que ClickHouse nunca busca una fila exacta, sino el bloque donde está. Para analítica es exactamente el trade-off correcto.
3. Motor vectorizado y paralelo. Las operaciones se ejecutan sobre bloques de columnas usando instrucciones SIMD, no fila a fila. Y se paralelizan agresivamente sobre todos los cores disponibles. En un portátil de 8 cores ya notas la diferencia; en un servidor de 64 es otra liga.
4. Separación de lecturas y escrituras. Los inserts crean "parts" nuevos que se fusionan en segundo plano (arquitectura tipo LSM). Insertar no bloquea consultas, y consultar no bloquea inserts.
Características principales que deberías conocer
Estas son las que de verdad cambian cómo diseñas tu proyecto, no la lista completa del datasheet.
Un solo binario, cero dependencias
Esto suena a detalle menor y es probablemente lo más importante para un proyecto pequeño. ClickHouse se distribuye como un único ejecutable que contiene servidor, cliente y modo local. No hay JVM, no hay ZooKeeper obligatorio, no hay orquestador. Descargas un archivo, lo ejecutas, tienes una base de datos analítica.
Compáralo con levantar Apache Druid, que necesita seis tipos de proceso distintos. Para un maker trabajando solo, esta diferencia es la que decide si el proyecto sale adelante o muere en el docker-compose.yml.
clickhouse-local: SQL sobre archivos sin servidor
Puedes consultar CSV, Parquet o JSON directamente desde disco o desde una URL, sin importar nada ni levantar servidor:
./clickhouse local --query "
SELECT country, count() AS visitas
FROM file('logs.csv', CSVWithNames)
GROUP BY country
ORDER BY visitas DESC
LIMIT 10
"
Esto sustituye scripts de pandas para exploración rápida y va notablemente más rápido en archivos grandes.
Vistas materializadas incrementales
Esta es la característica que más me ha cambiado la forma de construir. Una vista materializada en ClickHouse no es una caché que se refresca: es un trigger de inserción. Cada vez que insertas en la tabla origen, se calcula la agregación sobre ese bloque y se escribe en la tabla destino.
El resultado es que mueves el coste del momento de la consulta al momento de la inserción. Tu dashboard consulta una tabla de 4.000 filas pre-agregadas en lugar de 400 millones de filas crudas. Lo cubro en profundidad en la guía avanzada, pero quédate con la idea.
Soporte SQL completo con JOINs de verdad
Durante años la crítica estándar a ClickHouse era "los JOINs son malos". Eso ya no se sostiene. Soporta todos los tipos de JOIN estándar, tiene un optimizador que reordena joins usando estadísticas de columnas, y añade tipos que no existen en SQL estándar como ASOF JOIN (unir por el valor temporal más cercano, no exacto), que es oro puro para series temporales y datos financieros.
Además extiende SQL con cientos de funciones analíticas: uniqExact, quantileTDigest, windowFunnel, sequenceMatch. Cosas que en Postgres serían una CTE de 60 líneas aquí son una función.
Compatibilidad con 70+ formatos y data lakes
Lee y escribe Parquet, Iceberg, Delta Lake, Avro, Protobuf, JSON en todas sus variantes. Puede consultar directamente ficheros en S3 sin ingerirlos. Esto significa que no te encierra: si mañana quieres migrar, tus datos salen en Parquet con una sentencia.
JSON sin explosión de esquema
Puedes ingerir datos semi-estructurados con un tipo JSON nativo que internamente los almacena de forma columnar. Ingiere eventos con formas variables sin diseñar el esquema perfecto por adelantado, y sigues teniendo rendimiento de base de datos columnar.
Mi opinión: cuándo ClickHouse es la decisión correcta y cuándo no
Aquí es donde la mayoría de los tutoriales te fallan, porque están escritos por gente que quiere venderte algo.
ClickHouse es una gran idea si:
Tienes una tabla de eventos que crece sin parar —analítica de producto, logs, métricas, clicks, telemetría de IoT— y tus consultas son agregaciones sobre rangos temporales. Este es el caso canónico y donde va a parecer magia.
Estás construyendo analítica de cara al usuario: un dashboard dentro de tu producto que muchos clientes consultan simultáneamente. ClickHouse maneja concurrencia alta con latencias de milisegundos, que es justo donde los warehouses tipo Snowflake se vuelven caros.
Tu factura de BigQuery o Snowflake te da ansiedad. Un servidor dedicado de 30-60 € al mes con ClickHouse aguanta cargas que en un warehouse por consumo cuestan un orden de magnitud más. Para un proyecto bootstrapped esto no es una optimización, es la diferencia entre viable e inviable.
ClickHouse es mala idea si:
Necesitas actualizaciones y borrados frecuentes por fila. ClickHouse ha mejorado muchísimo aquí (mutaciones ligeras, ReplacingMergeTree, deletes ligeros), pero sigue siendo un motor pensado para escribir una vez y leer muchas. Si tu carga de trabajo es un CRUD, usa Postgres.
Necesitas transacciones ACID multi-tabla. El soporte transaccional es limitado y no es el objetivo del proyecto. No pongas aquí el estado de tus pedidos.
Tienes menos de unos pocos millones de filas. Con 500.000 filas Postgres con un índice decente ya te da respuestas en milisegundos. Añadir ClickHouse es complejidad operativa sin beneficio. La respuesta correcta para un dataset pequeño es no cambiar de base de datos.
Tu equipo son cero personas y ya tienes tres servicios que mantener. Es un servicio más que monitorizar, respaldar y actualizar. Merece la pena cuando el dolor de rendimiento es real, no cuando es anticipado.
Mi regla práctica: si un GROUP BY sobre tu tabla más grande tarda más de 5 segundos en Postgres y esa consulta es central para tu producto, es momento de mirar ClickHouse. Antes de eso, no.
Un matiz adicional: el patrón que mejor me ha funcionado no es reemplazar Postgres, sino ponerlos juntos. Postgres sigue siendo la fuente de verdad transaccional —usuarios, pedidos, configuración— y ClickHouse recibe una copia de la tabla de eventos vía CDC o un job de replicación. Cada uno hace lo que sabe hacer.
Instalación de ClickHouse paso a paso
Vamos a lo práctico. Tres caminos según lo que necesites.
Opción 1: instalación rápida con curl (macOS, Linux, FreeBSD)
La forma más directa. Descarga el binario adecuado para tu sistema:
curl https://clickhouse.com/ | sh
En Linux y macOS esto instala además clickhousectl (con alias chctl) en ~/.local/bin, la CLI oficial para gestionar varias versiones locales, arrancar servidores en segundo plano y conectar con ClickHouse Cloud.
Si solo quieres el binario sin la CLI de gestión:
curl https://clickhouse.com/ | CLICKHOUSE_ONLY=1 sh
Nota para usuarios de macOS: si Gatekeeper se queja de que no puede verificar al desarrollador del binario, ve a Ajustes del Sistema → Privacidad y Seguridad y autoriza la ejecución. Es el comportamiento normal de macOS con binarios sin firmar.
Arranca el servidor:
./clickhouse server
Y en otra terminal, el cliente:
./clickhouse client
Deberías ver algo así:
ClickHouse client version 24.5.1.117 (official build).
Connecting to localhost:9000 as user default.
Connected to ClickHouse server version 24.5.1.
local-host :)
Los datos se guardan en el directorio actual y sobreviven a reinicios del servidor.
Opción 2: Docker (recomendado si ya usas contenedores)
Mi opción por defecto cuando el proyecto ya tiene un docker-compose.yml, porque evita ensuciar el sistema y hace el entorno reproducible.
docker run -d \
--name clickhouse \
-p 8123:8123 \
-p 9000:9000 \
-v clickhouse_data:/var/lib/clickhouse \
--ulimit nofile=262144:262144 \
clickhouse/clickhouse-server
Los dos puertos importan y confunden a todo el mundo al principio:
- 8123 es la interfaz HTTP. La usan la mayoría de clientes web, herramientas de BI y
curl. - 9000 es el protocolo nativo TCP. Más rápido y compacto; lo usa
clickhouse-clienty los drivers nativos.
El flag --ulimit nofile no es opcional en la práctica: ClickHouse abre muchos descriptores de archivo y sin subir el límite verás errores raros bajo carga.
Como docker-compose.yml:
services:
clickhouse:
image: clickhouse/clickhouse-server
container_name: clickhouse
ports:
- "8123:8123"
- "9000:9000"
volumes:
- clickhouse_data:/var/lib/clickhouse
- ./config.d:/etc/clickhouse-server/config.d
ulimits:
nofile:
soft: 262144
hard: 262144
environment:
CLICKHOUSE_USER: creacosas
CLICKHOUSE_PASSWORD: cambia_esto
CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT: 1
volumes:
clickhouse_data:
Conéctate al cliente dentro del contenedor:
docker exec -it clickhouse clickhouse-client --user creacosas --password cambia_esto
Opción 3: sin instalar nada
Si solo quieres probar la sintaxis y ver la velocidad, el playground oficial tiene datasets reales cargados y ejecuta consultas desde el navegador. Cero fricción.
Tus primeras consultas: de cero a datos reales
Vamos a crear algo parecido a un caso real: una tabla de eventos de una web.
Crear la base de datos y la tabla
CREATE DATABASE creacosas;
USE creacosas;
CREATE TABLE eventos
(
fecha Date,
timestamp DateTime,
usuario_id UInt32,
evento LowCardinality(String),
pais LowCardinality(String),
url String,
duracion_ms UInt32
)
ENGINE = MergeTree
PARTITION BY toYYYYMM(fecha)
ORDER BY (evento, fecha, usuario_id);
Hay tres decisiones aquí que merecen explicación porque son las decisiones de ClickHouse:
ENGINE = MergeTree es el motor de tabla por defecto y el que vas a usar el 90% del tiempo. Toda la familia MergeTree (ReplacingMergeTree, SummingMergeTree, AggregatingMergeTree) comparte la misma base con comportamientos añadidos en la fusión de partes.
ORDER BY es la decisión más importante de todo tu esquema. Define el orden físico de los datos en disco y, por defecto, también la clave primaria. La regla: pon primero las columnas por las que filtras más y que tienen menor cardinalidad. Aquí filtramos casi siempre por tipo de evento y por fecha, así que van delante. Equivocarte aquí es la causa número uno de "ClickHouse me va lento".
LowCardinality(String) es un tipo que aplica codificación por diccionario. Si una columna tiene menos de ~10.000 valores distintos (países, tipos de evento, nombres de plan), envolverla en LowCardinality reduce el almacenamiento y acelera los filtros de forma notable. Es una victoria gratis que casi nadie usa al principio.
Insertar datos de prueba
Generemos 10 millones de filas sintéticas para tener algo con lo que jugar:
INSERT INTO eventos
SELECT
toDate('2026-01-01') + (number % 220) AS fecha,
toDateTime(fecha) + (number % 86400) AS timestamp,
(number % 50000) + 1 AS usuario_id,
['pageview','click','signup','purchase'][(intHash32(number) % 4) + 1] AS evento,
['ES','MX','AR','CO','CL','US'][(intHash32(number + 7) % 6) + 1] AS pais,
concat('/pagina/', toString(number % 500)) AS url,
(number % 5000) + 100 AS duracion_ms
FROM numbers(10000000);
La función numbers() genera filas sobre la marcha: es la forma estándar de crear datasets de prueba en ClickHouse sin descargar nada. Uso intHash32() en vez de number % N directamente para las columnas categóricas, porque si dos columnas usan módulos con factores comunes (4 y 6, por ejemplo) acaban correlacionadas y los resultados salen artificialmente uniformes.
Consultar
SELECT
pais,
evento,
count() AS total,
round(avg(duracion_ms)) AS duracion_media,
uniqExact(usuario_id) AS usuarios_unicos
FROM eventos
WHERE fecha >= '2026-03-01'
AND evento = 'purchase'
GROUP BY pais, evento
ORDER BY total DESC;
Fíjate en la última línea de la salida del cliente. Te dice cuántas filas ha procesado, cuántos bytes ha leído y a qué velocidad:
6 rows in set. Elapsed: 0.021 sec. Processed 1.14 million rows, 8.32 MB (54.28 million rows/s., 396.19 MB/s.)
Ese número —"processed 1.14 million rows" de un total de 10 millones— es lo importante. ClickHouse solo leyó el 11% de la tabla porque el ORDER BY (evento, fecha, ...) le permitió saltarse todo lo demás. Optimizar ClickHouse consiste casi siempre en reducir ese número.
Un truco: ver el tamaño real en disco
SELECT
table,
formatReadableSize(sum(data_compressed_bytes)) AS comprimido,
formatReadableSize(sum(data_uncompressed_bytes)) AS sin_comprimir,
round(sum(data_uncompressed_bytes) / sum(data_compressed_bytes), 2) AS ratio
FROM system.columns
WHERE database = 'creacosas'
GROUP BY table;
Las tablas del sistema (system.columns, system.parts, system.query_log) son una de las mejores cosas de ClickHouse: toda la introspección del motor es SQL consultable.
Errores que vas a cometer (yo los cometí)
Insertar fila a fila. ClickHouse detesta los inserts pequeños. Cada INSERT crea un "part" nuevo en disco que luego hay que fusionar. Mil inserts de una fila generan mil parts y el servidor se ahoga con el error Too many parts. Inserta en lotes de al menos 1.000 filas —idealmente entre 10.000 y 100.000— o activa inserts asíncronos con async_insert=1.
Usar Nullable por costumbre. Cada columna Nullable añade una columna extra de máscara y desactiva algunas optimizaciones. Si puedes usar un valor centinela (0, cadena vacía, 1970-01-01), hazlo.
Poner una columna de alta cardinalidad primera en el ORDER BY. Si pones usuario_id o un UUID al principio, destruyes la compresión y la capacidad de saltar bloques. Baja cardinalidad primero, siempre.
Esperar que UPDATE funcione como en Postgres. Funciona, pero es una operación pesada. Si tu diseño depende de actualizar filas constantemente, replantea el diseño (o replantea la base de datos).
Conclusión
ClickHouse no es una base de datos de propósito general y ese es justo su valor: hace una cosa —agregar sobre volúmenes grandes— mejor que casi nadie, y lo hace con una huella operativa ridículamente pequeña para lo que ofrece. Un binario, sin dependencias, corriendo desde un portátil hasta cientos de nodos con el mismo motor.
Para un maker trabajando solo, ese último punto es el que decide. No necesitas un equipo de datos para operar ClickHouse en un VPS. Necesitas entender bien tu ORDER BY y no insertar fila a fila.
Si vienes de Postgres y tus dashboards agonizan, dedica una tarde a esto. La curva de aprendizaje inicial es de horas, no de semanas, y el salto de rendimiento es de los que se notan sin necesidad de medirlos.
En los siguientes posts de esta serie profundizamos en las dos preguntas que vienen después de instalarlo:
- Alternativas a ClickHouse: comparativa completa — DuckDB, StarRocks, Druid, Pinot, TimescaleDB y los warehouses cloud, con tabla comparativa y veredicto por caso de uso.
- Guía avanzada de ClickHouse — vistas materializadas, projections, codecs de compresión, TTL, tiering a S3 y diagnóstico de consultas lentas.
Preguntas frecuentes
¿ClickHouse es gratis?
El motor es open source con licencia Apache 2.0 y puedes autoalojarlo sin coste ni límites de funcionalidad. ClickHouse Cloud es el servicio gestionado de pago, con un modelo basado en consumo de cómputo y almacenamiento por separado y escalado a cero cuando no hay actividad.
¿ClickHouse puede sustituir a PostgreSQL?
No en el caso general. Son herramientas para trabajos distintos: Postgres para transacciones y estado de aplicación, ClickHouse para analítica. El patrón habitual es usar ambos, con Postgres como fuente de verdad y ClickHouse recibiendo los datos de eventos.
¿Cuántos datos necesito para que merezca la pena?
Como referencia práctica, a partir de decenas de millones de filas en tu tabla de eventos la diferencia es evidente. Por debajo de unos pocos millones, Postgres bien indexado es suficiente y más simple de operar.
¿Funciona en Windows?
Sí, mediante Docker o WSL2, que es el camino recomendado. Existe también instalación vía clickhousectl.
¿Qué motor de tabla debo usar?
MergeTree para el 90% de los casos. ReplacingMergeTree si necesitas deduplicar por clave, SummingMergeTree o AggregatingMergeTree como destino de vistas materializadas de agregación.
Posts Relacionados
Continúa explorando contenido similar que te puede interesar

Guía avanzada de ClickHouse: optimización, vistas materializadas y trucos reales
Cómo sacar el máximo a ClickHouse: ORDER BY, vistas materializadas, projections, codecs, TTL, tiering a S3 y diagnóstico de consultas lentas. Con SQL real.

Bases de datos OLAP: qué son, casos de uso reales y proveedores principales
Qué es una base de datos OLAP, en qué se diferencia de OLTP, casos de uso prácticos con SQL real y los principales proveedores en 2026.

Alternativas a ClickHouse en 2026: comparativa honesta con tabla
DuckDB, StarRocks, Druid, Pinot, TimescaleDB, BigQuery y más. Comparativa real de alternativas a ClickHouse con tabla y recomendación por caso de uso.