Resumen de límites de carga de archivos en AWS S3 y CloudFront | Multipart y URLs Presignadas
Al crear una función de carga de archivos mediante AWS, S3, CloudFront, API Gateway y Lambda tienen diferentes límites de tamaño. Comprender qué capa se convierte en un cuello de botella es extremadamente importante. Este artículo explica los valores límite de cada servicio, cómo usar carga multiparte y URLs presignadas para manejar archivos grandes, y proporciona ejemplos de implementación en PHP.
Límites de carga de Amazon S3
Los límites de tamaño de carga de objetos a S3 varían según el método utilizado.
| Método de carga | Tamaño máximo | Notas |
|---|---|---|
| PUT Object (individual) | 5 GB | Límite de carga por solicitud |
| Multipart Upload | 5 TB | Tamaño máximo por objeto |
| Por parte | Mínimo 5 MB a máximo 5 GB | Solo la última parte puede ser menor de 5 MB |
| Número de partes | Máximo 10,000 partes | Límite de carga multiparte |
AWS recomienda carga multiparte para archivos mayores de 100 MB. Desde la perspectiva de retransmisión eficiente durante fallos de red y mayor rendimiento a través de transferencias paralelas, debe utilizarse activamente para archivos grandes.
Casos que requieren carga multiparte
La carga multiparte es un método donde un único objeto se divide en múltiples partes, cada una se envía como una solicitud independiente, y luego se combinan al final. Es efectiva en los siguientes escenarios.
- <strong>Archivos de 100 MB o mayores</strong>: Este es el umbral de carga multiparte recomendado por AWS.
- <strong>Entornos de red inestable</strong>: Incluso si ocurre un error durante la transferencia, solo las partes fallidas necesitan retransmitirse.
- <strong>Maximizar rendimiento</strong>: Cargue varias partes en paralelo para mejorar la velocidad de transferencia.
- <strong>Pausar y reanudar cargas</strong>: Guarde el Upload ID para reanudar entre sesiones.
El proceso de carga multiparte consta de tres pasos principales.
- <strong>Iniciar</strong> (CreateMultipartUpload): Obtener el ID de carga
- <strong>Enviar partes</strong> (UploadPart): Cargue cada parte y registre el ETag
- <strong>Completar</strong> (CompleteMultipartUpload): Envía una lista de números de parte y ETags para finalizar el objeto
Si cancela a mitad de camino sin llamar a <code>AbortMultipartUpload</code>, las partes incompletas continuarán siendo cobradas como cargos de almacenamiento. Se recomienda encarecidamente configurar una política de ciclo de vida en su bucket de S3 para "eliminar cargas multipartidas incompletas después de N días."
Expiración y tamaño de URL prefirmada
Usando una URL firmada (Presigned URL), los clientes sin permisos de acceso a S3 (como navegadores o aplicaciones móviles) pueden cargar archivos directamente a S3. Como el servidor no actúa como intermediario, los archivos grandes se pueden manejar de manera eficiente.
| Elemento | Restricciones y especificaciones |
|---|---|
| Expiración máxima (emitida por usuario de IAM) | 7 días (604,800 segundos) |
| Expiración máxima (emitida por rol de IAM) | Dentro del tiempo de sesión del rol (máximo 12 horas) |
| Tamaño máximo de archivo que se puede cargar | Máximo 5 GB para PUT único |
| Soporte para multipart | Emitir URLs presignadas individuales para cada parte |
Una URL prefirmada se genera en el backend y se devuelve al cliente, que luego envía una solicitud PUT directamente a esa URL. Dado que la URL contiene una firma, solo tiene éxito cuando se carga el archivo correcto dentro del período de vencimiento.
Límite de tamaño de body en CloudFront
Al reenviar solicitudes a través de CloudFront a un origen (como S3 o EC2), hay límites de tamaño en el cuerpo de la solicitud.
| Configuración | Valor predeterminado | Valor máximo |
|---|---|---|
| Tamaño del cuerpo de la solicitud (predeterminado) | 1 MB | Se puede cambiar en la configuración de distribución |
| Cuando se usa Lambda@Edge | 1 MB | 1 MB (no modificable) |
| En el caso de CloudFront Functions | — | El cuerpo de la solicitud no es accesible |
En la configuración de distribución de CloudFront, puede habilitar "Allow requests with body" y aumentar el límite, pero tenga en cuenta que Lambda@Edge tiene un límite de 1 MB que no se puede cambiar. Para cargar archivos grandes, se recomienda adoptar una arquitectura que omita CloudFront y cargue directamente desde el cliente a S3 usando URLs presignadas.
Límite de carga útil de API Gateway
API Gateway (tanto REST API como HTTP API) tiene un límite de tamaño de carga útil.
| Tipo de API | Tamaño máximo de carga útil | Notas |
|---|---|---|
| REST API | 10 MB | Lo mismo ocurre cuando el soporte binario está habilitado |
| HTTP API | 10 MB | — |
| WebSocket API | 128 KB (mensaje) / 32 KB (marco) | — |
El límite de 10 MB de API Gateway se clasifica como una cuota de servicio de AWS y no puede aumentarse. Cargar archivos que excedan 10 MB a través de API Gateway se considera un error de diseño; considera migrar al patrón de URL prefirmada.
Límites de archivos a través de Lambda
Al recibir archivos en una función Lambda, existe un límite de tamaño en la carga útil del evento transmitida por API Gateway. Además, Lambda en sí tiene las siguientes limitaciones.
| Elementos de restricción | Valor |
|---|---|
| Carga útil de llamada síncrona (Request) | 6 MB |
| Carga útil de llamada síncrona (Response) | 6 MB |
| Carga útil de llamada asincrónica | 256 KB |
| Capacidad de almacenamiento del directorio <code>/tmp</code> | Por defecto 512 MB (máximo 10 GB) |
| Tiempo máximo de ejecución | 15 minutos |
Al procesar archivos en Lambda, los archivos temporales se escriben en <code>/tmp</code>. El valor predeterminado es 512 MB, pero el almacenamiento efímero se puede extender hasta 10 GB mediante la configuración de Lambda (se aplican cargos adicionales).
Ejemplo de código de carga multiparte S3 en PHP
Este es un ejemplo de implementación de carga de múltiples partes usando AWS SDK para PHP (v3). El uso de la clase <code>MultipartUploader</code> del SDK maneja automáticamente la división de fragmentos, reintentos y procesamiento de finalización.
use Aws\S3\S3Client;
use Aws\S3\MultipartUploader;
use Aws\Exception\MultipartUploadException;
$s3 = new S3Client([
'region' => 'ap-northeast-1',
'version' => 'latest',
]);
$uploader = new MultipartUploader($s3, '/path/to/large-file.mp4', [
'bucket' => 'your-bucket-name',
'key' => 'uploads/' . basename('/path/to/large-file.mp4'),
'before_initiate' => function (\Aws\Command $command) {
// アップロード開始前のフック
},
'before_upload' => function (\Aws\Command $command) {
// 各パートアップロード前のフック(プログレス表示など)
},
'concurrency' => 5, // 並列アップロード数
'part_size' => 10 * 1024 * 1024, // 1パート = 10 MiB
]);
try {
$result = $uploader->upload();
echo 'アップロード完了: ' . $result['ObjectURL'];
} catch (MultipartUploadException $e) {
// 失敗したパートから再開する例
$uploader = new MultipartUploader($s3, '/path/to/large-file.mp4', [
'state' => $e->getState(),
]);
$result = $uploader->upload();
}
Aquí se explica cómo emitir una URL prefirmada y permitir que los clientes carguen directamente en S3.
use Aws\S3\S3Client;
$s3 = new S3Client([
'region' => 'ap-northeast-1',
'version' => 'latest',
]);
// 署名付きURLを生成(有効期限: 15分)
$cmd = $s3->getCommand('PutObject', [
'Bucket' => 'your-bucket-name',
'Key' => 'uploads/' . uniqid('', true) . '.jpg',
'ContentType' => 'image/jpeg',
]);
$request = $s3->createPresignedRequest($cmd, '+15 minutes');
$presignedUrl = (string) $request->getUri();
// このURLをクライアントに返す
// クライアントはこのURLに PUT リクエストでファイルを直接送信する
echo json_encode(['upload_url' => $presignedUrl]);
Directrices de selección de arquitectura
- <strong>Hasta 10 MB</strong>: Se puede implementar de forma simple con API Gateway → Lambda → S3
- <strong>10 MB–100 MB</strong>: Se recomienda carga directa del cliente a S3 mediante URLs prefinadas
- <strong>100 MB–5 GB</strong>: Lograr transferencias estables con URL prefirmada + carga multiparte
- <strong>Más de 5 GB</strong>: Carga multiparte obligatoria (PUT solo no es suficiente)
Procedimiento de prueba usando archivos de umbral de DevLab
Para verificar la configuración de carga de <code>S3</code> en la práctica, necesita archivos de prueba de tamaños precisos. Usando los archivos de prueba de valor límite de DevLab, puede verificar eficientemente el comportamiento alrededor de tamaños específicos.
- Descargue un archivo del tamaño deseado de la <a href="/ja/files/threshold/">lista de archivos de prueba de valores límite</a> en DevLab.
- Al validar el umbral de conmutación multiparte, también puede utilizar la versión de tamaño grande de <a href="/ja/files/images/png/">imágenes de prueba PNG</a>.
- Cargue el archivo descargado utilizando el comando <code>aws s3 cp</code> o <code>PutObject</code> / <code>MultipartUploader</code> del SDK, y verifique el éxito o fracaso con archivos alrededor del límite de tamaño.
Archivos de prueba para este artículo
- <a href="/ja/files/threshold/" class="text-primary-600 dark:text-primary-400 hover:underline">Lista de archivos de prueba de valores límite</a> — Para validar límites de S3, API Gateway y Lambda
- <a href="/ja/files/threshold/10mb/" class="text-primary-600 dark:text-primary-400 hover:underline">Conjunto de prueba de valores límite de 10MB</a> — Verificar justo antes y después del límite de 10 MB de API Gateway
- <a href="/ja/files/threshold/25mb/" class="text-primary-600 dark:text-primary-400 hover:underline">Conjunto de Prueba de Límite de 25MB</a> — Para verificar el comportamiento alrededor de la línea recomendada de multiparte
- <a href="/ja/files/images/png/" class="text-primary-600 dark:text-primary-400 hover:underline">Imágenes de prueba PNG</a> — Verificar la funcionalidad del pipeline de carga de imágenes
Artículos relacionados
- <a href="/ja/blog/how-to-test-upload-limit/" class="text-primary-600 dark:text-primary-400 hover:underline">Cómo probar correctamente los límites de tamaño de carga de archivos</a>
- <a href="/ja/blog/php-file-upload/" class="text-primary-600 dark:text-primary-400 hover:underline">Cómo implementar la carga de archivos en PHP | Guía completa de validación, almacenamiento y seguridad</a>
- <a href="/ja/blog/multipart-form-data-overhead/" class="text-primary-600 dark:text-primary-400 hover:underline">Calcular la sobrecarga de multipart/form-data con precisión</a>
- <a href="/ja/blog/mb-vs-mib-file-size/" class="text-primary-600 dark:text-primary-400 hover:underline">¡MB y MiB son diferentes! Las trampas de las unidades de tamaño de archivo</a>