El bucket cuesta 23 dólares por terabyte y mes. Ese número es la razón por la que nadie mira S3, y es también el número menos interesante de todo el servicio. Lo que encontramos en cuentas reales es una línea de almacenamiento inflada por objetos que se bajaron de clase demasiado rápido, versiones que nadie sabe que existen y subidas que nunca terminaron, junto a una línea de transferencia que muchas veces es mayor que el almacenamiento y que aparece en la factura bajo un epígrafe completamente distinto.
Almacenamiento y transferencia son un solo problema, porque las decisiones que dan forma a uno dan forma al otro. Una regla de ciclo de vida que mueve diez millones de objetos pequeños a Glacier es un evento de peticiones antes que un ahorro de almacenamiento. Una subred privada sin gateway endpoint paga cargos de NAT para hablar con un bucket de su misma región. Esta es la auditoría que hacemos.
Las clases de almacenamiento cobran por tiempo y por tamaño, no solo por bytes
Cada clase más fría de S3 lleva dos penalizaciones que el precio por gigabyte esconde.
La primera es la duración mínima facturable. Standard-IA y One Zone-IA facturan un mínimo de 30 días por objeto, Glacier Instant Retrieval 90, Glacier Flexible Retrieval 90 y Deep Archive 180. Si borras o transicionas el objeto antes, pagas el resto igualmente. Una política que baja de clase el día 1 y caduca el día 45 paga penalización en cada objeto, y cuantos más objetos, peor.
La segunda es el tamaño mínimo facturable por objeto. Las clases de acceso infrecuente y las de Glacier facturan los objetos pequeños como si midieran 128 KB. Si tu bucket son cuarenta millones de miniaturas de 12 KB de media, moverlas a Standard-IA multiplica por diez el volumen facturado. Esa transición sube la factura en lugar de bajarla, y lo hemos visto pasar.
De ahí la regla: las clases frías son para objetos grandes con vidas largas. Antes de escribir ninguna regla de ciclo de vida, saca de S3 Storage Lens el número de objetos y el tamaño medio. Si la media está por debajo de unos 128 KB, la respuesta es Standard, o es un cambio de empaquetado para que los objetos dejen de ser diminutos.
Intelligent-Tiering es correcto hasta que la cuota de monitorización se lo come
Intelligent-Tiering resuelve el problema de adivinar: mueve objetos entre niveles de acceso según el uso real, sin cargos de recuperación ni penalización por borrado anticipado entre los niveles frecuente, infrecuente e instantáneo. Para un bucket con un patrón de lectura impredecible suele ser el valor por defecto correcto.
El matiz es una pequeña cuota mensual de monitorización y automatización por objeto. Para cien mil objetos grandes es ruido. Para ochenta millones de objetos diminutos puede superar lo que habrías pagado en Standard. Los objetos por debajo de 128 KB ni se monitorizan ni se mueven de nivel, así que estás pagando atención sobre la mitad equivocada del bucket. Haz primero la cuenta del número de objetos: el punto de cruce es una división, no una opinión.
Las transiciones cuestan dinero por petición
Las transiciones de ciclo de vida se facturan por cada mil objetos, y las clases de Glacier cuestan bastante más por transición que las de acceso infrecuente. Mover cuarenta millones de objetos es un cargo real y puntual que aparece el mes en que activas la regla, y va a asustar a alguien. Modélalo antes de activarla, y no escribas nunca una configuración que transicione por varias clases en secuencia: cada salto vuelve a facturar.
Lo que se va acumulando
- Versiones no actuales. El versionado está activo, nadie puso caducidad y el bucket guarda en silencio todas las revisiones de todos los objetos desde el día en que se activó. En buckets con mucha escritura, el volumen no actual suele ser mayor que el actual. Añade una regla
NoncurrentVersionExpiration. - Marcadores de borrado sin versiones detrás. Borrar en un bucket versionado crea un marcador, no un borrado. Los marcadores huérfanos cuestan poco, pero destrozan el rendimiento del listado y ocultan el tamaño real.
ExpiredObjectDeleteMarkerlos limpia. - Cargas multiparte incompletas. Una subida fallida de 5 GB deja partes que facturan como almacenamiento y que no aparecen en ningún listado. Todos los buckets deberían tener una regla
AbortIncompleteMultipartUploada 7 días. Es el hallazgo más común que tenemos y es una línea de Terraform. - Coste de peticiones en cargas de objetos pequeños. Un millón de GET contra un bucket de objetos de 5 KB cuesta más que guardarlos. Si un servicio lee constantemente los mismos objetos pequeños, la solución es una caché, no una clase de almacenamiento.
- Replicación que olvidaste. La replicación entre regiones paga la transferencia, el almacenamiento en destino y las peticiones, para siempre, por cada objeto nuevo. Revisa qué se replica y por qué.
- Logs escritos en el bucket que se está registrando. Los logs de acceso al servidor escritos en el mismo bucket generan objetos que generan logs. Mándalos a otro sitio con una caducidad.
Luego la transferencia, en el orden en que muerde
La entrada es gratis. Todo lo demás es cuestión de dónde está la frontera, y son las mismas fronteras que provocan los problemas de diseño de los errores de red en AWS que cuestan dinero.
- La salida a internet es la tarifa titular, con tramos a la baja por volumen y una franquicia mensual gratuita. Poner CloudFront delante de un bucket suele bajarla dos veces: la tarifa de salida de la CDN es menor y las lecturas de origen de S3 hacia CloudFront son gratuitas.
- El procesamiento de datos de la NAT gateway se cobra por gigabyte además del precio por hora, en ambos sentidos, y se aplica a tráfico que nunca sale de AWS. Una subred privada que habla con S3 o DynamoDB a través de la NAT está pagando por nada. Los gateway endpoints de VPC para S3 y DynamoDB son gratuitos y sacan ese tráfico del camino de la NAT por completo. Si arreglas una sola cosa este mes, que sea esta.
- Los interface endpoints (PrivateLink) para el resto de servicios cuestan una tarifa por hora por endpoint y zona más un cargo por gigabyte, y aun así suelen salir más baratos que la NAT para tráfico de mucho volumen, con una frontera de seguridad real de propina.
- El tráfico entre zonas de disponibilidad dentro de una región se factura en los dos sentidos. En un clúster de Kubernetes multizona con servicios que ignoran la topología, la mayor parte del tráfico entre pods cruza una zona, el efecto que describimos en lo que cuesta EKS.
- La transferencia entre regiones por replicación, aplicaciones parlanchinas repartidas y copias de seguridad. Suele ser un hallazgo de arquitectura, no una palanca.
Qué hacer esta semana
Abre S3 Storage Lens en la cuenta, ordena los buckets por bytes en versiones no actuales y por bytes en cargas multiparte incompletas, y quédate con los tres primeros de cada lista. Después enumera todas las VPC de la cuenta y comprueba cuáles tienen gateway endpoint para S3. Las dos listas se sacan en veinte minutos y las dos son más largas de lo que nadie espera. Hacemos exactamente esto en la fase de costes de un proyecto cloud, junto a las cinco capas de una factura de AWS.