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.
Package info
github.com/justinholtweb/craft-chunky
Type:craft-plugin
pkg:composer/justinholtweb/craft-chunky
Requires
- php: ^8.2
- ext-json: *
- ext-mbstring: *
- craftcms/cms: ^5.3.0
Requires (Dev)
None
Suggests
None
Provides
None
Conflicts
None
Replaces
None
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.