SenseiTeoría desde cero0/32

5 · Datos y almacenamientoLección 3 de 5

Object storage, data lakes y warehouses

Object storage, data lakes and warehouses

Dónde viven las fotos, los datasets, los pesos y los logs de un sistema de ML, cuánto cuesta guardarlos un año y cómo los encuentra después un analista o un job de entrenamiento.

⏱ 58 min lo esencial · 73 min todo16 conceptos nuevos2 calculadoras9 ejerciciosDatos
Secciones14
  1. 01Object storage: objetos, llaves y buckets
  2. 02Bloques y archivos: los otros dos almacenes extra
  3. 03La URL prefirmada: un permiso de un rato, dentro de la dirección
  4. 04Durabilidad y clases de almacenamiento
  5. 05Ciclo de vida, retención y lo que cuesta
  6. 06Data lake y particiones por fecha
  7. 07Warehouse, lakehouse y snapshots
  8. 08Feature store y backfill extra
  9. 09Errores comunes
  10. 10En la vida real extra
  11. 11Ejercicios
  12. 12Lo que sigue
  13. 13Palabras que vas a oír
  14. 14Chequeo
La pregunta

C01 guarda millones de fotos, el dataset para reentrenar, los pesos del modelo y un log de cada predicción. ¿Dónde va cada cosa, cuánto cuesta guardarla un año y cómo la encuentra después quien la necesita?

Cada día, C01 recibe ≈ 10 millones de fotos, de ≈ 200 KB cada una: 10 M × 200 KB = 2 TB al día. Cada mes se reentrena con un dataset nuevo. Cada versión del modelo deja un archivo de pesos de ≈ 98 MB. Y cada predicción deja una línea de log (log: el registro de lo que pasó, como qué foto llegó, qué categoría salió y a qué hora) de ≈ 300 bytes: 10 M × 300 B = 3 GB al día.

Son cuatro cosas muy distintas. Unas son enormes y se leen poco; otras son chiquitas y se escriben millones de veces. Unas tienen que durar años; otras conviene borrarlas a los 90 días, porque traen datos de personas.

En la lección de formatos viste cómo se escribe cada archivo por dentro (json lines, parquet). En la de bases de datos, cómo se guardan filas que cambian. Aquí vas a ver dónde se guardan los archivos cuando son millones, quién puede entrar, qué pasa si se rompe un disco, cuánto cuesta y cómo se organizan para que un analista o un job de entrenamiento (un programa que arranca, hace su tarea y termina) lea un día sin tener que leer el año.

01

Object storage: objetos, llaves y buckets

Esencial

Object storage: objects, keys and buckets

El disco de tu computadora guarda archivos en carpetas, con un sistema de archivos. Funciona muy bien para una máquina. Para 3,650 millones de fotos al año, que leen cientos de máquinas a la vez, se usa otra cosa: un object storage (almacenamiento de objetos).

Los más conocidos son de la nube, las computadoras que se rentan por hora o por GB: S3 (Simple Storage Service) de AWS, la nube de Amazon; Cloud Storage (GCS) de Google, y Blob Storage de Microsoft Azure. También hay versiones que una empresa instala en sus propias máquinas, como MinIO o Ceph.

Un objeto: bytes, llave y metadatos

Un objeto tiene tres partes:

  • Los bytes: el contenido, sea un JPEG, un Parquet o un archivo de pesos. A S3 le da igual qué son.
  • La llave (key): el nombre con el que lo guardas y lo pides, como fotos/2026/11/06/ana-tenis.jpg.
  • Los metadatos (metadata): datos sobre el objeto, como su tamaño, su tipo (image/jpeg), la fecha en que se guardó y una huella de su contenido.

No hay que instalar nada para usarlo: se le habla por HTTP, con los métodos que ya conoces. PUT guarda un objeto, GET lo lee, DELETE lo borra y HEAD lee solo sus metadatos. Además hay LIST, que lista llaves. Cada una de esas operaciones es una request, y se cobra aparte de los GB guardados.

Se reemplaza entero

Un objeto no se edita a la mitad. Para cambiar un byte de una foto, la bajas completa, la cambias y la vuelves a subir: un PUT a la misma llave reemplaza al objeto viejo entero. Tampoco se le agregan líneas al final, como a un log en tu disco. Sí se puede leer solo un pedazo, con el header Range de un GET («dame del byte 1,000 al 5,000»): así un lector de Parquet lee solo las columnas que necesita.

¿Por qué tan limitado? Porque esa sencillez es lo que lo deja crecer sin tope. Si nadie edita a la mitad, no hay que coordinar a dos máquinas que escriben el mismo archivo. Cada objeto es independiente, y S3 puede repartir billones de ellos entre miles de discos. A cambio, tú organizas tus datos en objetos que se escriben una vez y se leen muchas.

Si dos programas hacen PUT a la misma llave casi al mismo tiempo, no se mezclan: gana el último, entero, y el otro se pierde sin aviso. Si no quieres que nadie pise una llave, desde agosto de 2024 S3 acepta escrituras condicionales: con el header If-None-Match: * («solo si no hay nada con esa llave»), el PUT falla con el código 412 si la llave ya existe. Y un GET justo después de un PUT ya ve el objeto nuevo: S3 lo garantiza desde diciembre de 2020. Antes, al reemplazar un objeto, un GET podía devolver el viejo durante un rato, la consistencia eventual de la lección de bases de datos.

Para ir más hondoObjetos grandes: la subida en partes

Un solo PUT sube hasta 5 GB. Para algo más grande, como un checkpoint de un LLM (los pesos guardados a mitad del entrenamiento), se usa la subida en partes (multipart upload): el archivo se corta en pedazos, por ejemplo de 100 MB, que suben en paralelo y se reintentan uno por uno si falla la red. Al final, una request le dice a S3 «junta las partes», y el objeto aparece completo de golpe. Antes de eso, nadie lo ve a medias. Se aceptan hasta 10,000 partes, y así un objeto llega a 50 TB (desde diciembre de 2025; antes, el tope era 5 TB).

El bucket

Los objetos viven dentro de un bucket. Ojo: en la lección de percentiles, un bucket era el intervalo de un histograma. Aquí es otra cosa, y en el glosario se llama bucket de objetos: el contenedor donde guardas objetos.

En S3, cada bucket tiene, por omisión, un nombre único en el mundo: si alguien ya usó ml-datos, tú no puedes (desde marzo de 2026 también se puede crear con un sufijo que lleva tu número de cuenta y la región, y ese nombre es solo tuyo). El bucket vive en una región, un grupo de centros de datos en un lugar, como el norte de Virginia, y lleva sus reglas: quién puede leer y escribir (su bucket policy), cuánto dura cada cosa y si guarda versiones viejas.

La dirección completa de un objeto junta las dos cosas: en s3://ml-datos/logs/dt=2026-11-06/part-0001.parquet, el bucket es ml-datos y la llave es todo lo que sigue.

Las carpetas no existen

La llave es solo un texto, de hasta 1,024 bytes, y puede llevar «/». La consola de S3 te enseña «carpetas», pero dentro hay una lista plana de llaves, ordenada. Lo que parece una carpeta es un prefijo (prefix): el principio que varias llaves comparten.

Las carpetas de un bucket no existen. Arriba, lo que enseña la consola: una carpeta logs, cerrada, y una carpeta fotos, dentro 2026, dentro 11, y dentro dos carpetas, 06 con ana-tenis.jpg y beto-bici.jpg, y 07 con caro-lampara.jpg. Abajo, lo que de verdad hay: una lista plana de cuatro llaves en orden alfabético, fotos/2026/11/06/ana-tenis.jpg, fotos/2026/11/06/beto-bici.jpg, fotos/2026/11/07/caro-lampara.jpg y logs/dt=2026-11-06/part-0000.parquet. Las dos primeras comparten el prefijo fotos/2026/11/06/, que está resaltado. Un LIST con ese prefijo devuelve esas dos llaves. La diagonal es una letra más de la llave. LO QUE ENSEÑA LA CONSOLA fotos/ 2026/ 11/ 06/ ana-tenis.jpg beto-bici.jpg 07/ caro-lampara.jpg Parecen carpetas, pero nadie las creó: la consola las dibuja cortando en cada «/». logs/ (otra «carpeta», cerrada) LO QUE HAY: LLAVES EN ORDEN fotos/2026/11/06/ana-tenis.jpg fotos/2026/11/06/beto-bici.jpg fotos/2026/11/07/caro-lampara.jpg logs/dt=2026-11-06/part-0000.parquet LIST «fotos/2026/11/06/» → 2 llaves La «/» es una letra más de la llave.
Arriba, lo que enseña la consola: carpetas. Abajo, lo que de verdad hay: una lista plana de llaves ordenadas. Pedir «la carpeta del día 6» es un LIST con el prefijo fotos/2026/11/06/.

Esto tiene consecuencias. Listar con un prefijo es rápido, porque las llaves están ordenadas, y S3 te las da de 1,000 en 1,000. Pero «renombrar una carpeta» no existe: hay que copiar cada objeto a su llave nueva y borrar el viejo. Con un millón de objetos son dos millones de requests.

Para ir más hondoCuántas requests aguanta un prefijo

El prefijo también reparte la carga. Según AWS, S3 aguanta al menos 3,500 escrituras y 5,500 lecturas por segundo por prefijo, y escala de a poco: mientras crece, puede responder 503 (Slow Down, «más despacio»), y el cliente reintenta. Los 500 GET por segundo del pico de C01 quedan lejos de ese techo.

El juguete de abajo es un object storage hecho con un diccionario de Python: las llaves son texto y no hay carpetas. Fíjate en cuántas requests cuesta cambiar un byte y mover dos fotos.

python
from collections import Counter
objetos, requests = {}, Counter()        # un object storage de juguete: llave → bytes

def put(llave, datos):
    requests["PUT"] += 1
    objetos[llave] = bytes(datos)        # si la llave ya existía, lo reemplaza entero
def get(llave):
    requests["GET"] += 1
    return objetos[llave]
def listar(prefijo):
    requests["LIST"] += 1
    return sorted(k for k in objetos if k.startswith(prefijo))

for llave, kb in (("fotos/2026/11/06/ana-tenis.jpg", 200), ("fotos/2026/11/06/beto-bici.jpg", 150),
                  ("fotos/2026/11/07/caro-lampara.jpg", 180)):
    put(llave, b"\xff" * kb * 1000)
print(listar("fotos/2026/11/06/"))

foto = bytearray(get("fotos/2026/11/06/ana-tenis.jpg"))   # para cambiar un byte...
foto[10] = 0
put("fotos/2026/11/06/ana-tenis.jpg", foto)                # ...se sube entera otra vez

for k in listar("fotos/2026/11/06/"):                       # «renombrar la carpeta» del día 6
    put(k.replace("/06/", "/06-revisadas/"), get(k))
    del objetos[k]; requests["DELETE"] += 1
print(listar("fotos/"))
print(dict(requests))
Salida
['fotos/2026/11/06/ana-tenis.jpg', 'fotos/2026/11/06/beto-bici.jpg']
['fotos/2026/11/06-revisadas/ana-tenis.jpg', 'fotos/2026/11/06-revisadas/beto-bici.jpg', 'fotos/2026/11/07/caro-lampara.jpg']
{'PUT': 6, 'LIST': 3, 'GET': 3, 'DELETE': 2}

Seis PUT para tres fotos guardadas: una para cambiar un byte y dos para «mover» dos fotos. En S3 de verdad, la copia se hace sin bajar los bytes (una request COPY), pero se cobra igual que un PUT.

02

Bloques y archivos: los otros dos almacenes

Extra

Block and file storage: the other two

El object storage no es la única manera de guardar en la nube. Hay otras dos, y cada una se parece a algo que ya conoces.

Almacenamiento de bloques: un disco de red

Un disco, por dentro, es una fila larguísima de bloques numerados, pedazos de tamaño fijo. El sistema operativo pone encima su sistema de archivos y decide qué bloques forman cada archivo. Eso es el almacenamiento de bloques (block storage): te dan un disco en crudo, y tu máquina lo usa como suyo.

