Modelo mental
S3 es una tabla hash gigante de cadena a bytes. La clave es el nombre completo del objeto, el valor son sus bytes, y no hay nada más.
Todo lo que sorprende de S3 sale de tomarse esa frase en serio:
No hay carpetas. facturas/2026/09/4711.pdf no está “dentro” de nada: es un
nombre que contiene barras. La consola las dibuja como directorios porque es
cómodo, pero no existen. Por eso no puedes renombrar una carpeta —hay que
copiar cada objeto y borrar el original— y por eso listar “una carpeta” con
muchos objetos es caro.
No se modifica, se reemplaza. No hay append, no hay escribir en el byte 1 000. Cambiar una línea de un CSV de 2 GB es subir 2 GB otra vez. Si tu caso de uso es escribir poco y a menudo sobre el mismo objeto, el problema no es que S3 vaya lento: es que estás usando la herramienta equivocada.
La consistencia ya no es un problema. S3 da lectura tras escritura fuerte desde 2020. Los artículos que hablan de “consistencia eventual en S3” y de esperar unos segundos antes de leer están desactualizados.
El nombre de la clave es tu plan de capacidad
Esta es la parte que separa a quien ha operado S3 a escala de quien no.
Cada prefijo particionado sostiene al menos 3 500 escrituras y 5 500 lecturas por segundo, y —esto es lo bueno— no hay límite en el número de prefijos de un bucket. Diez prefijos son 55 000 lecturas por segundo.
Así que el rendimiento de S3 no se pide con un ticket: se diseña nombrando.
Si todas tus claves empiezan por uploads/2026-09-06/, todo el tráfico del día
cae en el mismo prefijo. Si empiezan por un identificador con buena
distribución, se reparte solo.
Y un detalle operativo importante: el escalado es gradual, no instantáneo. Cuando subes el ritmo de golpe, S3 responde con 503 (Slow Down) mientras reparticiona. No es un error de tu código; es S3 pidiendo tiempo. Reintentar con backoff es la respuesta correcta.
Cómo te factura
Cuatro conceptos, y el que sorprende no es el almacenamiento:
| Concepto | Precio aproximado |
|---|---|
| Almacenamiento estándar | ~0,023 USD / GB-mes |
| Peticiones PUT, COPY, POST, LIST | ~0,005 USD / 1 000 |
| Peticiones GET y similares | ~0,0004 USD / 1 000 |
| Transferencia de salida a internet | el que se lleva la factura |
Guardar es barato. Sacar es caro. Un terabyte almacenado cuesta unos 23 dólares al mes; ese mismo terabyte servido a internet cuesta varias veces más. Por eso poner CloudFront delante de un bucket con tráfico no es solo una optimización de latencia: es una decisión de coste.
Dos trampas de facturación concretas:
LIST cuesta como una escritura, no como una lectura — un orden de magnitud
más. Un proceso que lista un bucket grande en bucle es una factura sorpresa
clásica.
Las clases baratas tienen letra pequeña. Glacier y compañía cobran por recuperar y tienen mínimos de permanencia; mover a Glacier objetos que vas a leer el mes que viene sale más caro que dejarlos donde estaban.
Cuándo NO usarlo
- Necesitas modificar partes de un archivo. No hay append ni escritura parcial. Eso es EFS, o una base de datos.
- Necesitas latencia de milisegundos. S3 da del orden de 100–200 ms para objetos pequeños. Es almacenamiento, no una caché.
- Necesitas consultar por contenido. Buscar “todos los pedidos de septiembre con importe mayor que 500” no se hace listando un bucket. Los metadatos van a una base de datos y S3 guarda los bytes.
- Los objetos son diminutos y numerosísimos. Millones de objetos de 200 bytes pagan mucho más en peticiones que en almacenamiento. Agrúpalos.
- Necesitas semántica de sistema de ficheros —bloqueos, renombrar directorios, permisos POSIX—. Eso es EFS o FSx.
Errores comunes
Poner el bucket público para servir archivos. La respuesta casi siempre es CloudFront con OAC, o una URL prefirmada. Un bucket público es una fuga de datos esperando a que alguien suba el archivo equivocado.
Hacer que el archivo pase por tu Lambda. Es el error más caro en serverless: API Gateway admite 10 MB y una Lambda síncrona 6 MB, así que el techo real son 6 MB, y encima pagas la duración de la función mientras mueve bytes. Para eso están las URL prefirmadas.
Diseñar claves con prefijo temporal. 2026-09-06/... concentra todo el
tráfico del día en un prefijo. Funciona hasta que deja de funcionar, y entonces
la solución es renombrar millones de objetos.
Tratar los 503 como un bug. Durante el reparticionado S3 devuelve Slow Down. Reintenta con backoff y jitter.
Listar para comprobar si algo existe. HeadObject sobre la clave concreta
es una petición barata; ListObjectsV2 sobre un prefijo grande, no.
Olvidar el ciclo de vida. Sin reglas, las subidas multipart abortadas se quedan como partes huérfanas que ocupan y se facturan sin aparecer en la lista de objetos. Es la línea de la factura que nadie sabe explicar.
Fuentes
Rendimiento por prefijo, ausencia de límite en el número de prefijos, escalado gradual y respuestas 503 Slow Down: Best practices design patterns: optimizing Amazon S3 performance. Tamaño máximo de objeto y de parte, número de partes, buckets por cuenta, política de bucket, notificaciones, reglas de ciclo de vida y replicación, etiquetas y access points: Amazon S3 endpoints and quotas. Los importes proceden de la página de precios de AWS, que se renderiza dinámicamente y no pudo citarse literalmente: trátalos como orden de magnitud.