# 📊¿Qué es el teorema CAP?

Este teorema dice que un sistema distribuido solo puedes garantizar simultáneamente dos de estas tres propiedades:

* **Consistency** (consistencia)
    
* **Availability** (disponibilidad)
    
* **Partition tolerance** (tolerancia a particiones)
    

### ¿Pero qué significan estas propiedades?

#### Consistencia

Todos los nodos/usuarios del sistema ven los mismos datos al mismo tiempo. Cuando una escritura se realiza en un nodo, todas las lecturas siguientes van a devolver el valor actualizado.

#### Disponibilidad

Cada petición realizada a un nodo disponible recibe una respuesta. Sin tener la garantía de que contenga la versión más actualizada de los datos.

#### Tolerancia a particiones

El sistema puede seguir en funcionamiento aunque parte de la red esté caída o parte de los mensajes se pierdan.

<div data-node-type="callout">
<div data-node-type="callout-emoji">⚠</div>
<div data-node-type="callout-text">Nótese que la definición de consistencia en el contexto de CAP es diferente a la de consistencia en bases de datos ACID. Un poco confuso todo, la verdad.</div>
</div>

### ¿Dónde está la trampa?

Pues que, a no ser que estemos trabajando con una arquitectura monolito, seguramente estemos ante un sistema distribuido y, por lo tanto, la tolerancia a particiones es obligatoria. Por lo tanto, ya hemos elegido una de las dos propiedades que podemos tener.

Así que la pregunta clave termina siendo:

## Cuando ocurre una partición en la red, ¿queremos priorizar la disponibilidad o la consistencia?

Imaginémonos el siguiente caso por un momento: nuestro sistema es una aplicación web que se utiliza en todo el mundo y tenemos una base de datos con todos los usuarios de nuestra aplicación en el mundo y, desplegadas, hay una instancia en Estados Unidos y otra en Europa. Dichas bases de datos son una réplica la una de la otra y están sincronizadas.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1753996497703/a0f455d9-6df4-476b-a93b-b6278a19f1a6.png align="center")

Pues ahora va John y quiere actualizar su perfil, por ejemplo, cambiar la biografía que aparece. Justo después de esto, va Paco y quiere leer la información que tiene John en su perfil. Ocurriría algo así:

1. John se conecta al servidor de Estados Unidos y actualiza su biografía.
    
2. La base de datos de Europa se sincroniza con la de EEUU y se trae los cambios.
    
3. Cuando Paco ve el perfil de John, ve su biografía actualizada.
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1753996912342/23d0c597-5ded-42af-8790-0a00a2ecb474.png align="center")

Todo funciona de maravilla hasta que nos encontramos con una partición en la red. La conexión entre el clúster de Estadios Unidos y el de Europa se rompe.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1753997458893/d28f6ce0-659d-4061-a778-194d78e2d633.png align="center")

Ahora bien, si consideramos el ejemplo anterior de nuevo, pero con esta partición de red, ¿qué deberíamos hacer?

* Opción A: devolver un error porque no podemos garantizar que nuestros datos estén actualizados (elegimos consistencia)
    
* Opción B: devolver datos que podrían estar desactualizados (elegimos disponibilidad)
    

Pues esta es la clave del teorema de CAP, la respuesta a esta pregunta definirá si esta parte de tu sistema prioriza la consistencia o la disponibilidad.

En este caso está claro, devolveríamos la biografía del usuario John, aunque no podamos asegurar que sea la versión más actualizada.

## ¿Cuándo elijo consistencia y cuando disponibilidad?

La realidad es que en la mayoría de sistemas van a tolerar algo de inconsistencia y deberían priorizar la disponibilidad. En estos casos lo que se llama [eventual consistency](https://en.wikipedia.org/wiki/Eventual_consistency) es suficiente. Esto quiere decir que el sistema llegará eventualmente en algún punto a ser consistente, pero puede tardar segundos o incluso minutos.

#### Elegiremos consistencia en sistemas como:

* **Un sistema que tenga reserva de tickets (Ticketmaster, Skyscanner):** imagínate que hemos comprado tickets para un vuelo, pero a la hora de comprarlos hubo una partición de red y otra persona también los vio disponibles y compró los mismos tickets. Al aeropuerto llegarán dos personas con el mismo ticket.
    
* **Inventario de una tienda e-commerce:** si en una tienda como Amazon aparece que queda una sola Nintendo Switch 2 y la compras cuando hay una partición de red, quizás más de un usuario ha comprado la última unidad y alguien se queda sin ella.
    
* **Sistemas de finanzas:** los sistemas relacionados con stocks tienen que enseñar los últimos datos actualizados o si no, podrían haber problemas relacionados con los precios a los que se compraron o vendieron acciones.
    

#### Elegiremos disponibilidad en sistemas como:

* **Redes sociales (Instagram):** si un usuario actualiza su biografía, no pasa nada si otro usuario tarda un poquito más en verla actualizada.
    
* **Plataformas de contenido (Netflix o Youtube):** si alguien actualiza el nombre de una película en otro idioma, no pasa nada porque el título antiguo aparezca un poco más de tiempo.
    
* **Páginas de reseñas (Google Maps):** si un restaurante actualiza su horario, es mejor enseñar el horario antiguo que no enseñar nada.
    

Así que, de nuevo, ya para terminar, la pregunta que uno se tiene que preguntar es:

## ¿Sería un desastre si los usuarios viesen datos inconsistentes durante un rato?

Si la respuesta es sí, elige consistencia. Si es no, elige disponibilidad.

### Fuentes:

* [https://www.hellointerview.com/learn/system-design/deep-dives/cap-theorem](https://www.hellointerview.com/learn/system-design/deep-dives/cap-theorem).
    
* [Kleppmann, M. (2017). Designing Data-Intensive Applications. O’Reilly Media.](https://www.goodreads.com/book/show/23463279-designing-data-intensive-applications)
    
* [Ejsmont, A. (2015). *Web Scalability for Startup Engineers*. Apress.](https://www.goodreads.com/book/show/23615147-web-scalability-for-startup-engineers)