En AWS se llama EBS (Elastic Block Store). En la lección de memoria lo viste: es un disco que vive en otra parte del centro de datos, se conecta por la red y sobrevive si la máquina se apaga. El más común, gp3, da de base 3,000 operaciones por segundo (IOPS) y 125 MiB/s.

Lo bueno: puedes cambiar un byte a la mitad de un archivo, como en tu laptop, con latencias de milisegundos o menos. Por eso ahí van el disco con el que arranca la máquina y las bases de datos. Lo malo: normalmente lo usa una sola máquina a la vez, vive en una sola zona de disponibilidad (un centro de datos dentro de la región) y pagas los GB que reservas, los uses o no. Si reservas 500 GB y usas 50, pagas 500.

Algunas máquinas traen además un SSD conectado directo a ellas (instance store; casi siempre NVMe, la conexión más rápida para un SSD), todavía más rápido que EBS porque no pasa por la red. Pero es de esa máquina: si se apaga o se reemplaza, lo que tenía se pierde. Sirve como caché, para los pesos que se bajaron de S3, nunca como único lugar de algo.

Almacenamiento de archivos: una carpeta compartida

El tercero es una carpeta compartida por la red, que muchas máquinas montan a la vez y ven como un disco suyo. Habla NFS, un protocolo de los años ochenta para compartir archivos. En AWS se llama EFS (Elastic File System); en Google, Filestore. Tiene carpetas de verdad, renombrar es instantáneo y se puede editar a la mitad. Cuesta bastante más por GB.

Bloques (EBS)Archivos (EFS)Objetos (S3)
Cómo se veUn discoUna carpeta compartidaLlaves y objetos, por HTTP
Quién lo usa a la vezUna máquinaMuchasCualquiera con permiso
Editar a la mitadSíSíNo: se reemplaza entero
Latencia típicaMenos de 1 ms a pocos ms≈ 1 ms al leer, ≈ 3 ms al escribir≈ 100 a 200 ms por request, según AWS
Precio aproximado (us-east-1, 2026)≈ US$0.08 por GB-mes reservado (gp3)≈ US$0.30 por GB-mes (Standard)≈ US$0.023 por GB-mes (Standard)
En C01El disco de cada nodo—Fotos, logs, datasets y pesos

Con 100 GB al mes: ≈ US$8 en EBS, ≈ US$30 en EFS y ≈ US$2.30 en S3. Por eso la regla de la Ronda (M13) es sencilla: lo que vive con una máquina va en su disco; lo que se comparte o tiene que durar va al object storage. C07, la búsqueda por foto, guarda sus vectores (embeddings) en un disco gp3 porque los lee el page cache de una sola máquina; C10, el chat con un LLM, baja sus pesos de S3 al disco local de cada máquina nueva.

03

La URL prefirmada: un permiso de un rato, dentro de la dirección

Esencial

Presigned URLs: a short-lived permission inside the address

Ana toca «publicar», y la foto de 200 KB tiene que quedar guardada en un bucket del marketplace, para mostrarla en la publicación. La Ronda no dice cómo la sube la app: lo que sigue es el diseño más común, como supuesto, porque explica bien la idea. Hay dos caminos malos.

  • Que pase por tu API. La foto cruza tu balanceador de carga y tus servidores solo para que ellos la vuelvan a subir a S3. A 500 fotos por segundo, eso son ≈ 100 MB/s de bytes que no necesitabas mover.
  • Darle a la app las credenciales de S3, la clave secreta que da permiso de entrar al bucket. Cualquiera que abra la app podría sacarlas y leer o borrar todo el bucket. Nunca.

El camino bueno es una URL prefirmada (presigned URL; en Google se llama signed URL, URL firmada).

Quién firma, qué permite y cuánto dura

Tu servidor sí tiene permiso de escribir en el bucket. Con su clave secreta calcula una firma: un número que solo se puede producir con esa clave, y que depende de exactamente qué se permite (la cuenta se llama HMAC, y la verás en la lección de cifrado). Mete la firma en la dirección, en la query (la parte de la URL después del ?, en pares nombre=valor), y se la da a la app. Firmar es una cuenta local: el servidor no tiene que llamar a AWS.

La URL de una subida trae, entre otras, estas partes:

  • El bucket y la llave: c01-subidas.s3.amazonaws.com y /fotos/8f3a.jpg.
  • X-Amz-Credential: quién firmó, sin su secreto. Puede ser un usuario o un rol (una identidad de AWS con sus permisos, que usa un programa en vez de una persona).
  • X-Amz-Date y X-Amz-Expires=900: cuándo se firmó y cuántos segundos vale.
  • X-Amz-Signature: la firma.

Cuando llega el PUT, S3 recalcula la firma. Si alguien cambió la llave, el método o la hora, no coincide y responde 403. Si coincide, revisa que no haya vencido y que quien firmó todavía tenga permiso de hacer eso. Como el permiso viaja en la URL, esa request no lleva header Authorization.

Lo que permite una URL prefirmada es una operación (un PUT o un GET) sobre una llave, durante un rato que elige quien firma: en este ejemplo, 15 minutos, igual que en C02 (las cámaras de los centros de distribución). En S3, como mucho 7 días, y menos si se firmó con credenciales temporales (las que caducan solas, como las de un rol), porque vence cuando ellas vencen.

Para ir más hondoLo que una firma puede amarrar, y lo que no

Quien firma puede amarrar más cosas. En C02, la firma también cubre el tipo del archivo (Content-Type: video/mp4): si la «caja», la computadora del sitio conectada a las cámaras, manda otro, S3 lo rechaza. Lo que una URL de PUT no limita es un tamaño máximo (solo se puede firmar uno exacto); para eso hay otra variante, un formulario firmado (POST con una policy) que sí pone un máximo de bytes.

La foto de Ana sube directo al bucket, con un permiso prestado · La foto de Ana va directo de su app al bucket, con un permiso de 15 minutos que firmó la API. Después, C01 recibe solo la llave y lee la foto con su propio permiso. Esa última parte es una variante que M13 propone para ahorrar: en el diseño base de C01, el gateway recibe los bytes de la foto, como viste en la lección de HTTP. Usa «Recorrer» para seguir la subida y la clasificación.
  • App de Ana · la foto de 200 KB
    La app tiene la foto, pero no tiene credenciales del bucket: si las tuviera, cualquiera podría sacarlas de la app y leer o borrar todo. Lo único que recibe es una URL prefirmada para una sola llave.
  • API del marketplace · firma la URL
    Revisa que Ana inició sesión, inventa una llave nueva y firma con la clave secreta de su rol una URL de PUT que vale 15 minutos. Firmar es una cuenta local: no llama a S3. La API nunca ve los bytes de la foto.
  • Base de datos · la publicación y su llave
    La publicación de Ana guarda el texto de la llave (fotos/8f3a.jpg), no la foto. Es una fila chiquita en una base de datos.
  • Bucket de fotos · privado · S3
    Un bucket privado del producto. Recibe el PUT, recalcula la firma, revisa que no haya vencido y guarda el objeto con durabilidad de once nueves. Una regla de ciclo de vida lo mueve de clase cuando envejece.
  • Gateway de C01 · variante: la llave
    En la variante que propone M13 para ahorrar, la request a C01 lleva la llave, no los bytes (en el diseño base, el gateway recibe la foto). El gateway lee la foto del bucket con el permiso de su propio rol, que solo deja leer el prefijo de fotos: un GET por foto, ≈ 304 millones al mes.
  • Log en el lake · la llave, no la foto
    El log de cada predicción anota la llave de la foto, la categoría y la confianza: ≈ 300 bytes. La foto ya vive en el bucket del producto; copiarla «por si acaso» serían ≈ 60 TB más cada mes.

Sirve igual para bajar. En la Ronda, M02 lo usa en los trabajos largos: el resultado (un JSON enorme, una máscara, un PDF) se guarda en el bucket, y el cliente lo baja con una URL prefirmada de GET que vence en minutos.

04

Durabilidad y clases de almacenamiento

Esencial

Durability and storage classes

Guardaste la foto de Ana. ¿Qué tan seguro es que siga ahí dentro de un año?

Once nueves

La durabilidad (durability) es la probabilidad de que un objeto que guardaste siga ahí, intacto, después de un año. S3 está diseñado para 99.999999999 % al año: once nueves. Dicho al revés, la probabilidad de perder un objeto dado en un año es 0.000000001 %, es decir, 10⁻¹¹.

Es un número tan chico que conviene traducirlo a objetos.

Cuántos objetos perderías al año con once nuevesLa cuenta
Perder un objeto dado en un añouna en cien mil millones
1 − 0.99999999999
10⁻¹¹
Con 10 millones de objetosel ejemplo de AWS
10⁷ × 10⁻¹¹
0.0001 al año
Cada cuánto se pierde uno
1 ÷ 0.0001
1 cada 10,000 años
Las fotos de un año del marketplace10 M al día × 365
3.65 × 10⁹ × 10⁻¹¹
0.0365 al año
Cada cuánto se pierde una
1 ÷ 0.0365
≈ 1 cada 27 años
Resultado
Con 3,650 millones de fotos, esperarías perder una cada ≈ 27 años por culpa del almacenamiento. Por culpa de un DELETE equivocado se pierden muchas más.

¿Cómo se logra? En S3 Standard (y en las demás clases de la tabla de abajo), cada objeto se guarda repartido en muchos discos, en al menos tres zonas de disponibilidad (centros de datos separados por kilómetros) de la región. Cada pedazo lleva una huella para detectar si un bit se dañó. Y cuando un disco muere, el sistema rehace sus pedazos con los demás antes de que muera otro.

Para ir más hondoPor qué tres copias dan tantos nueves

Con números de juguete: un disco pierde sus datos con probabilidad 1 % al año, y una copia perdida se rehace en un día.

  • Una copia: pierdes 1 de cada 100 objetos al año: 10⁻².
  • Dos copias: para perder el objeto, la segunda tiene que morir el mismo día que la primera: 10⁻² × (10⁻² ÷ 365) ≈ 2.7 × 10⁻⁷.
  • Tres copias: además, la tercera, ese mismo día: 10⁻² × (10⁻² ÷ 365)² ≈ 7.5 × 10⁻¹².

Ignorando factores de 2 o 3, eso ya son ≈ 11 nueves. Las copias tienen que fallar por separado: tres discos en el mismo estante, con la misma fuente de luz, no cuentan como tres (en la lección de probabilidad lo viste como falla correlacionada). S3 no guarda tres copias completas, sino pedazos con información extra (erasure coding), que dan la misma protección con menos bytes.

Durabilidad no es disponibilidad

En la lección de probabilidad viste la disponibilidad y los los nueves: qué fracción del tiempo un servicio contesta. Son cosas distintas:

  • Disponibilidad: ¿S3 me responde ahora? S3 Standard está diseñado para 99.99 % (≈ 53 minutos al año en que una request puede fallar). En su contrato (el SLA), AWS promete menos: 99.9 % cada mes, y si no lo cumple devuelve una parte del cobro.
  • Durabilidad: ¿mi objeto sigue existiendo? Once nueves.

Un bucket puede no contestar un rato sin perder nada: reintentas y ahí está. Y al revés, con disponibilidad perfecta, un DELETE tuyo borra la foto para siempre. La durabilidad te protege del hardware, no de ti. Para lo segundo hay versionado del bucket (cada PUT o DELETE guarda la versión anterior), Object Lock (una versión que nadie puede borrar antes de una fecha) y copias en otra cuenta o región.

Clases de almacenamiento

No todo se lee igual de seguido. La foto de una publicación activa se ve cientos de veces; la de una que se vendió hace un año, casi nunca. Por eso S3 tiene clases de almacenamiento (storage classes): la misma foto, con la misma durabilidad, guardada más barato a cambio de que leerla cueste más o tarde más. Los nombres son de S3: IA quiere decir Infrequent Access (acceso poco frecuente), y Glacier (glaciar) es la familia de las clases para archivo.

