Handling Large File Uploads in Laravel with Chunked Uploads

April 4, 2026

Handling Large File Uploads in Laravel with Chunked Uploads

As a backend engineer working with Laravel in production, I’ve encountered my fair share of challenges when it comes to handling large file uploads. One of the most significant issues is dealing with uploads that exceed the maximum allowed size, causing the application to timeout or even crash.

The Problem

When a user attempts to upload a large file, the entire file is sent to the server in a single request. This can lead to several problems, including:

  • Server timeouts: If the upload takes too long, the server may timeout, causing the upload to fail.
  • Memory issues: Large files can consume a significant amount of memory, leading to performance issues or even crashes.
  • Inefficient use of resources: Uploading large files in a single request can be inefficient, as it ties up server resources for an extended period.

The Solution

To overcome these challenges, I’ve implemented chunked uploads in my Laravel application. This approach involves breaking down the large file into smaller chunks, uploading each chunk separately, and then reassembling the chunks on the server.

Code Implementation

To implement chunked uploads in Laravel, I’ve used the following code:

// Client-side JavaScript code to handle chunked uploads
const fileInput = document.getElementById('file');
const chunkSize = 1024 * 1024; // 1MB chunk size

fileInput.addEventListener('change', (e) => {
  const file = e.target.files[0];
  const fileSize = file.size;
  const numChunks = Math.ceil(fileSize / chunkSize);
  const chunks = [];

  for (let i = 0; i < numChunks; i++) {
    const start = i * chunkSize;
    const end = (i + 1) * chunkSize;
    const chunk = file.slice(start, end);
    chunks.push(chunk);
  }

  const uploadChunks = async () => {
    for (const chunk of chunks) {
      const response = await fetch('/upload-chunk', {
        method: 'POST',
        body: chunk,
        headers: {
          'Content-Range': `bytes ${chunks.indexOf(chunk)}-${chunks.indexOf(chunk) + 1}/${numChunks}`,
        },
      });

      if (!response.ok) {
        throw new Error('Failed to upload chunk');
      }
    }
  };

  uploadChunks();
});

// Server-side Laravel code to handle chunked uploads
Route::post('/upload-chunk', function (Request $request) {
  $chunk = $request->all();
  $uploadId = $request->header('Upload-ID');
  $chunkNumber = $request->header('Chunk-Number');

  // Store the chunk in a temporary location
  Storage::disk('local')->put("uploads/$uploadId/$chunkNumber", $chunk);

  // Return a success response
  return response()->json(['success' => true]);
});

// Server-side Laravel code to reassemble the chunks
Route::post('/upload-complete', function (Request $request) {
  $uploadId = $request->header('Upload-ID');
  $numChunks = $request->header('Num-Chunks');

  // Reassemble the chunks
  $chunks = [];
  for ($i = 0; $i < $numChunks; $i++) {
    $chunk = Storage::disk('local')->get("uploads/$uploadId/$i");
    $chunks[] = $chunk;
  }

  // Store the reassembled file
  $filePath = 'uploads/' . $uploadId . '.pdf';
  Storage::disk('local')->put($filePath, implode('', $chunks));

  // Return a success response
  return response()->json(['success' => true]);
});

Conclusion

Handling large file uploads in Laravel can be a challenging task, but by implementing chunked uploads, we can overcome the limitations of traditional upload methods. By breaking down large files into smaller chunks, uploading each chunk separately, and then reassembling the chunks on the server, we can ensure efficient and reliable uploads. The code examples provided demonstrate how to implement chunked uploads in Laravel, and I hope this helps you in your own projects.