¿Buscas nuestro logo?
Aquí te dejamos una copia, pero si necesitas más opciones o quieres conocer más, visita nuestra área de marca.
¿Buscas nuestro logo?
Aquí te dejamos una copia, pero si necesitas más opciones o quieres conocer más, visita nuestra área de marca.
dev
Sergio David Morel Hace 19 minutos Cargando comentarios…
En base a nuestra experiencia en entornos cloud, el acceso al almacenamiento de objetos como AWS S3 se resuelve habitualmente de tres formas: mediante llamadas directas a la API (AWS CLI), montando el bucket como un filesystem local con (s3fs-fuse) o a través del nuevo cliente nativo de Amazon, AWS S3 Files.
En este artículo presentamos un benchmark automatizado con Terraform/OpenTofu para comparar el rendimiento real de estas tres aproximaciones, midiendo operaciones secuenciales de lectura y escritura sobre diferentes tamaños de archivo.
Analizaremos las IOPS, latencia y throughput de cada método, concluyendo que no existe una solución universalmente superior, sino que la elección óptima depende de las características de la carga de trabajo.
El entorno de pruebas se ha definido íntegramente como código Terraform y consta de los siguientes elementos:

Cada componente cumple un rol específico:
El benchmark sigue un diseño estructurado para garantizar la comparabilidad de resultados entre ambas aproximaciones:
| Parámetro | Valor |
|---|---|
| Región | eu-south-2 (Spain) |
| Instancia | t3.micro (2 vCPU, 1 GiB RAM) |
| SO | Amazon Linux 2023 |
| Tamaños de archivo | 1 KB, 100 KB, 1 MB, 10 MB, 100 MB |
| Archivos por tamaño | 10 |
| Método de generación | /dev/urandom (datos no comprimibles) |
Para AWS CLI se miden cinco operaciones secuenciales:
Para s3fs-fuse y S3 Files se utilizan benchmarks con fio (v3.32) con I/O directo (libaio, direct=1), midiendo:
La métrica principal es el tiempo total en milisegundos para completar cada operación (10 archivos) en CLI, complementada con IOPS y throughput en MB/s para los mounts FUSE/S3 Files.
Todo el ciclo de vida: crear bucket, lanzar instancia, instalar dependencias, compilar s3fs-fuse desde fuente, montar S3 Files, ejecutar las pruebas y generar el CSV de resultados… se orquesta desde un único script que se ejecuta como user-data en el arranque de la instancia.
La infraestructura se encuentra definida como código con Terraform usando dos módulos reutilizables:
El enfoque nativo utiliza AWS CLI v2 (aws-cli/2.33.15), que internamente realiza llamadas a la API REST de S3. Cada invocación de aws s3 cp implica:
# UPLOAD -- un archivo individual
aws s3 cp "test_10MB_1.dat" "s3://my-bucket/native/test_10MB_1.dat" --no-progress
# LIST -- listado recursivo
aws s3 ls "s3://my-bucket/native/" --recursive
# HEAD -- metadatos de un objeto
aws s3api head-object --bucket "my-bucket" --key "native/test_10MB_1.dat"
Para las operaciones de UPLOAD y DOWNLOAD se itera sobre los 10 archivos secuencialmente, midiendo el tiempo total del bloque completo.
s3fs-fuse (v1.97, compilado desde github.com/s3fs-fuse/s3fs-fuse) monta el bucket S3 como un sistema de archivos FUSE (Filesystem in Userspace), permitiendo acceder a los objetos mediante operaciones POSIX estándar (cp, ls, stat, rm):
# Compilación desde fuente (Amazon Linux 2023)
dnf install -y fuse fuse3 fuse3-devel fuse-devel libcurl-devel \
libxml2-devel gcc-c++ make openssl-devel autoconf automake libtool git
cd /tmp && git clone https://github.com/s3fs-fuse/s3fs-fuse.git
cd s3fs-fuse && ./autogen.sh && ./configure
make -j$(nproc) && make install && ldconfig
# Montaje con credenciales temporales del IAM Role
eval $(aws configure export-credentials --format env)
s3fs "my-bucket" "/mnt/s3" \
-o access_key_id="$AWS_ACCESS_KEY_ID" \
-o secret_access_key="$AWS_SECRET_ACCESS_KEY" \
-o session_token="$AWS_SESSION_TOKEN" \
-o use_cache=/tmp \
-o use_path_request_style \
-o enable_noobj_cache \
-o sigv2
Nota: s3fs-fuse no está disponible como paquete para Amazon Linux 2023, por lo que es necesario compilarlo desde el código fuente en el arranque de la instancia.
Los parámetros de montaje son clave para el rendimiento:
| Opción | Función |
|---|---|
| use_cache=/tmp | Almacena archivos descargados en RAM (tmpfs), evitando re-descargas repetidas. |
| enable_noobj_cache | Cachea la no-existencia de objetos para reducir llamadas HeadObject. |
| use_path_request_style | Usa path-style URLs (/bucket/key) en lugar de virtual-hosted. |
| sigv2 | Fuerza la firma de API v2, reduciendo overhead de autenticación. |
El mecanismo interno de s3fs-fuse traduce cada llamada POSIX a la API correspondiente de S3. Por ejemplo, un cp a un archivo nuevo se traduce en un PUT Object, mientras que un stat se resuelve como HEAD Object.
AWS S3 Files es el servicio nativo de Amazon para montar buckets S3 como filesystem, disponible como mount.s3files en Amazon Linux 2023. A diferencia de s3fs-fuse, S3 Files no conecta la instancia EC2 directamente a S3. El flujo de datos real es el siguiente:

La instancia EC2 monta un filesystem mediante el protocolo NFS desde una instancia EFS que actúa como caché de alto rendimiento. Esta caché se encarga de servir una copia local de ficheros y de sincronizar los cambios con el bucket S3.
# Instalación (Amazon Linux 2023)
dnf install -y amazon-efs-utils
# Montaje -- OpenTofu crea el File System y Mount Target en la VPC.
# El benchmark script monta usando el ID del File System:
mount_file_id=$(cat /root/benchmark-results/s3files_fs_id)
/usr/sbin/mount.s3files "${mount_file_id}" /root/s3files-mount
# Verificación del montaje
mount | grep s3files
# fs-0bbbd1d66142be171 on /root/s3files-mount type s3files ...
Características clave de S3 Files:
| Característica | S3 Files | s3fs-fuse |
|---|---|---|
| Arquitectura | NFS client → Mount Target (VPC) → File System → S3 | FUSE → HTTPS → S3 API |
| Protocolo | NFSv4.1 o 4.2 (a Mount Target en VPC) | FUSE (estas operaciones POSIX → S3 REST API) |
| Ruta de red | EC2 → VPC local (Mount Target) → S3 (gestionado por AWS) | EC2 → Internet/VPC endpoint → S3 REST API |
| Caché de lectura | Caché EFS (Fast Path para archivos < 128 KB) | Cache local en RAM (use_cache=/tmp, tmpfs) |
| Consistencia | Strong read-after-write por defecto | Eventual con enable_noobj_cache |
| Credenciales | IAM Role automático (resuelto por Mount Target) | Inyección manual de credenciales temporales |
S3 Files está diseñado para ofrecer consistencia fuerte y operativa simplificada, pero su rendimiento puede diferir significativamente del de s3fs-fuse según el escenario.
El despliegue completo se ejecuta con tres comandos:
# 1. Inicializar OpenTofu
tofu init
# 2. Revisar el plan
tofu plan -var-file=terraform.tfvars
# 3. Desplegar
tofu apply -var-file=terraform.tfvars
Tras el apply, OpenTofu devuelve la IP pública de la instancia. El benchmark arranca automáticamente en menos de un minuto:
Outputs:
instance_public_ip = "<EC2_PUBLIC_IP"
results_location = "/root/benchmark-results/"
ssh_command = "ssh -i <ssh_key>.pem ec2-user@<EC2_PUBLIC_IP>"
Los resultados se guardan en /root/benchmark-results/ con los siguientes archivos:
Los datos completos se recopilan en formato CSV. Los resultados de la CLI se miden como tiempo total para 10 operaciones secuenciales, mientras que los resultados de s3fs-fuse y S3 Files se miden con fio en modo sostenido (30 segundos, I/O directo con libaio).
| Tamaño | AWS CLI | s3fs-fuse | S3 Files | FUSE vs Files |
|---|---|---|---|---|
| 1 KB | 1 | 30.546 | 1.452 | 21,0x |
| 100 KB | 1 | 13.213 | 750 | 17,6x |
| 1 MB | 1 | 1.590 | 30 | 53,0x |
| 10 MB | 0 | 114 | 16 | 7,1x |
| 100 MB | 0 | 14 | 2 | 7,0x |
| Tamaño | AWS CLI | s3fs-fuse | S3 Files | FUSE vs Files |
|---|---|---|---|---|
| 1 KB | 738 | 34 | 686 | 0,05x |
| 100 KB | 745 | 75 | 1.389 | 0,05x |
| 1 MB | 785 | 503 | 33.580 | 0,02x |
| 10 MB | 735 | 8.761 | 67.888 | 0,13x |
| 100 MB | 729 | 71.089 | 493.593 | 0,14x |
| Tamaño | s3fs-fuse | S3 Files | FUSE vs Files |
|---|---|---|---|
| 1 KB | 22.600 | 219 | 103,2x |
| 100 KB | 9.211 | 82 | 112,3x |
| 1 MB | 1.453 | 49 | 29,7x |
| 10 MB | 105 | 12 | 8,8x |
| 100 MB | 10 | 2 | 5,0x |
| Tamaño | s3fs-fuse | S3 Files | FUSE vs Files |
|---|---|---|---|
| 1 KB | 42 | 4.553 | 0,01x |
| 100 KB | 106 | 12.246 | 0,01x |
| 1 MB | 684 | 20.514 | 0,03x |
| 10 MB | 9.496 | 80.100 | 0,12x |
| 100 MB | 103.649 | 485.609 | 0,21x |
| Tamaño | s3fs-fuse | S3 Files | FUSE vs Files |
|---|---|---|---|
| 1 KB | 30,5 | 1,4 | 21,4x |
| 100 KB | 1.321 | 74 | 17,8x |
| 1 MB | 1.620 | 30 | 54,0x |
| 10 MB | 1.164 | 164 | 7,1x |
| 100 MB | 1.496 | 210 | 7,1x |
| Tamaño | s3fs-fuse | S3 Files | FUSE vs Files |
|---|---|---|---|
| 1 KB | 24,0 | 0,2 | 120x |
| 100 KB | 1.117 | 9 | 124x |
| 1 MB | 1.761 | 52 | 33,9x |
| 10 MB | 1.120 | 136 | 8,2x |
| 100 MB | 1.027 | 216 | 4,8x |
| Operación | 1 KB | 100 KB | 1 MB | 10 MB | 100 MB |
|---|---|---|---|---|---|
| UPLOAD | 1.801 | 777 | 911 | 1.071 | 1.432 |
| STAT | 738 | 734 | 785 | 735 | 729 |
| DOWNLOAD | 824 | 854 | 878 | 880 | 1.539 |
Independientemente del tamaño del archivo (1 KB o 10 MB), las operaciones con AWS CLI muestran un piso constante de 7 a 10 segundos para procesar 10 archivos (es decir, no puede bajar de ese valor). Esto se debe a que cada invocación de aws s3 cp ejecuta un proceso independiente que:
El tamaño del archivo apenas influye porque el coste de establecimiento domina sobre el coste de transferencia real, especialmente con archivos pequeños en una conexión de red suficiente.
La diferencia de rendimiento más dramática (hasta 750x en DELETE) se explica por la caché en memoria. Con la opción use_cache=/tmp, s3fs-fuse almacena en tmpfs (RAM) los archivos descargados. En Amazon Linux 2023, /tmp es un tmpfs montado en memoria, no en disco. Esto significa que el caché compite directamente con la memoria disponible de la instancia. Cuando la prueba descarga los mismos archivos que previamente subió, el kernel satisface las lecturas desde el page cache sin generar tráfico de red.
Esto no es un "engaño", refleja un patrón de uso real: en producción, los mismos archivos se leen frecuentemente más de una vez y el caché de s3fs-fuse elimina la latencia de red en accesos repetidos.
AWS S3 Files ofrece un comportamiento fundamentalmente distinto al de s3fs-fuse. Los benchmarks con fio en modo directo (direct=1, libaio) revelan que S3 Files presenta latencias de lectura 7x a 53x superiores y latencias de escritura 8x a 115x superiores respecto a s3fs-fuse:
| Métrica | S3 Files (1 KB) | s3fs-fuse (1 KB) | Diferencia |
|---|---|---|---|
| Read IOPS | 1.426 | 30.546 | FUSE 21x más rápido |
| Read Latencia | 698 μs | 31 μs | FUSE 23x más rápido |
| Write IOPS | 219 | 22.600 | FUSE 103x más rápido |
| Write Latencia | 4.553 μs | 42 μs | FUSE 108x más rápido |
En archivos grandes (10 MB), la brecha se reduce pero sigue siendo significativa:
| Métrica | S3 Files (10 MB) | s3fs-fuse (10 MB) | Diferencia |
|---|---|---|---|
| Read IOPS | 16 | 114 | FUSE 7x más rápido |
| Read Latencia | 62.423 μs | 8.761 μs | FUSE 7x más rápido |
| Write IOPS | 12 | 105 | FUSE 9x más rápido |
| Write Latencia | 80.100 μs | 9.496 μs | FUSE 8x más rápido |
La causa principal es el caching en userspace de s3fs-fuse. Incluso con la opción de fio direct=1 (que ignora la page cache del kernel), s3fs-fuse mantiene su propio caché en /tmp a nivel de proceso FUSE, mientras que S3 Files realiza cada petición a través de NFS hacia S3 sin caché intermedio, priorizando la consistencia fuerte de lectura tras escritura. Esta arquitectura de doble salto (EC2 → → EFS → S3) explica parte de la latencia adicional observada en archivos grandes.
Los tiempos de UPLOAD con s3fs-fuse fluctúan (35-55 ms) sin correlación directa con el tamaño del archivo. Esto ocurre porque la operación cp a un mount FUSE es asíncrona por defecto: el kernel devuelve éxito cuando los datos entran en el buffer, y s3fs-fuse realiza el PUT a S3 en segundo plano. El sync posterior fuerza la escritura completa, pero la medición captura solo el retorno inicial del cp.
La operación LIST con s3fs-fuse (2-3 ms) es notablemente más rápida que con AWS CLI (721-738 ms) porque el directorio ya está cacheado tras las operaciones anteriores. AWS CLI, en cambio, ejecuta ListObjectsV2 paginado en cada invocación, recorriendo todos los prefijos del bucket.
La opción enable_noobj_cache permite a s3fs-fuse cachear también las respuestas negativas de HeadObject. Con 15 ms constantes para cualquier tamaño de archivo, s3fs-fuse resuelve los STAT desde caché local mientras que AWS CLI debe hacer 10 llamadas HTTP independientes (una por archivo).
Una característica distintiva de S3 Files es que su latencia crece proporcionalmente al tamaño del archivo, tanto en lectura como en escritura. Esto es esperable en un sistema sin caché local donde cada operación de I/O debe completarse a través del Mount Target NFS hacia S3 de forma síncrona: EC2 → Mount Target (VPC) → File System → S3. A diferencia de s3fs-fuse, donde la latencia por operación se mantiene baja gracias al caché en memoria local (tmpfs), S3 Files no tiene esa capa intermedia:
En comparación, s3fs-fuse muestra un crecimiento mucho más suave:
Los datos de 100 MB revelan un patrón clave: la ventaja de s3fs-fuse se reduce significativamente en archivos grandes. En lectura, el throughput de S3 Files (210 MB/s) se acerca al de s3fs-fuse (1.496 MB/s), reduciendo la brecha de 54x (1 MB) a 7,1x (100 MB). En escritura, la tendencia es similar: S3 Files logra 216 MB/s frente a los 1.027 MB/s de s3fs-fuse, una diferencia de apenas 4,8x.
Este comportamiento es consistente con la arquitectura de S3 Files descrita por AWS: para archivos grandes (≥ 1 MB), las lecturas se transmiten directamente desde S3, bypassando la capa de caché. Como S3 ofrece alto throughput para transferencias secuenciales grandes, el rendimiento converge hacia el ancho de banda de red disponible.
Sin embargo, el throughput de s3fs-fuse en lectura para archivos grandes (1.496 MB/s para 100 MB) sugiere que su caché local sigue ofreciendo datos desde el page cache del kernel, ya que los 1,5 GB/s superan lo que una conexión de red típica puede ofrecer. Esto confirma que las pruebas de fio con direct=1 no bypassan completamente el caché de s3fs-fuse a nivel de proceso FUSE, como sí lo hacen con S3 Files.
La siguiente tabla resume cómo evoluciona la latencia de escritura con el tamaño de archivo:
| Tamaño | s3fs-fuse (μs) | S3 Files (μs) | Ratio |
|---|---|---|---|
| 1 KB | 42 | 4.553 | 108x |
| 100 KB | 106 | 12.246 | 115x |
| 1 MB | 684 | 20.514 | 30x |
| 10 MB | 9.496 | 80.100 | 8,4x |
| 100 MB | 103.649 | 485.609 | 4,7x |
La ventaja de s3fs-fuse disminuye convergentemente: de 108x en 1 KB a solo 4,7x en 100 MB. Esto tiene implicaciones prácticas importantes:
Más allá de los números del benchmark, estos son los escenarios donde cada método encaja mejor:
Con S3 Files, podemos montar petabytes de datos de entrenamiento directamente como filesystem sin duplicarlos en volúmenes EBS. Los workers de entrenamiento (hasta 25.000 simultáneos) acceden a los datos como archivos locales y los grandes batches de entrenamiento se transmiten directamente desde S3.
Recomendación: S3 Files para la accesibilidad compartida; s3fs-fuse si la latencia por epoch es crítica y es tolerable la consistencia eventual.
Sistemas multi-agente donde cada agente lee y escribe logs, estado y memoria en un directorio compartido de S3. Hasta 25.000 recursos (EC2, Lambda, EKS pods) pueden conectarse al mismo filesystem simultáneamente.
Recomendación: S3 Files — consistencia fuerte para escrituras concurrentes y acceso bidireccional S3 ↔ NFS.
Procesos que descargan archivos de S3, los transforman y los suben de vuelta. No necesitan un mount persistente.
Recomendación: AWS CLI — simplicidad, sin estado local, sin montajes que gestionar.
Data scientists y devops que necesitan navegar un bucket con ls, cat, grep, find sin montar nada permanentemente.
Recomendación: s3fs-fuse — la caché local ofrece respuestas instantáneas para accesos repetidos, y la interactividad POSIX es insuperable.
Videos, datasets de imágenes, backups donde el throughput importa más que la latencia por operación.
Recomendación: S3 Files o s3fs-fuse — a 100 MB, la diferencia de throughput se reduce a 5-7x. Preferir S3 Files si se necesita consistencia fuerte o acceso simultáneo desde múltiples instancias.
Este benchmark demuestra que la elección entre AWS CLI nativo, s3fs-fuse y AWS S3 Files depende fundamentalmente del patrón de acceso, el tamaño de archivo y los requisitos de consistencia:
Un punto clave a considerar es que los resultados de s3fs-fuse se benefician significativamente del caché de lectura. En escenarios de primera lectura (cold cache), los tiempos de descarga serán comparables a los de AWS CLI y S3 Files, ya que las tres aproximaciones deben transferir los datos desde S3 a través de la red.
La incorporación de S3 Files al benchmark revela que no existe una solución universalmente superior: s3fs-fuse sacrifica consistencia por rendimiento, S3 Files sacrifica rendimiento en archivos pequeños por consistencia y simplicidad operativa, y AWS CLI ofrece simplicidad operativa sin montaje de filesystem. La elección debe alinearse con los requisitos específicos de cada workload.
La infraestructura completa de este benchmark está disponible como módulo de OpenTofu reutilizable en este repositorio, lista para desplegar en cualquier cuenta AWS con una configuración mínima.
¿Has realizado benchmarks similares en tu infraestructura? ¿Qué estrategia usas para acceder a S3 desde tus aplicaciones? Cuéntanos tu experiencia en los comentarios.
Los comentarios serán moderados. Serán visibles si aportan un argumento constructivo. Si no estás de acuerdo con algún punto, por favor, muestra tus opiniones de manera educada.
Cuéntanos qué te parece.