Las cinco clases de almacenamiento de S3, con el precio de guardar un GB al mes como barra. Standard, 0.023 dólares, se lee al instante sin cargo por GB. Standard-IA, 0.0125, se lee al instante pagando 0.01 dólares por GB, con un mínimo de 30 días. Glacier Instant Retrieval, 0.004, al instante pagando 0.03 por GB, mínimo 90 días. Glacier Flexible Retrieval, 0.0036, de minutos a horas, mínimo 90 días. Glacier Deep Archive, cerca de 0.001, hasta 12 horas, mínimo 180 días. Todas tienen once nueves de durabilidad: lo que cambia es cuánto cuesta o cuánto tarda leer. De Standard a Deep Archive, guardar es unas 23 veces más barato. GUARDAR 1 GB UN MES, Y LEER Standard US$0.023 Leer: al instante, sin cargo por GB Standard-IA US$0.0125 Leer: al instante + US$0.01/GB · mín. 30 días Glacier Instant Retrieval US$0.004 Leer: al instante + US$0.03/GB · mín. 90 días Glacier Flexible Retrieval US$0.0036 Leer: de minutos a horas · mín. 90 días Glacier Deep Archive ≈ US$0.001 Leer: hasta 12 h de espera · mín. 180 días Las cinco: once nueves. De arriba abajo, guardar es 23 veces más barato; leer, más caro o lento.
Las clases de S3, de la más cara de guardar a la más barata. La barra es el precio por GB al mes; debajo, lo que cuesta leer y cuánto hay que esperar. Todas tienen la misma durabilidad.
ClaseGuardar, US$ por GB-mesLeerMínimo que te cobranPara qué
Standard0.023Al instante, sin cargo por GB—Lo que se lee seguido
Standard-IA0.0125Al instante, + US$0.01 por GB30 días y 128 KB por objetoSe lee poco, pero hay que tenerlo a la mano
Glacier Instant Retrieval0.004Al instante, + US$0.03 por GB90 días y 128 KB por objetoSe lee una vez por trimestre
Glacier Flexible Retrieval0.0036De minutos a horas90 díasArchivo que casi no se lee
Glacier Deep Archive≈ 0.001Hasta 12 h, o 48 h barato180 díasLo que se guarda por ley

Son precios de lista de la región del norte de Virginia (us-east-1), revisados en noviembre de 2026; cambian por región y con el tiempo. Standard baja un poco con volúmenes muy grandes: US$0.022 pasados los primeros 50 TB y US$0.021 pasados 500 TB.

Fíjate en la columna del mínimo. Si guardas algo en Standard-IA y lo borras a los 10 días, te cobran 30. Un objeto de 10 KB en Standard-IA paga como si pesara 128 KB. En Flexible Retrieval y Deep Archive, cada objeto paga además ≈ 40 KB de metadatos: con millones de objetos chicos, se nota. Y lo que se guarda en Glacier Deep Archive no se puede abrir al momento: primero pides que lo «restauren», y esperas horas. Google tiene la misma escalera con otros nombres: Standard, Nearline (30 días), Coldline (90) y Archive (365).

Elegir clase a mano para millones de objetos es imposible. Para eso existen las reglas de la sección siguiente.

05

Ciclo de vida, retención y lo que cuesta

Esencial

Lifecycle, retention and what it costs

Reglas de ciclo de vida

Una regla de ciclo de vida (lifecycle rule) le dice al bucket qué hacer con los objetos según su edad, sin que ningún programa tuyo lo haga. Tiene dos tipos de acción:

  • Mover (transition): «a los 30 días, pasa a Glacier Instant Retrieval».
  • Borrar (expiration): «a los 365 días, bórralo».

Cada regla aplica a un prefijo (o a los objetos con cierta etiqueta), así que distintas partes del bucket pueden tener reglas distintas. S3 la revisa por su cuenta, más o menos una vez al día. Así se ve una, en el JSON que recibe S3 (ilustración):

json
{"Rules": [{"ID": "fotos-viejas", "Status": "Enabled", "Filter": {"Prefix": "fotos/"},
            "Transitions": [{"Days": 30, "StorageClass": "GLACIER_IR"}],
            "Expiration": {"Days": 365}}]}

Retención: cuánto guardar y por qué

Antes de escribir la regla hay que decidir la retención (retention): cuánto tiempo se conserva cada cosa. La deciden tres fuerzas, y casi siempre tiran en direcciones distintas.

  • El costo. Cada GB se paga cada mes que sigue ahí. Lo que nunca se borra crece sin parar.
  • La ley y la privacidad. Las fotos y los logs traen datos de personas: caras, placas, ubicaciones en el EXIF (los datos que la cámara esconde dentro del JPEG). Las leyes de datos personales piden guardar solo lo necesario y borrar cuando alguien lo pide. Cuanto más guardas, más puedes filtrar.
  • El ML. Para reentrenar, buscar drift y comparar modelos de meses distintos hace falta historia.

En C01, la Ronda las reparte así: los logs de predicción duran 90 días; las copias de fotos que van a etiquetar, también 90; los agregados diarios (cuántas predicciones por categoría, por ejemplo) se guardan para siempre, porque no traen datos de nadie. El golden set (las fotos fijas, bien etiquetadas, con las que se examina cada modelo) y los snapshots de entrenamiento (la lista exacta de datos con que se entrenó cada modelo, en la sección 7) no caducan: si el golden set se borrara a los 90 días, ya no podrías comparar el modelo de marzo con el de octubre sobre las mismas fotos. Pero cuando alguien pide que borren su foto, se busca por su huella en todos ellos.

Lo que cuesta: GB-mes y requests

S3 cobra con dos medidores.

  • GB-mes: guardar 1 GB durante un mes. En Standard, ≈ US$0.023. Guardar 2 GB durante medio mes también es 1 GB-mes.
  • Requests: en Standard, US$0.005 por cada 1,000 PUT (y COPY y LIST), y US$0.0004 por cada 1,000 GET. Los DELETE son gratis. Cuando una regla mueve un objeto de clase, eso también es una request (una transición): US$0.01 por cada 1,000 objetos hacia Standard-IA, US$0.02 hacia Glacier Instant Retrieval y US$0.05 hacia Deep Archive.

Para pasar de días a meses, las cuentas usan 30.4 días por mes (365 ÷ 12).

Una equivalencia para recordar: un PUT cuesta lo mismo que guardar ≈ 217 KB durante un mes (0.000005 ÷ 0.023 GB). Con una foto de 200 KB, subirla cuesta como un mes de guardarla. Con un log de 300 bytes, subirlo cuesta como guardarlo 60 años.

Un año de fotos del marketplace, con y sin ciclo de vidaLa cuenta
Fotos que entran cada día10 M × 200 KB
2,000 GB
2 TB al día
Guardado después de un año
2 TB × 365
730 TB
Todo en Standard, cada mesya lleno
730,000 GB × 0.023
≈ US$16,790
Con ciclo: los últimos 30 días en Standard
60,000 GB × 0.023
US$1,380
Los 335 días anteriores en Glacier IR
670,000 GB × 0.004
US$2,680
Mover cada foto cobra una requestUS$0.02 por 1,000
10 M × 30.4 × 0.02 ÷ 1,000
US$6,080
Con ciclo, cada mes
1,380 + 2,680 + 6,080
≈ US$10,140
Resultado
El ciclo de vida ahorra ≈ 40 %, y la línea más cara ya no son los GB: son las 304 millones de transiciones al mes. Con objetos chicos, hasta mover cuesta.
Para ir más hondoEl descuento por volumen y los objetos chicos

La cuenta usa US$0.023 para todo. Con el descuento por volumen, «todo en Standard» bajaría a ≈ US$15,900 y el ahorro, a ≈ 36 %: la conclusión no cambia. AWS conoce bien el problema de mover objetos chicos: desde septiembre de 2024, una regla nueva no mueve objetos de menos de 128 KB, a menos que se lo pidas.

Esa cuenta es la del bucket del producto, el del marketplace. C01 no guarda su propia copia de cada foto: la foto ya vive ahí, y C01 solo anota su llave. Si la copiara «por si acaso», la Ronda (M12) calcula ≈ 60 TB más cada mes: ≈ US$1,380 el primer mes, US$2,760 el segundo, y así cada mes más, con datos personales y sin dueño.

Un año de fotos, con ciclo de vidaCalculadora

Las fotos entran cada día; las primeras semanas viven en Standard y después pasan a una clase fría hasta que se borran. Arranca con el bucket del marketplace: 10 millones de fotos de 200 KB, 30 días en Standard, Glacier Instant Retrieval y borrado al año. Las cuentas son de un mes cualquiera, cuando el bucket ya está lleno.

Lo que entra cada día2.00 TB
Guardado en totallos días de retención × lo de cada día730 TB
Standard, en US$ al mes1,380
Clase fría, en US$ al mes2,680
Mover las fotos, en US$ al mesuna request por foto, ≈ 30.4 días de fotos6,080
Total con ciclo de vida, en US$ al mes10,140
Todo en Standard, en US$ al mes16,790
Lo que ahorra el ciclo de vidanegativo: sale más caro que no hacer nada39.6 %

No cuenta lo que cuesta leer de la clase fría (US$0.01 a 0.03 por GB, u horas de espera en Glacier) ni las duraciones mínimas (si la retención es menor que el mínimo de la clase, te cobran el mínimo), ni los ≈ 40 KB de metadatos que paga cada objeto en Deep Archive. Standard se cobra a US$0.023 por GB-mes para todo, sin el descuento por volumen. Precios de lista de us-east-1, noviembre de 2026.

Prueba Deep Archive (precio 0.001, mover 0.05): sale más caro que dejar todo en Standard. Después pon la retención en 90 días: «Todo en Standard» baja de ≈ US$16,790 a ≈ US$4,140, y mover a Glacier ya no conviene. Borrar a tiempo ahorra más que cualquier clase.

Con objetos grandes, el costo son los GB. Con millones de objetos chicos, mandan las requests. El log de C01 lo muestra.

El log de C01: un objeto por predicción o un archivo por minutoLa cuenta
Predicciones al día≈ 300 B cada una
10 M × 300 B
3 GB al día
Guardar 90 días de log
270 GB × 0.023
≈ US$6 al mes
Un objeto por predicción: PUT al mes
10 M × 30.4 × 0.005 ÷ 1,000
≈ US$1,520
Leerlo una vez al mes, objeto por objeto
304 M × 0.0004 ÷ 1,000
≈ US$122
Un archivo por minuto: PUT al mes
1,440 × 30.4 × 0.005 ÷ 1,000
≈ US$0.22
Resultado
Los mismos 3 GB al día cuestan ≈ US$1,650 al mes en objetos sueltos o ≈ US$6 en archivos de un minuto. Por eso C01 solo imprime sus logs, como texto, y otro programa los junta y los sube a S3 en archivos grandes.
Objetos chicos contra archivos grandesCalculadora

Los mismos registros, guardados uno por objeto o juntos en archivos. Arranca con el log de C01: 10 millones de predicciones al día, de ≈ 300 bytes, un objeto por predicción, 90 días de retención y un job que lee el último mes una vez al mes. Precios de lista de S3 Standard en us-east-1 (noviembre de 2026): US$0.023 por GB-mes, US$0.005 por 1,000 PUT y US$0.0004 por 1,000 GET.

Tamaño de cada objeto300 B
Objetos que se suben al día10,000,000
Guardar, en US$ al mes6.21
Los PUT, en US$ al mes1,520.00
Los GET de las lecturas, en US$ al mes121.60
Total, en US$ al mes1,647.81
Parte del total que son requests99.6 %

Un PUT cuesta lo mismo que guardar ≈ 217 KB un mes. Con objetos mucho más chicos que eso, mandan las requests; con objetos mucho más grandes, los GB.

Arranca con un objeto por predicción. Escribe 6944 registros por objeto (un archivo por minuto: 10 M ÷ 1,440 minutos del día) y mira cómo las requests pasan de casi todo a casi nada. Cada archivo de un minuto pesa ≈ 2 MB: ya basta para que las requests casi no cuesten. Para leer rápido conviene juntar todavía más, en archivos de ≈ 100 MB a 1 GB, y eso hace la compactación de la sección siguiente.

