Search by

justinholtweb / craft-chunky

Uploads too big for your server, in pieces small enough for it. Chunky splits large files in the control panel into chunks, reassembles them behind Craft’s own upload path, and resumes the ones that stumble.

Maintainers

Package info

github.com/justinholtweb/craft-chunky

Homepage

Type:craft-plugin

pkg:composer/justinholtweb/craft-chunky

Transparency log

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

dev-main 2026-08-29 12:04 UTC

This package is auto-updated.

Last update: 2026-08-29 12:07:43 UTC


README

Uploads too big for your server, in pieces small enough for it.

A file is as big as it is. Every hop between the browser and PHP has its own opinion about how big one request may be — upload_max_filesize, post_max_size, nginx's client_max_body_size, a CDN's body cap, a load balancer's timeout — and the smallest of those opinions is the real limit on what anybody can upload. Raising them all is somebody else's server, somebody else's plan, and sometimes nobody's to raise at all.

Chunky does not raise any of them. It makes them irrelevant, by never sending a request larger than the smallest one.

Free. Craft 5.3+, PHP 8.2+. No build step, no runtime dependencies, no outbound requests, no third-party service.

Chunky is the successor to sebastianlenz/craft-chunked-uploads, which was abandoned. It is not a fork — it is a fresh implementation against Craft 5, and it fixes that plugin's best-known limitation: it works everywhere in the control panel, not just on the Assets screen.

Install

composer require justinholtweb/craft-chunky
php craft plugin/install chunky

That is the whole setup. Large uploads in the control panel start arriving in 4 MB pieces immediately.

How it works

Craft already ships jQuery File Upload, and jQuery File Upload has supported Content-Range chunking for a decade. Craft simply never turns it on.

So Chunky is not a new uploader. It decorates the one Craft already builds, and it decides per file:

The file is… What happens
at or under the chunk size posted whole to Craft's own assets/upload, untouched
larger than the chunk size sliced into Content-Range requests, reassembled by Chunky, then handed to Craft

That gate is the whole safety story. A bug in Chunky can only affect uploads that were going to be rejected anyway.

On the server, each chunk is written straight into a .part file at the offset it claims, so a 1 GB upload needs 1 GB of scratch space rather than two copies of it. The response to an unfinished upload carries Range: 0-<last byte held>, which is how the browser knows where it stands — and what makes resuming after a dropped connection land in the right place instead of writing the same bytes twice into the middle of the file.

Where it works

  • The Assets screen — the drop zone and the upload button.
  • Assets fields — on entries, categories, users, and every element editor slideout. This is the part the abandoned Craft 4 plugin never did.
  • Replace file — on the asset editor and the element index action.

It deliberately leaves user photos, site images, and other plugins' upload actions alone.

What it adds beyond chunking

It says no early. A file with an extension Craft will not accept, or one past the configured maximum, is refused on the first chunk. Twenty seconds of somebody's time, not forty minutes.

It retries. A chunk that fails for a reason that might not happen twice — a dropped connection, a timeout, a 502 from a proxy — is retried, with a doubling delay, from the offset the server reports rather than the one the browser assumed. A 4xx is Craft saying no on purpose and is never retried.

It tells you when it cannot work. The settings screen reads the limits it can see and says plainly which ones the chunk size clears — and names the ones no PHP process can read (client_max_body_size, LimitRequestBody, a CDN's cap), because those reject a chunk before Craft is involved, which means an empty log and a bare 413 in the browser.

It cleans up after itself. A browser tab closed mid-upload leaves a partial file behind. Craft's garbage collection sweeps them; php craft chunky/partials says what is on disk and php craft chunky/partials/cleanup sweeps on demand.

Settings

Settings → Plugins → Chunky, or config/chunky.php:

return [
    'chunkSize' => '4MB',
    'maxUploadSize' => '2GB',
    'maxRetries' => 3,
];

See docs/configuration.md for the full list.

Requirements

  • Craft CMS 5.3 or later
  • PHP 8.2 or later
  • Somewhere writable under storage/runtime
  • A chunk-sized request allowed through by PHP, the web server, and anything in front of them

Licence

The Craft License. See LICENSE.md.