06

Data lake y particiones por fecha

Esencial

Data lake and date partitions

Ya tienes dónde guardar. Ahora falta organizar, para que alguien encuentre lo que busca entre millones de archivos.

Un lago de archivos

Un data lake es un object storage donde llega todo el dato de la empresa como archivos: logs, eventos de la app, etiquetas, copias de tablas. Se guarda tal como llegó y también ya procesado, y lo lee cualquier herramienta: Spark (un programa que reparte el trabajo de leer y transformar datos entre muchas máquinas), DuckDB (una base de datos chiquita para analizar, que corre en tu laptop), Athena (consultas SQL directo sobre los archivos de S3) o un script de Python.

La Ronda lo llama la fuente de verdad del camino offline, el que prepara el siguiente modelo sin que nadie espere: todo dataset de entrenamiento y todo recálculo del pasado salen de ahí. Casi siempre se organiza en zonas, cada una con su prefijo:

  • Crudo (raw): tal como llegó, por ejemplo JSON lines del log. No se toca: si un paso posterior tenía un bug, se puede rehacer desde aquí.
  • Procesado (processed): limpio, con tipos correctos, en Parquet. Es columnar y viene comprimido: los 3 GB diarios de log de C01 quedan en ≈ 0.3 a 0.6 GB.
  • Curado (curated): tablas listas para usar, como un dataset de entrenamiento o los agregados diarios.

Así se vería el lake de C01, con un bucket y un prefijo por zona (un ejemplo; cada equipo elige sus nombres):

text
s3://c01-lake/
  crudo/predicciones/dt=2026-11-06/...        JSON lines, como llegaron
  procesado/predicciones/dt=2026-11-06/...    Parquet, una fila por predicción
  curado/agregados_diarios/dt=2026-11-06/...  conteos por categoría
  curado/datasets/ds-2026-09-01/...           el snapshot de un entrenamiento

Un lago no obliga a nada. Cualquiera puede escribir cualquier archivo, y nadie revisa que cumpla el esquema: las columnas y sus tipos. El esquema lo descubre quien lee, al leer (schema on read). Si el equipo de la app renombró una columna el martes, el job de la noche se entera al fallar, o peor, sin fallar. Por eso los lagos sin reglas se vuelven pantanos, con archivos que nadie sabe qué son. Las capas de la sección siguiente ponen el orden: el warehouse y el lakehouse revisan el esquema al escribir.

Particionar por fecha

Si todo el log de un año estuviera en un solo prefijo, preguntar «¿cuántas fotos de tenis hubo ayer?» obligaría a leer el año entero. La solución es una partición (partition): dividir la tabla en grupos de archivos según el valor de una columna, casi siempre la fecha, y poner ese valor en la llave:

logs/predicciones/dt=2026-11-06/part-0000.parquet

El pedazo dt=2026-11-06 es una convención (columna=valor) que entienden Spark, Athena, DuckDB y los warehouses. dt es solo el nombre de la columna, por date; en la lección de formatos la viste como fecha=2026-11-05/, y funciona igual. Cuando la consulta dice «solo el 6 de noviembre», el motor lista ese prefijo y no abre nada más. Se llama partition pruning: podar las particiones que no sirven.

Un mes de log de predicciones de C01, noviembre de 2026, como 30 casillas, una partición por día, cada una con 4 archivos Parquet de unos 125 MB, de dt=2026-11-01 a dt=2026-11-30. La casilla del día 6 está resaltada: es la que pide una consulta de un día. Las casillas del 1 al 7 están marcadas como la semana. Abajo, lo que se lee en cada caso: un día, 4 archivos y medio GB; una semana, 28 archivos y 3.3 GB; el mes entero, 120 archivos y 15 GB. Sin particiones, cualquier consulta tendría que abrir el mes entero. LOGS/PREDICCIONES/ · NOV 2026 Cada casilla es un prefijo, de dt=2026-11-01/ a dt=2026-11-30/, con 4 archivos de ≈ 125 MB. 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 el día que pide la consulta: dt=2026-11-06 la semana, del 1 al 7 LO QUE SE LEE Un día 4 archivos · 0.5 GB Una semana 28 archivos · 3.3 GB El mes, o cualquier consulta sin particiones 120 archivos · 15 GB
Un mes de log de C01, una partición por día. La consulta de un día abre 4 archivos; la de una semana, 28; sin particiones, habría que abrir los 120 del mes.

El lake de juguete de abajo tiene un mes de log: 4 archivos Parquet por día, de ≈ 125 MB cada uno. Leer «un día» es listar su prefijo.

python
import random
random.seed(7)
lake = {}                                  # llave → bytes del archivo: solo importan las llaves
for dia in range(1, 31):                   # noviembre de 2026, 4 archivos Parquet por día
    for parte in range(4):
        llave = f"logs/predicciones/dt=2026-11-{dia:02d}/part-{parte:04d}.parquet"
        lake[llave] = random.randint(100, 150) * 1_000_000

def leer(prefijos):                        # lo que hace un motor de consultas: listar y leer
    llaves = [k for k in lake if any(k.startswith(p) for p in prefijos)]
    return len(llaves), sum(lake[k] for k in llaves)

semana = [f"logs/predicciones/dt=2026-11-{d:02d}/" for d in range(1, 8)]
for nombre, prefijos in (("un día", ["logs/predicciones/dt=2026-11-06/"]),
                         ("una semana", semana), ("el mes entero", ["logs/predicciones/"])):
    n, b = leer(prefijos)
    print(f"{nombre:>13}: {n:>3} archivos · {b / 1e9:5.2f} GB")

particiones = sorted({k.split("/")[2] for k in lake})   # como un LIST con delimitador «/»
print(len(particiones), "particiones:", particiones[0], "…", particiones[-1])
Salida
       un día:   4 archivos ·  0.50 GB
   una semana:  28 archivos ·  3.34 GB
el mes entero: 120 archivos · 14.92 GB
30 particiones: dt=2026-11-01 … dt=2026-11-30

Leer un día abre 4 de los 120 archivos: un trigésimo del mes. La última línea hace lo que un LIST con delimitador «/»: en vez de todas las llaves, S3 devuelve solo los prefijos distintos hasta la siguiente «/», que aquí son las 30 particiones.

Particionar también hace que cada corrida procese una partición. El job de cada noche escribe solo dt=2026-11-06/. Si tenía un bug, se reescribe esa partición y nada más. Lo contrario, una tabla única que se reescribe entera cada noche, obliga a reprocesar todo para arreglar un día.

Se puede particionar por más de una columna, una dentro de otra. El log de predicciones de la Ronda (M12) va por día y por versión del modelo, dt=2026-11-06/model_version=v13/, para que el job que compara la versión nueva con la vieja lea solo las dos que le tocan. La columna que va primero es la que más se filtra.

Tres reglas para que funcione:

  • Partir por lo que se filtra. La fecha casi siempre, porque casi toda pregunta empieza por «en estos días». Partir por categoría, si nadie filtra por categoría, solo multiplica archivos.
  • Ni muy fino ni muy grueso. Particionar por hora y además por usuario daría millones de archivos diminutos, y ya viste que los objetos chicos se pagan en requests y en tiempo de listar. Se buscan archivos de ≈ 100 MB a 1 GB. Cuando un stream (un flujo de eventos que no para, tema de la lección siguiente) deja muchos archivos chicos, un job de compactación los junta cada noche en pocos grandes.
  • ¿Qué fecha? Una predicción de las 23:59 puede llegar al lake a las 00:03. Si la partición usa la hora de llegada, cae en el día siguiente. Para entrenar importa la hora en que pasó, el event time, que verás en la lección de tiempo y hashes.
07

Warehouse, lakehouse y snapshots

Esencial

Warehouses, lakehouses and snapshots

Dos maneras de usar datos: OLTP y OLAP

La base de datos del marketplace atiende millones de operaciones chiquitas: guardar una publicación, leer el usuario 42, cambiar un precio. Cada una toca pocas filas, completas, y tiene que tardar milisegundos. Eso se llama OLTP (online transaction processing, procesar transacciones en línea, mientras el usuario espera), y es lo que viste en la lección de bases de datos: tablas en una base relacional, con transacciones e índices.

Un analista pregunta otra cosa: «¿cuántas predicciones hubo por categoría en octubre, y cuántas aceptó la gente?». Su consulta toca millones de filas, pero solo dos o tres columnas, y puede tardar segundos. Eso es OLAP (online analytical processing, procesar para analizar).

Son formas tan distintas que piden almacenes distintos. Para OLTP conviene guardar cada fila junta; para OLAP, cada columna junta, como Parquet. La lección de formatos lo explicó: leer dos columnas de treinta en un formato columnar es leer ≈ 2/30 de los bytes (≈ 7 %), y menos con compresión. La diferencia entre OLTP y OLAP es la razón de que existan los warehouses.

Data warehouse

Un data warehouse es una base de datos hecha para OLAP: guarda las tablas por columnas, comprimidas, en su propio almacenamiento, y responde SQL repartiendo cada consulta entre muchas máquinas. Los más usados son BigQuery (Google), Snowflake y Redshift (AWS). Separan el almacenamiento del cálculo: guardas petabytes baratos y rentas máquinas solo mientras corre la consulta.

sql
SELECT categoria, COUNT(*) AS fotos, AVG(CAST(aceptada AS INT64)) AS tasa_aceptacion
FROM c01.predicciones
WHERE dt BETWEEN '2026-10-01' AND '2026-10-31'
GROUP BY categoria
ORDER BY fotos DESC;

Se lee casi en español: de la tabla c01.predicciones, toma las filas de octubre (WHERE), júntalas por categoría (GROUP BY) y, para cada grupo, cuenta las fotos y saca el promedio de aceptada, que vale 1 si la persona aceptó la categoría sugerida y 0 si no: ese promedio es la tasa de aceptación. Toca millones de filas, pero solo tres columnas: categoria, aceptada y dt.

BigQuery, en su modo por consulta, cobra por los bytes que lee: US$6.25 por TiB en su precio de lista de 2026, con el primer TiB de cada mes gratis. Ahí las particiones y las columnas se vuelven dinero. Si la consulta leyera el log crudo, como archivos JSON sin particiones, pagaría el año entero: ≈ 1.1 TB, ≈ US$6 por consulta. En Parquet, las tres columnas que usa esa consulta en las particiones de un mes son unos pocos GB: centavos.

¿Lake o warehouse? El lake es barato, guarda cualquier cosa y lo lee cualquier herramienta, pero no tiene transacciones: si un job muere a la mitad de escribir una partición, quien lea en ese momento ve archivos a medias. El warehouse da tablas con transacciones y SQL rápido, pero cuesta más y hay que cargarle los datos. Muchas empresas usan los dos: el lake guarda todo y el warehouse, las tablas que se consultan a diario.

Lakehouse: tablas encima de los archivos

Un lakehouse junta lo mejor de los dos: deja los datos como archivos Parquet en el lake y les pone encima un formato de tabla que da transacciones. Los tres más usados son Delta Lake (de Databricks), Apache Iceberg (nació en Netflix) y Apache Hudi (nació en Uber).

El truco es un registro aparte, guardado en el mismo bucket, que dice qué archivos forman la tabla en cada versión. Escribir es: subir los Parquet nuevos y, al final, agregar al registro una entrada que diga «la versión 3 son estos archivos». Hasta que esa entrada existe, nadie ve los archivos nuevos. Así cada escritura pasa completa o no pasa, y quien lee nunca ve una tabla a medias.

Cómo guarda versiones un lakehouse. En el bucket hay cinco archivos Parquet, A, B, C, D y E. Un registro aparte dice qué archivos forman cada versión de la tabla. La versión 1 son A y B. La versión 2 agrega filas en C: A, B y C. La versión 3 borra filas de B: reescribe lo que quedaba de B en un archivo nuevo, D, y deja de apuntar a B: A, C y D. La versión 4 agrega E: A, C, D y E. Leer la versión 2 es leer A, B y C: eso es el time travel. B sigue en el bucket hasta que la limpieza lo borra; después, las versiones 1 y 2 ya no se pueden leer. ARCHIVOS PARQUET EN EL BUCKET A B C D E Nunca se editan: solo se agregan archivos nuevos. EL REGISTRO DE VERSIONES v1 escribe A y B A B v2 agrega filas en C A B C v3 borra filas de B → D A C D v4 agrega E A C D E Time travel: leer v2 es leer A, B y C. La tabla de hoy (v4) ya no usa B, pero B sigue en el bucket: nadie copió nada para guardar v2. Si la limpieza borra B, v1 y v2 se pierden.
Un lakehouse no copia datos para cada versión: cada versión es una lista de archivos. Borrar filas reescribe un archivo y la versión nueva deja de apuntar al viejo, pero el viejo sigue ahí, y leer la versión 2 sigue funcionando. Eso es el time travel.

Con eso se puede:

  • Corregir filas sueltas con un upsert (actualizar la fila si existe, insertarla si no) o borrarlas, algo que con Parquet solo no se puede, porque un objeto no se edita a la mitad. Hace falta, por ejemplo, para borrar los datos de una persona que lo pidió.
  • Agregar columnas sin romper a quien lee (la evolución del esquema de la lección de formatos).
  • Leer la tabla como estaba en una versión o una fecha: el time travel (viaje en el tiempo).

Snapshot: una foto fija para repetir un entrenamiento

Un snapshot es una foto fija de los datos en un momento: lo que había, y que ya no cambia aunque la tabla siga creciendo. En Iceberg, cada escritura crea uno. Para ML es la pieza que hace repetible un entrenamiento: el modelo de octubre guarda con qué snapshot se entrenó, y dentro de seis meses alguien puede volver a leer exactamente esas filas.

C01 lo hace sin copiar fotos. Su snapshot es un manifest: un archivo Parquet que lista la llave de cada foto, su etiqueta y una huella de su contenido (un hash SHA-256, que cambia si cambia un solo byte). Vive en un prefijo que no se reescribe, como datasets/ds-2026-09-01/, y el modelo guarda la huella del propio manifest. Un manifest pesa megabytes, así que puedes tener uno por mes durante años.

Para ir más hondoEl time travel no es para siempre

En Delta Lake, por omisión, el historial dura 30 días y la limpieza (VACUUM) puede borrar los archivos viejos pasados 7; en Iceberg, la limpieza de snapshots (expire_snapshots) borra por omisión los de más de 5 días. Ninguna de las dos borra sola: corren cuando alguien las programa, y se programan para no pagar archivos viejos para siempre. Un snapshot que tiene que durar (el de un modelo en producción) se marca aparte, con su propia retención.

Llevar la cuenta de qué snapshot, qué código y qué contenedor produjeron cada modelo es el versionado de datos y el linaje: los verás a fondo en la estación 2 del Dojo, con DVC y lakeFS.

08

Feature store y backfill

Extra

Feature stores and backfills

El mismo número en dos lugares

Un modelo de fraude, como el de C09, usa features como «cuántas compras hizo esta tarjeta en las últimas 24 horas». Ese número se necesita en dos momentos muy distintos:

  • Para entrenar: para cada transacción del pasado, el valor que tenía en ese momento. Son millones de filas, y se leen de una vez, en horas.
  • Para servir: para la transacción de ahora, el valor de ahora, en un par de milisegundos.

Si cada equipo lo calcula a su manera, con un SQL para entrenar y un código distinto en el servicio, tarde o temprano los dos números se separan. Es el training-serving skew que viste en la lección de imágenes: el modelo aprendió con un número y en producción recibe otro.

Un feature store resuelve eso con una sola definición de cada feature y dos almacenes:

  • El offline store: todas las versiones de cada valor, con su hora, en el lake o en el warehouse. Sirve para armar datasets de entrenamiento.
  • El online store: solo el último valor de cada usuario o tarjeta, en una base base llave-valor como Redis o DynamoDB (la de AWS), que responde en milisegundos.

Un job copia, cada tanto, los valores nuevos del offline al online. A eso se le llama materializar. Herramientas conocidas: Feast (de código abierto), Tecton (desde 2025, parte de Databricks) y los feature stores de Databricks, SageMaker y Vertex AI.

Una feature, una definición, dos almacenes · Arriba, el carril lento: el mismo job llena el offline store, y de ahí salen los datasets. Abajo, el rápido: el servicio lee el último valor del online store en ≈ 1 ms. La flecha «materializa» une los dos. Usa «Recorrer» para seguir un entrenamiento, una request y el backfill de una feature nueva.
  • Data lake · eventos por dt=
    Las transacciones y los eventos de cada día, en Parquet, en una partición por fecha. Es la fuente de verdad: todo lo de abajo se puede rehacer desde aquí.
  • Job de features · una sola definición
    El código que calcula «compras de la tarjeta en las últimas 24 h». Es el mismo para la historia y para el presente: si hubiera dos versiones, sus números se separarían (training-serving skew).
  • Offline store · cada valor con su hora
    Todas las versiones de cada valor, con su timestamp, en el lake o en el warehouse. De aquí salen los datasets de entrenamiento.
  • Dataset · point-in-time
    Para cada ejemplo toma el valor que la feature tenía justo antes de ese momento (point-in-time correctness). Si tomara uno posterior, el modelo aprendería con el futuro: leakage.
  • Request · la tarjeta 77
    Una transacción de ahora. El modelo tiene que decidir en milisegundos si la deja pasar.
  • Servicio del modelo · pide las features
    Lee las features de la tarjeta del online store, con su llave (el id de la tarjeta), y se las da al modelo. No calcula nada histórico en el momento.
  • Online store · llave-valor · el último valor
    Solo el valor más nuevo de cada tarjeta, en una base base llave-valor como Redis: responde en ≈ 1 ms. Cada llave lleva un TTL para que lo que ya nadie usa se borre solo.

Al armar un dataset, para cada ejemplo hay que tomar el valor que la feature tenía justo antes de ese momento, no el de después. Si no, el modelo aprende con información del futuro, un leakage. Esa unión se llama point-in-time join, y la verás con calma en la lección de tiempo y hashes: point-in-time correctness.

El online store solo guarda el presente, así que cada llave lleva un tiempo de vida (TTL): si una tarjeta no se usa en meses, su fila se borra sola y la memoria no crece sin fin.

¿C01 necesita un feature store? La Ronda dice que no: en visión pura, una foto entra y una categoría sale, y la feature es la imagen misma. Sí lo necesitan C08 (recomendación) y C09 (fraude), donde el modelo vive de la historia de cada usuario.

Backfill: recalcular el pasado

Inventas una feature nueva: «fotos que subió este vendedor en los últimos 7 días». Hoy empiezas a calcularla, pero para entrenar necesitas su historia, y el log de los últimos 90 días está en el lake. Correr el mismo cálculo sobre los días que ya pasaron es un backfill (rellenar hacia atrás).

Gracias a las particiones, un backfill es la misma corrida diaria, repetida una vez por cada día viejo.

El backfill de una feature nueva, 90 díasLa cuenta
Particiones que hay que procesar
90 días × 1
90 corridas
Tiempo por particiónsupuesto: lo que tarda la corrida diaria
—
≈ 20 min
En serie, una tras otra
90 × 20 min
1,800 min = 30 h
Con 10 corridas a la vez
30 h ÷ 10
≈ 3 h
Resultado
Como cada corrida escribe solo su partición y escribirla dos veces da lo mismo (idempotencia), si una se cae a la mitad se repite esa y ya.

Dos cuidados. El backfill corre el mismo código que la corrida diaria, no un script aparte escrito con prisa: si no, la historia y el presente vuelven a ser números distintos. Y escribe en el offline store, no en el online: a las requests de hoy no les sirve el valor de hace 90 días.

El backfill de C01 es otro: clasificar con el modelo las ≈ 200 millones de fotos que ya había en el catálogo. La Ronda lo parte en ≈ 2,000 pedazos de 100,000 fotos, cada uno con su archivo de salida. Al reanudar, se saltan los pedazos que ya tienen salida. Leer las 200 millones de fotos son 200 millones de GET: 200 M × US$0.0004 ÷ 1,000 = US$80.

09

Errores comunes

Esencial

Common mistakes

1. Usar el object storage como si fuera un disco

Abrir un objeto para agregarle una línea, editarlo a la mitad o «renombrar una carpeta» con un millón de fotos como si fuera instantáneo. O dos jobs que escriben la misma llave: gana el último, y el otro se pierde sin aviso.

Cómo evitarlo: diseñar con objetos que se escriben una vez. Llaves que no se repiten (con la fecha, la versión o el id del job), archivos nuevos en vez de editar los viejos y, si hace falta editar filas, un formato de tabla como Delta o Iceberg.

2. Millones de objetos chiquitos

Un objeto por predicción, por evento o por fila. Guardarlos es barato; subirlos, listarlos, moverlos de clase y leerlos, no. El log de C01 así cuesta ≈ US$1,650 al mes en vez de ≈ US$6.

Cómo evitarlo: juntar en archivos de ≈ 100 MB a 1 GB (Parquet, o pedazos de muchas fotos para entrenar). Y antes de una regla de ciclo de vida, contar los objetos, no solo los GB.

3. Creer que once nueves son un respaldo

La durabilidad protege de discos rotos, no de un DELETE, de una regla de ciclo de vida mal escrita o de un script con el prefijo equivocado.

Cómo evitarlo: versionado del bucket en lo que no se puede perder, Object Lock en lo que nadie debe borrar (el golden set, los snapshots de modelos en producción) y permisos que no dejen borrar a quien solo necesita leer.

4. Hacer público un bucket para «compartir rápido»

Un bucket público, o URLs prefirmadas de 7 días pegadas en un chat, con fotos de personas adentro.

Cómo evitarlo: el bucket privado siempre. Para compartir, URLs prefirmadas de una sola llave, de minutos, firmadas por un servicio que revisa quién las pide.

5. Mover a una clase fría lo que se sigue leyendo

Mandar a Standard-IA el dataset que se lee en cada entrenamiento, o a Deep Archive algo que alguien va a necesitar mañana. Pagas el GB leído, el mínimo de días y, en Deep Archive, horas de espera.

Cómo evitarlo: mirar cuántas veces se lee de verdad cada prefijo antes de escribir la regla. Si no lo sabes, Intelligent-Tiering, una clase de S3 que mueve cada objeto sola según su uso, a cambio de una cuota pequeña por objeto.

6. Una retención que nadie cumple

El bucket borra a los 90 días, pero las fotos siguen en snapshots, en copias y en laptops.

Cómo evitarlo: escribir la retención de cada artefacto al crearlo, no después, y que los snapshots se puedan buscar por la huella de cada foto para borrarla de todos.

10

En la vida real

Extra

In real life

C01: dónde va cada cosa

Ya puedes responder la pregunta de la lección. Las cuentas son de la Ronda, con precios de S3 Standard.

QuéDóndeCuántoRetenciónAl mes
Fotos de las publicacionesBucket del producto, no de C012 TB al díaLa del productoLa paga el marketplace
Log de cada predicciónLake, Parquet por dt=3 GB al día crudo90 días; agregados para siempre≈ US$6
Fotos que van a etiquetarBucket restringido, sin EXIF≈ 5,000 al mes, ≈ 1 GB90 díasCentavos
Golden setBucket restringido50,000 fotos, ≈ 10 GBSin caducar, borrado por huella≈ US$0.23
Snapshots de entrenamientoPrefijos fijos, manifest en ParquetMegabytes cada unoSin caducar, borrado por huellaCentavos
Pesos de cada versiónBucket de artefactos, junto al registro de modelos≈ 98 MB el ONNXLas versiones que puedan volverCentavos

Todo lo propio de C01 cabe en menos de US$10 al mes. La Ronda lo resume en una frase: el almacenamiento es barato; lo caro es la privacidad de lo que guardas.

Lo que sí se nota son las requests y la red. En el diseño base, el gateway recibe los bytes de cada foto. M13 propone que la request a C01 lleve la llave de la foto y no sus bytes, si el GET extra cabe en el p99. Con esa variante, el gateway lee cada foto de S3 con un GET: 304 millones al mes, ≈ US$122. Y M13 advierte que si esos GET salieran por el NAT (la puerta que deja a las máquinas privadas llegar a internet, y que cobra por GB), los ≈ 61 TB al mes costarían ≈ US$2.7 mil más; por un camino privado hacia S3, nada. Lo verás en la lección de redes en la nube.

Los pesos, además, van horneados (copiados adentro) en la imagen del contenedor del servicio, y la estación 7 del Dojo lo explica: el nombre de versión de la imagen (su tag) es la versión del modelo.

C02: cámaras que suben clips

Las cajas de C02, en cada centro de distribución, suben fotos y clips de cada evento con una URL prefirmada de 15 minutos, directo a S3: los megabytes de video no cruzan la API. Los clips se guardan 30 días, porque traen personas. Si cada sitio mandara el video continuo de sus 40 cámaras serían ≈ 1.7 TB al día; solo con los clips de eventos, de ≈ 5 MB, son ≈ 10 GB.

C07 y C08: copias para reconstruir y lagos para aprender

C07, la búsqueda por foto, guarda en S3 una copia de cada vector que calcula, en Parquet por versión del modelo: ≈ 205 GB por versión, ≈ US$5 al mes. Con ella reconstruye el índice sin volver a usar la GPU. Los vectores que lee en cada búsqueda, en cambio, viven en un disco gp3 de cada máquina.

C08, la recomendación, guarda en su lake 90 días del log de lo que mostró, de los eventos de la app y de la historia de sus features (su offline store), particionado por día y hora. Solo el log, en Parquet, son ≈ 18 a 36 TB: ≈ US$0.4 a 0.8 mil al mes en Standard. Con los eventos y la historia de features, la Ronda calcula ≈ US$0.5 a 1 mil al mes.

C09: el lake que espera 90 días

En el fraude, la etiqueta llega tarde. Cada transacción y la decisión del modelo entran al lake el mismo día, pero solo se sabe si era fraude cuando el dueño de la tarjeta reclama un cargo (un contracargo), y eso puede tardar semanas. La Ronda usa una regla: si en 90 días no apareció un contracargo, la fila ya es un ejemplo negativo «maduro». Aquí la retención del lake no la pone solo el costo: sin 90 días de historia no hay etiquetas.

El cálculo en vivo de C09 guarda su estado, ≈ 24 GB de contadores (80 millones de tarjetas × ≈ 300 bytes), en el disco local de sus máquinas, y cada tanto deja en S3 un checkpoint: una copia de ese estado de la que puede volver a arrancar (el programa puede subir solo lo que cambió desde el checkpoint anterior). Es el mismo reparto de la sección extra de bloques: el disco para trabajar rápido, el object storage para no perder nada si la máquina muere.

C06: el mismo log en dos servicios

M13 compara dónde mandar ≈ 5.5 TB al mes de logs de C06, el caso de moderación de contenido. En CloudWatch Logs, el servicio de logs de AWS, cuesta US$0.50 por GB al recibirlos: 5,472 GB × 0.50 ≈ US$2,700 al mes. En S3, 5,472 GB × 0.023 ≈ US$126. Los mismos bytes, veinte veces de diferencia. Por eso C01 manda a CloudWatch solo los logs del servicio (errores, arranques), y los de cada predicción, a S3.

Fuera de ML: el archivo que nadie lee

Un banco tiene que guardar sus registros durante años, por ley, y casi nunca los vuelve a abrir. Es el uso típico de Deep Archive con Object Lock: guardar cuesta ≈ US$1 por TB al mes, nadie puede borrar nada antes de la fecha, y si un día un auditor pide un archivo, se espera unas horas. Lo mismo hacen los estudios de cine con sus copias maestras y los hospitales con sus imágenes viejas.

11

Ejercicios

Esencial

Exercises

Resuélvelos con lápiz antes de abrir la solución. Los de costo se pueden comprobar con las calculadoras. Usa los precios de S3 Standard de la lección.

  1. 1Fácil

    En s3://ml-datos/logs/dt=2026-11-06/part-0003.parquet, ¿cuál es el bucket y cuál la llave? ¿Qué devuelve un LIST con el prefijo logs/dt=2026-11-0? Alguien quiere «renombrar la carpeta» logs/ a predicciones/ y tiene 50,000 objetos: ¿cuántas requests hace y cuánto cuestan?

    Ver la solución paso a paso
    • Bucket: ml-datos. Llave: logs/dt=2026-11-06/part-0003.parquet, todo lo que sigue.
    • El LIST devuelve las llaves de los días 1 al 9 de noviembre de 2026: un prefijo no tiene que terminar en «/».
    • Renombrar no existe: 50,000 COPY y 50,000 DELETE, más 50 LIST de 1,000 llaves. Son ≈ 100,050 requests.
    • Las COPY y los LIST se cobran como PUT: 50,050 × 0.005 ÷ 1,000 ≈ US$0.25. Los DELETE son gratis. Barato, pero no instantáneo, y quien lea a la mitad ve una parte en cada lado.
  2. 2Fácil

    Un equipo guarda mil millones de objetos en S3, con once nueves de durabilidad. ¿Cuántos esperaría perder al año? Y si el servicio tiene 99.99 % de disponibilidad, ¿cuántos minutos al año puede no contestar? ¿Se pierde algo en esos minutos?

    Ver la solución paso a paso
    • Durabilidad: 10⁹ × 10⁻¹¹ = 0.01 objetos al año: uno cada 100 años.
    • Disponibilidad: 0.01 % de 525,600 minutos ≈ 53 minutos al año.
    • En esos minutos no se pierde nada: las requests fallan, se reintenta y los objetos siguen ahí. Son dos medidas distintas.
  3. 3Fácil

    Un millón de registros de 1 KB: ¿cuánto cuesta guardarlos un mes y cuánto subirlos, si cada uno es un objeto? ¿Y si los juntas en un solo archivo de 1 GB?

    Ver la solución paso a paso
    • Guardar: 1 GB × 0.023 = US$0.023 en los dos casos.
    • Subir un millón de objetos: 10⁶ × 0.005 ÷ 1,000 = US$5, 217 veces lo que cuesta guardarlos un mes.
    • Un solo archivo: un PUT (en la práctica, unas pocas partes), ≈ US$0.000005.
  4. 4Fácil

    La API de C02 firma una URL de PUT para la llave sitio-07/clips/e-31.mp4, válida 15 minutos. ¿Qué puede hacer quien la tenga? ¿Puede leer otros clips, o subir uno a otra llave? ¿Y a los 20 minutos?

    Ver la solución paso a paso
    • Puede subir un archivo a esa llave, una o varias veces, durante 15 minutos (900 segundos). Si sube dos veces, el segundo reemplaza al primero.
    • No puede leer nada (la firma es para PUT), ni escribir en otra llave: cambiar la llave rompe la firma y S3 responde 403.
    • A los 20 minutos ya venció: 403. La caja (la computadora del sitio) pide una URL nueva.
    • Ojo: cualquiera que la copie puede hacer lo mismo durante esos 15 minutos. Por eso no se escribe en los logs.
  5. 5Medio

    Guardas 1 TB de datos temporales que vas a borrar a los 10 días. ¿Sale más barato en Standard o en Standard-IA? ¿Y si los guardaras 60 días?

    Ver la solución paso a paso
    • Standard, 10 días: 1,000 GB × 0.023 × 10 ÷ 30.4 ≈ US$7.57.
    • Standard-IA cobra mínimo 30 días: 1,000 × 0.0125 = US$12.50. Sale más caro, aunque su precio por GB es casi la mitad.
    • A 60 días: Standard, 1,000 × 0.023 × 2 ≈ US$46; IA, 1,000 × 0.0125 × 2 = US$25, si no se lee. Leerlo todo una vez sumaría 1,000 × 0.01 = US$10, y todavía gana IA.
  6. 6Medio

    El log de C01 en Parquet pesa ≈ 0.5 GB al día. Un analista corre cada mañana una consulta sobre los últimos 7 días. ¿Cuántos GB lee con particiones por día? ¿Y si la tabla no tuviera particiones y guardara un año? ¿Cuántas veces más?

    Ver la solución paso a paso
    • Con particiones: 7 × 0.5 = 3.5 GB.
    • Sin particiones, el motor no sabe dónde está cada fecha y abre todo el año: 365 × 0.5 = 182.5 GB.
    • 182.5 ÷ 3.5 ≈ 52 veces más, cada mañana. En BigQuery, que cobra por bytes leídos, es ≈ 52 veces el precio.
  7. 7Medio

    C07 guarda una copia de sus vectores en S3: ≈ 205 GB por versión del modelo. Quiere conservar las últimas 6 versiones. ¿Cuánto cuesta al mes en Standard y en Glacier Instant Retrieval? ¿Cuánto cuesta leer una versión completa desde Glacier IR para reconstruir un índice?

    Ver la solución paso a paso
    • 6 × 205 = 1,230 GB.
    • Standard: 1,230 × 0.023 ≈ US$28 al mes.
    • Glacier IR: 1,230 × 0.004 ≈ US$4.92 al mes.
    • Leer una versión desde Glacier IR: 205 × 0.03 ≈ US$6.15. Si las versiones viejas se leen menos de una vez al mes, conviene: deja la actual en Standard y las otras 5 en Glacier IR.
  8. 8Reto

    Diseña el almacenamiento del log de C01 para un año, con la Ronda: filas crudas 90 días, agregados para siempre. Compara: (a) un objeto por predicción, en Standard; (b) un archivo por minuto. Para cada uno: GB guardados, costo de guardar, de los PUT y de leerlo una vez al mes. ¿Qué regla de ciclo de vida escribes?

    Ver la solución paso a paso
    • Guardado en los dos: 3 GB × 90 = 270 GB, ≈ US$6.2 al mes.
    • (a) PUT: 10 M × 30.4 × 0.005 ÷ 1,000 ≈ US$1,520 al mes. Leer un mes: 304 M × 0.0004 ÷ 1,000 ≈ US$122. Total ≈ US$1,650.
    • (b) PUT: 1,440 × 30.4 = 43,776 al mes, ≈ US$0.22. Leer un mes, 43,776 GET: ≈ US$0.02. Total ≈ US$6.4.
    • La regla: borrar a los 90 días el prefijo de las filas crudas (Expiration, 90 días) y ninguna regla sobre el de los agregados. No vale la pena mover el log a una clase fría: pesa poco y se lee para cada reentrenamiento.
    • En Parquet serían ≈ 0.3–0.6 GB al día: el guardado bajaría a ≈ 27–54 GB, ≈ US$1 al mes.
  9. 9Reto

    El backfill del catálogo de C01: 200 millones de fotos, partidas en 2,000 pedazos iguales. Cada GPU T4 clasifica ≈ 1,000 fotos por segundo, y hay 4. (a) ¿Cuántas fotos lleva cada pedazo? (b) ¿Cuánto tarda todo? (c) ¿Cuánto cuestan los GET? (d) El pedazo 1,234 se cae a la mitad: ¿qué se repite, y qué tiene que cumplir cada pedazo para que repetirlo no haga daño?

    Ver la solución paso a paso
    • (a) 200,000,000 ÷ 2,000 = 100,000 fotos por pedazo.
    • (b) 200 M ÷ (4 × 1,000 por segundo) = 50,000 s ≈ 14 horas.
    • (c) 200 M × 0.0004 ÷ 1,000 = US$80.
    • (d) Solo el pedazo 1,234: el job ve que no tiene archivo de salida y lo vuelve a correr. Para que eso sea seguro, cada pedazo escribe su salida en una llave fija, como .../shard-01234.parquet, y solo al terminar: si se repite, reescribe el mismo objeto con lo mismo. Es idempotente.
12

Lo que sigue

Esencial

What comes next

En la Ronda:

  • M09 · Datos es esta lección hecha diseño: el data lake en Parquet particionado por dt=, cada corrida sobre una partición, los backfills de 180 días, los snapshots con manifest y prefijos que no se pisan, Delta e Iceberg con su time travel, y el feature store con sus dos almacenes.
  • M13 · Nube recorre los bytes para encontrar los costos ocultos: S3 por GB y por request, objetos chicos contra Parquet, las equivalencias entre AWS, Google y Azure (S3, Cloud Storage, Blob; EBS, Persistent Disk; Redshift, BigQuery) y por qué los pesos se leen de S3 por un camino privado y no por internet.
  • M12 · Monitoreo guarda el log de predicciones con retención escalonada (filas 90 días, agregados para siempre) y advierte la trampa de loguear la imagen «por si acaso».
  • M02 · Patrones usa la URL prefirmada en los trabajos asíncronos y los pedazos con salida fija en el batch.

En el Dojo: la estación 1, «Datos y etiquetas», ya copia de S3 las fotos que hay que etiquetar, sin EXIF, a un bucket restringido. La estación 2, «Versionado y linaje», cuando abra, va a armar los snapshots con manifest y a versionarlos con DVC o lakeFS.

En Sensei: la siguiente lección, «Colas y streams», cuenta cómo llegan los eventos al lake, y «Tiempo, hashes e identificadores» explica las huellas de los manifests, el event time y el point-in-time join. Más adelante, las lecciones de regiones y redes en la nube explican por qué cuesta sacar datos de una región.

13

Palabras que vas a oír

Esencial

Words you will hear

Estos son los conceptos que presentó esta lección. Cada uno tiene su tarjeta con la definición completa.

Object storageobject storage · almacenamiento de objetosUn almacén donde cada archivo es un objeto: sus bytes, una llave para encontrarlo y unos metadatos. Se le habla por HTTP (PUT para guardar, GET para leer) y guarda billones de objetos baratos y casi imposibles de perder. Los más conocidos son S3, de la nube de Amazon (AWS), y Cloud Storage, de la de Google.Más

Un objeto no se edita a la mitad: un PUT a la misma llave lo reemplaza entero, y no se le pueden agregar líneas al final. Sí se puede leer un pedazo, con el header Range. Las llaves son texto plano y la «/» es una letra más: las carpetas que enseña la consola son prefijos que varias llaves comparten, y «renombrar una carpeta» es copiar y borrar cada objeto. Los objetos viven en un bucket, tienen durabilidad de once nueves y se cobran por GB-mes y por request, así que millones de objetos chiquitos salen caros. Es donde viven el data lake, los datasets, los pesos de los modelos y los logs. Se distingue del almacenamiento de bloques (un disco de una máquina) y del de archivos (una carpeta compartida).

Analogía. Un guardarropa con boletos: entregas la chamarra, te dan un número y con ese número la recuperas, entera. No puedes pedir que le cosan un botón ahí adentro: te la llevas, la arreglas y la vuelves a dejar. Se rompe en dos cosas: aquí tú eliges el número (la llave), y puedes pedir la lista de todos los números que empiezan igual (un LIST con prefijo), algo que ningún guardarropa hace.

Ejemplo. La foto de Ana se guarda con PUT en la llave fotos/2026/11/06/ana-tenis.jpg del bucket del marketplace. C01 la lee con un GET a esa llave. Cambiar un solo byte obliga a subir los 200 KB otra vez.

Ver en el glosario →

Bucket (de objetos)bucket · object storage bucketEl contenedor donde se guardan los objetos de un object storage, con un nombre propio y sus reglas: quién entra, cuánto dura cada cosa y si guarda versiones viejas. No es el bucket de un histograma, que es un intervalo.Más

En S3, el nombre de cada bucket es, por omisión, único en el mundo (desde marzo de 2026 también se puede crear con un sufijo de tu cuenta y la región, solo tuyo), y el bucket vive en una región. La dirección de un objeto junta el bucket y la llave: en s3://ml-datos/logs/dt=2026-11-06/part-0001.parquet, el bucket es ml-datos. Cada bucket lleva su bucket policy (los permisos), sus reglas de ciclo de vida, su versionado y, si se quiere, Object Lock (versiones que nadie puede borrar antes de una fecha). Lo normal es separar los datos por bucket según quién debe verlos: en C01, las fotos para etiquetar van a un bucket restringido, sin EXIF. Ojo con la palabra: en la lección de percentiles, un bucket es el intervalo de un histograma.

Ejemplo. C01 tiene un bucket de lake (c01-lake) para los logs y los snapshots, y otro restringido para el golden set y las fotos que van a etiquetar. Nadie con permiso solo de leer el lake puede ver esas fotos.

Ver en el glosario →

URL prefirmadapresigned URL · signed URL · URL firmadaUna dirección web que trae escrito adentro, en su query, un permiso firmado: hacer una sola operación (subir o bajar) sobre un solo archivo de un bucket, durante un rato corto que elige el servidor que la firma, por ejemplo 15 minutos. Quien la tenga la puede usar sin tener las claves del almacén.Más

La firma la calcula un servidor que sí tiene permiso, con su clave secreta, sin llamar al object storage: es una cuenta local. Cubre el método (PUT o GET), el bucket, la llave, la hora y cuántos segundos vale, y a veces headers como el Content-Type. Al recibir la request, S3 recalcula la firma: si algo cambió, responde 403; si venció, también. Además revisa que quien firmó todavía tenga permiso. Como el permiso viaja en la URL, la request no lleva header Authorization. En S3 dura como mucho 7 días, y menos si se firmó con credenciales temporales. Sirve para que una app o una cámara suban archivos directo al bucket, sin que los bytes crucen la API, y para que un cliente baje un resultado privado. Es como un boleto: si se filtra, sirve hasta que vence; por eso se firma para una llave, con vencimiento corto, y no se escribe en los logs. Google la llama signed URL.

Analogía. Un pase de estacionamiento que te da la caseta: abre una sola pluma, una vez, durante 15 minutos, y no dice tu nombre. Se rompe en que el pase de verdad se pierde al usarlo; una URL prefirmada se puede usar varias veces mientras no venza.

Ejemplo. En C02, la API firma para la caja de cada sitio una URL de PUT a la llave sitio-07/clips/e-31.mp4, con X-Amz-Expires=900: 15 minutos. La caja sube el clip directo a S3; si tarda 20 minutos, recibe 403 y pide otra.

Ver en el glosario →

DurabilidaddurabilityLa probabilidad de que un dato que guardaste siga ahí, intacto, después de un año. S3 está diseñado para once nueves (99.999999999 %): con 10 millones de objetos, perderías uno cada 10,000 años.Más

En S3 Standard se logra guardando cada objeto repartido en muchos discos de al menos tres zonas de disponibilidad (centros de datos separados), con huellas que detectan si un bit se dañó y reparando rápido cuando un disco muere. No es lo mismo que la disponibilidad: esa mide si el servicio contesta ahora (S3 Standard está diseñado para 99.99 %, ≈ 53 minutos al año de fallas, aunque su contrato promete 99.9 % al mes). Un bucket puede no contestar un rato sin perder nada, y al revés: con disponibilidad perfecta, un DELETE tuyo borra el objeto para siempre. La durabilidad protege del hardware, no de los errores humanos; para eso están el versionado del bucket, Object Lock y las copias en otra cuenta o región. Las copias tienen que fallar por separado: tres discos con la misma fuente de luz no valen como tres.

Ejemplo. Las fotos de un año del marketplace son 3,650 millones. Con 10⁻¹¹ de probabilidad de perder cada una al año, esperarías perder 0.0365 al año: una cada ≈ 27 años.

Ver en el glosario →

Clase de almacenamientostorage classCada una de las maneras de guardar un objeto en el mismo object storage, más caras o más baratas según qué tan seguido y qué tan rápido lo vas a leer. En S3 van de Standard (US$0.023 por GB al mes, precio de lista del norte de Virginia en 2026) a Glacier Deep Archive (≈ US$0.001), con la misma durabilidad.Más

Lo que cambia es el trato: cuánto cuesta guardar, cuánto cuesta leer y cuánto hay que esperar. Standard se lee al instante, sin cargo por GB. Standard-IA (Infrequent Access) cuesta casi la mitad, pero cobra US$0.01 por GB leído, un mínimo de 30 días y un mínimo de 128 KB por objeto. Glacier Instant Retrieval cuesta ≈ US$0.004 y cobra US$0.03 por GB leído, con mínimos de 90 días y 128 KB por objeto. Glacier Flexible Retrieval y Deep Archive son para archivo: leerlos tarda de minutos a horas. Mover un objeto de clase es una request que se cobra por objeto, así que con millones de objetos chicos mover puede costar más de lo que ahorra. Intelligent-Tiering mueve cada objeto solo, según su uso, por una cuota pequeña. Las mueven las reglas de ciclo de vida. Google tiene la misma escalera: Standard, Nearline, Coldline y Archive.

Ejemplo. La copia de los vectores de C07 pesa ≈ 205 GB por versión: ≈ US$4.70 al mes en Standard y ≈ US$0.82 en Glacier Instant Retrieval. Leer una versión entera desde Glacier IR para reconstruir el índice cuesta ≈ US$6.15.

Ver en el glosario →

Regla de ciclo de vidalifecycle rule · lifecycle policyUna regla de un bucket que mueve o borra objetos según su edad, sin que ningún programa tuyo lo haga: «a los 30 días, pásalo a una clase más barata, como Glacier; a los 365, bórralo».Más

Tiene dos acciones: mover (transition) a una clase más barata y borrar (expiration). Cada regla aplica a un prefijo o a los objetos con una etiqueta, así que cada parte del bucket puede tener la suya, y S3 las revisa más o menos una vez al día. Es la manera de cumplir una retención: los logs crudos de C01 se borran a los 90 días con una regla. Cuidados: cada transición se cobra por objeto (con millones de fotos chicas puede comerse el ahorro), las clases frías cobran un mínimo de días, y una regla mal escrita borra en silencio lo que no debía. Con el versionado prendido, borrar deja la versión vieja, y hace falta otra regla para las versiones no actuales.

Ejemplo. El bucket de fotos del marketplace: 30 días en Standard, después Glacier Instant Retrieval, borrado al año. Al mes cuesta ≈ US$10,140 en vez de ≈ US$16,790, y US$6,080 de eso son las 304 millones de transiciones.

Ver en el glosario →

Almacenamiento de bloquesblock storageUn disco en crudo, visto como una fila de bloques numerados, sobre el que la máquina pone su propio sistema de archivos. En la nube es un disco de red pegado a una sola máquina, como EBS en AWS.Más

Se puede leer y escribir a la mitad de un archivo, con latencias de milisegundos o menos, así que ahí van el disco con el que arranca la máquina y las bases de datos. A cambio, normalmente lo usa una sola máquina a la vez, vive en una sola zona de disponibilidad y se paga por los GB reservados, se usen o no: un gp3 de EBS cuesta ≈ US$0.08 por GB-mes, unas 3.5 veces S3 Standard, y da de base 3,000 IOPS y 125 MiB/s. Las otras dos maneras de guardar en la nube son el almacenamiento de archivos (una carpeta compartida por NFS que montan muchas máquinas, como EFS, ≈ US$0.30 por GB-mes) y el de objetos. El disco NVMe local de una máquina (instance store) es más rápido, pero se pierde con ella: sirve de caché, nunca de único lugar.

Ejemplo. C07 guarda en un disco gp3 de cada máquina los 51.2 GB de vectores que lee en cada búsqueda, servidos desde el page cache. La copia que no se puede perder va a S3.

Ver en el glosario →

Data lakedata lakeUn object storage donde llegan todos los datos de una empresa como archivos, crudos y procesados, para que cualquier herramienta los lea. Es la fuente de verdad de lo que se prepara sin que nadie espere: de ahí salen los datasets de entrenamiento y los recálculos del pasado.Más

Suele tener zonas, cada una con su prefijo: crudo (tal como llegó, por ejemplo JSON lines), procesado (limpio, en Parquet) y curado (tablas listas, como un dataset o los agregados diarios). Los datos se organizan en particiones por fecha para leer solo lo necesario. Lo leen Spark, DuckDB, Athena o un script de Python. Es barato y no obliga a nada: cualquiera escribe cualquier archivo, y el esquema lo descubre quien lee. Sin reglas se vuelve un pantano. Le faltan las transacciones de un warehouse; un lakehouse se las agrega encima.

Ejemplo. El log de predicciones de C01 llega al lake cada pocos minutos, en Parquet particionado por dt=: ≈ 0.3 a 0.6 GB al día. De ahí salen el monitoreo de drift y el dataset de cada reentrenamiento.

Ver en el glosario →

Data warehousedata warehouseUna base de datos hecha para analizar: guarda las tablas por columnas y responde consultas en SQL (el lenguaje para pedirle datos a una tabla) sobre millones de filas repartiendo la consulta entre muchas máquinas. Los más usados son BigQuery, Snowflake y Redshift.Más

Es la respuesta al lado OLAP: consultas que tocan muchísimas filas pero pocas columnas. Guarda cada columna junta y comprimida, así que leer tres columnas de treinta cuesta una fracción. Separa el almacenamiento del cálculo: guardas mucho barato y rentas máquinas solo mientras corre la consulta. Algunos cobran por bytes leídos (BigQuery, en su modo por consulta, US$6.25 por TiB en 2026), y ahí las particiones y elegir columnas se vuelven dinero. Frente a un data lake da tablas con transacciones, esquema revisado al escribir y SQL rápido, a cambio de costar más y de que hay que cargarle los datos. Muchas empresas tienen los dos.

Ejemplo. Un analista de C01 pregunta cuántas predicciones hubo por categoría en octubre y cuántas aceptó la gente. Con particiones por día y tres columnas, la consulta lee unos pocos GB en vez del año entero.

Ver en el glosario →

OLTP y OLAPOLTP vs OLAP · online transaction / analytical processingLas dos maneras de usar datos. OLTP: millones de operaciones chiquitas, cada una sobre pocas filas completas, en milisegundos (guardar una publicación). OLAP: pocas consultas grandes, sobre millones de filas pero pocas columnas (cuántas ventas por categoría en un mes).Más

Piden almacenes distintos. Para OLTP conviene guardar cada fila junta, con índices y transacciones: es una base relacional como Postgres. Para OLAP conviene guardar cada columna junta y comprimida, como Parquet o un data warehouse. Correr analítica pesada en la base de OLTP del producto la vuelve lenta para los usuarios; por eso los datos se copian a un lake o a un warehouse para analizarlos.

Ejemplo. OLTP: «lee la publicación 8f3a», una fila, en 2 ms. OLAP: «predicciones por categoría en octubre», 300 millones de filas y 3 columnas, en unos segundos.

Ver en el glosario →

Lakehouselakehouse · open table formatUn data lake con tablas de verdad: los datos siguen como archivos Parquet en el object storage, y un registro aparte dice qué archivos forman la tabla en cada versión. Así cada escritura pasa completa o no pasa, se pueden corregir filas y se puede leer una versión vieja. Los formatos más usados son Delta Lake, Apache Iceberg y Apache Hudi.Más

Escribir es subir archivos nuevos y, al final, agregar al registro una entrada con la versión nueva: hasta entonces nadie los ve, así que cada escritura pasa completa o no pasa. Los archivos nunca se editan: borrar filas reescribe un archivo y la versión nueva deja de apuntar al viejo. Por eso se puede leer la tabla como estaba en una versión o una fecha (time travel) sin copiar datos. El time travel dura lo que dura la limpieza: en Delta, por omisión, el historial dura 30 días y los archivos viejos se pueden borrar pasados 7; en Iceberg, la limpieza borra snapshots de más de 5 días. Lo que tiene que durar se marca aparte. Delta nació en Databricks, Iceberg en Netflix y Hudi en Uber.

Ejemplo. El log de predicciones de C01 como tabla Iceberg: el job de la noche agrega los archivos del día en una sola transacción, y una solicitud de borrado quita las filas de una persona creando una versión nueva. El snapshot del dataset de septiembre se marca con una retención de 365 días.

Ver en el glosario →

Partición (de datos)partition · data partitioningCada grupo en que se divide una tabla grande según el valor de una columna, casi siempre la fecha, con ese valor escrito en la llave: dt=2026-11-06/. Así una consulta o un job lee solo los días que necesita y no el año.Más

La convención columna=valor la entienden Spark, Athena, DuckDB y los warehouses: si la consulta filtra por fecha, el motor lista solo esos prefijos (partition pruning). También hace que cada corrida diaria escriba solo su partición, así que un error se arregla reescribiendo un día, y que un backfill sea la misma corrida repetida por cada día viejo. Se puede partir por más de una columna (dt=…/model_version=v13/). Reglas: partir por lo que más se filtra, no hacer particiones tan finas que dejen millones de archivos chiquitos (se buscan de ≈ 100 MB a 1 GB) y decidir si la fecha es la de llegada o la del evento (event time). No es la partición de un tópico de Kafka (partición del tópico), que reparte mensajes entre consumidores.

Ejemplo. Con el log de C01 en Parquet, ≈ 0.5 GB al día, una consulta de los últimos 7 días lee 3.5 GB con particiones y 182.5 GB sin ellas, si la tabla guarda un año: ≈ 52 veces más.

Ver en el glosario →

SnapshotsnapshotUna foto fija de los datos en un momento: lo que había entonces, que ya no cambia aunque la tabla siga creciendo. Hace repetible un entrenamiento: el modelo guarda con qué snapshot se entrenó.Más

En un lakehouse, cada escritura crea un snapshot, y el time travel lee uno viejo; dura hasta que la limpieza lo borra, así que el de un modelo en producción se marca con su propia retención. Otra forma, la de C01: un manifest, un archivo que lista la llave de cada foto, su etiqueta y su hash, en un prefijo que nunca se reescribe; no copia fotos y pesa megabytes. Un snapshot también debe respetar la retención: si alguien pide borrar su foto, hay que poder encontrarla en todos. La palabra se usa igual para otras cosas: un snapshot de EBS es una copia de un disco. Llevar la cuenta de qué snapshot, qué código y qué contenedor produjeron cada modelo es el versionado de datos y el linaje.

Ejemplo. El modelo de C01 de septiembre apunta a datasets/ds-2026-09-01/, con la huella SHA-256 del manifest. Seis meses después, alguien vuelve a armar exactamente el mismo dataset y repite el entrenamiento.

Ver en el glosario →

Retencióndata retentionCuánto tiempo se conserva cada dato antes de borrarlo. La deciden el costo, la ley y la privacidad, y lo que el ML necesita para reentrenar y comparar modelos.Más

Se decide al crear cada artefacto, no después, y se cumple con reglas de ciclo de vida (en S3), con un TTL o con un job de purga (en una tabla). La retención real es la del artefacto que más dura: si el bucket borra a los 90 días pero la foto sigue en un snapshot, en un respaldo en otra región o en un CSV en una laptop, sigue existiendo. Un dataset no puede ser la puerta trasera de la retención. Lo común es una retención escalonada: filas crudas por semanas o meses, agregados (que no traen datos de nadie) para siempre.

Ejemplo. C01: logs de predicción, 90 días; copias para etiquetar, 90 días; agregados diarios, para siempre; golden set y snapshots, sin caducar, pero borrados por hash cuando alguien lo pide. Si el golden set caducara, ya no podrías comparar modelos de meses distintos.

Ver en el glosario →

Feature storefeature storeUn sistema que guarda las features de un modelo (los números que recibe, como «compras de esta tarjeta en 24 h») con una sola definición para entrenar y para servir: un almacén offline con toda la historia y uno online con el valor de ahora, que responde en milisegundos.Más

El offline store guarda todas las versiones de cada valor con su hora, en el lake o el warehouse: de ahí salen los datasets, tomando para cada ejemplo el valor de justo antes de su momento (point-in-time correctness), para no aprender del futuro (leakage). El online store guarda solo el último valor de cada usuario o tarjeta en una base base llave-valor como Redis. Un job copia los valores nuevos del uno al otro (materializar). Como los dos salen del mismo código, se evita el training-serving skew. Herramientas: Feast (de código abierto), Tecton (desde 2025, parte de Databricks) y los de Databricks, SageMaker y Vertex AI. En visión pura, como C01, casi nunca hace falta: la feature es la imagen.

Ejemplo. C09 usa «compras de la tarjeta en las últimas 24 h». Para entrenar, una transacción de las 10:05 toma el valor de las 10:00 del offline store; en producción, el servicio lee el valor actual del online store en ≈ 1 ms.

Ver en el glosario →

BackfillbackfillRecalcular el pasado: correr un cálculo nuevo sobre datos viejos, como una feature nueva sobre los últimos 90 días o un modelo sobre todo el catálogo que ya existía.Más

Con los datos en particiones por fecha, un backfill es la corrida diaria repetida una vez por cada día viejo, varias a la vez. Para que se pueda reanudar, cada corrida escribe solo su partición (o su pedazo) en una llave fija, de modo que repetirla da lo mismo (idempotencia). Debe usar el mismo código que la corrida diaria, o la historia y el presente vuelven a ser números distintos, y escribir en el almacén offline, no en el online. Es un trabajo de throughput, no de latencia: va por el camino offline, en tandas y sin tocar el servicio.

Ejemplo. Una feature nueva con 90 particiones de ≈ 20 minutos son 30 h en serie y ≈ 3 h con 10 a la vez. El backfill de C01, clasificar 200 millones de fotos viejas en ≈ 2,000 pedazos, tarda ≈ 14 h con 4 GPUs y paga ≈ US$80 de GET a S3.

Ver en el glosario →

14

Chequeo

Esencial

Check

Intenta responder en tu cabeza antes de abrir cada respuesta.

  1. 1¿Por qué no se puede «editar a la mitad» un objeto de S3, y qué haces si necesitas cambiarlo?Ver respuesta

    Porque solo guarda objetos enteros: un PUT a la misma llave reemplaza todo, y esa sencillez le deja repartir billones de objetos sin coordinar escrituras. Lo bajas, lo cambias y lo subes entero; para editar filas, Delta o Iceberg.

  2. 2¿Qué permite una URL prefirmada y quién la firma?Ver respuesta

    Una operación (PUT o GET) sobre una llave, por un rato. La firma con su clave secreta un servidor con permiso, y quien tenga la URL la usa hasta que vence.

  3. 3Once nueves de durabilidad, ¿quieren decir que tus datos están a salvo?Ver respuesta

    De los discos rotos, sí: perderías uno de 10 millones cada 10,000 años. De un DELETE, una regla mal escrita o un prefijo equivocado, no: para eso, versionado, Object Lock y permisos.

  4. 4¿Por qué un ciclo de vida que mueve millones de fotos chicas a una clase fría puede ahorrar poco?Ver respuesta

    Porque cada transición se cobra por objeto: mover 304 millones de fotos al mes a Glacier IR cuesta ≈ US$6,080, casi la mitad del ahorro en GB; a Deep Archive, más que todo el ahorro.

  5. 5¿Para qué sirve particionar un log por dt=?Ver respuesta

    Para leer solo los días necesarios: una semana son 3.5 GB en vez de los 182.5 del año. Y para que cada corrida reescriba solo su día si algo sale mal.

  6. 6¿Qué le agrega un lakehouse a un data lake?Ver respuesta

    Un registro de qué archivos forman la tabla en cada versión. Con él, cada escritura pasa completa o no pasa, se corrigen filas y se lee una versión vieja (time travel), sin copiar datos.

Sigue · 30Colas y streams: mensajes que esperanDatos y almacenamiento Léelo en la RondaM09 · Datos y featuresLo que acabas de leer, con el ojo del entrevistador. ← 28 · Bases de datos: tablas, SQL y llave-valor