PHPackages                             aditkuma/laravel-bulk-upload - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Queues &amp; Workers](/categories/queues)
4. /
5. aditkuma/laravel-bulk-upload

ActiveLibrary[Queues &amp; Workers](/categories/queues)

aditkuma/laravel-bulk-upload
============================

Queue-backed bulk CSV/Excel upload pipeline for Laravel - any columns, any row count - with a live processed/failed/in-progress/remaining progress dashboard (WebSocket broadcast + polling fallback).

v0.1.0(yesterday)01↑2900%MITPHP ^8.1

Since Jul 22Compare

[ Source](https://github.com/aditkuma/laravel-bulk-upload)[ Packagist](https://packagist.org/packages/aditkuma/laravel-bulk-upload)[ RSS](/packages/aditkuma-laravel-bulk-upload/feed)WikiDiscussions Synced today

READMEChangelogDependencies (7)Versions (2)Used By (0)

aditkuma/laravel-bulk-upload
============================

[](#aditkumalaravel-bulk-upload)

Queue-backed bulk CSV/Excel upload pipeline for Laravel 9 - any columns, any row count - with a live processed/failed/in-progress/remaining progress dashboard. Pairs with the [Angular component](https://www.npmjs.com/package/@aditkuma/ngx-bulk-upload)(`@aditkuma/ngx-bulk-upload`), but the four REST endpoints work with any frontend.

How it works
------------

[](#how-it-works)

1. `POST /api/uploads` stores the file and dispatches `AnalyzeUploadJob`, returning a `uuid` immediately - the HTTP request never waits on parsing.
2. `AnalyzeUploadJob` streams just the header row and a row count (`PhpSpreadsheet`'s `listWorksheetInfo` + a read-filtered `load()`), then splits the data rows into fixed-size chunks and dispatches them as a `Bus::batch` of `ProcessUploadChunkJob`.
3. Each `ProcessUploadChunkJob` reads only its own row window (bounded memory regardless of file size), validates rows, and atomically updates the parent `Upload`'s counters - safe under many concurrent queue workers.
4. `FinalizeUploadJob` runs once, right after the batch finishes, setting the final status.
5. Every chunk (and the final job) broadcasts on the public channel `upload.{uuid}` - if you don't configure a broadcaster, this fails silently (see `SafeBroadcaster`) and polling `GET /api/uploads/{uuid}` still works.

Row-level validation is behind the `RowProcessor` interface (default: `GenericRowProcessor`, which only rejects entirely-blank rows, plus a CSV/TXT-only ragged-column check inside `ProcessUploadChunkJob` - a sparsely filled Excel row is normal and is never flagged). **Bind your own `RowProcessor`** to add domain-specific processing (e.g. inserting into your own tables) without touching the upload pipeline itself:

```
$this->app->bind(
    \Aditkuma\LaravelBulkUpload\Contracts\RowProcessor::class,
    \App\Uploads\MyRowProcessor::class
);
```

Install
-------

[](#install)

```
composer require aditkuma/laravel-bulk-upload

```

The service provider is auto-discovered. Then:

```
php artisan vendor:publish --tag=bulk-upload-config   # optional, to customize
php artisan migrate

```

### Requirements

[](#requirements)

- Laravel 9, PHP 8.1+
- A queue connection that supports `Bus::batch()` (the `database` driver works out of the box - just make sure you've run `php artisan queue:table`, `php artisan queue:failed-table`, and `php artisan queue:batches-table` at some point, since batching needs the `job_batches` table)
- A running queue worker (`php artisan queue:work`) - nothing processes without one
- (Optional) A Pusher-protocol broadcaster (e.g. self-hosted [Soketi](https://docs.soketi.app/)) for realtime updates - omit entirely and the frontend's polling fallback still works

Configuration
-------------

[](#configuration)

`config/bulk-upload.php` (env vars in parens):

KeyDefaultPurpose`chunk_size` (`BULK_UPLOAD_CHUNK_SIZE`)`500`Rows per queued job`max_file_size_kb` (`BULK_UPLOAD_MAX_FILE_SIZE_KB`)`512000`Server-side upload size limit`allowed_extensions``csv,txt,xls,xlsx`Accepted file types`disk` (`BULK_UPLOAD_DISK`)`local`Filesystem disk (from `config/filesystems.php`) for stored source files`register_routes` (`BULK_UPLOAD_REGISTER_ROUTES`)`true`Set `false` to wire up `UploadController` yourself`route_prefix` (`BULK_UPLOAD_ROUTE_PREFIX`)`api`Prefix for the package's routesRoutes
------

[](#routes)

- `POST {prefix}/uploads` - multipart upload, returns `{ uuid }`
- `GET {prefix}/uploads/{uuid}` - progress snapshot (also the polling endpoint)
- `GET {prefix}/uploads/{uuid}/errors?page=&per_page=` - paginated failed rows
- `GET {prefix}/uploads/{uuid}/errors/export` - CSV download of all failures

Broadcasting
------------

[](#broadcasting)

If `BROADCAST_DRIVER=pusher` is configured (pointed at Soketi or Pusher Cloud), `UploadProgressUpdated` broadcasts on public channel `upload.{uuid}`with event name `progress.updated`, payload matching the polling endpoint's JSON shape.

Development
-----------

[](#development)

```
git clone https://github.com/aditkuma/laravel-bulk-upload.git
cd laravel-bulk-upload
composer install

```

There's no bundled test Laravel app in this repo - point a real app's `composer.json` at this directory with a local `path` repository to iterate against it.

###  Health Score

36

—

LowBetter than 79% of packages

Maintenance100

Actively maintained with recent releases

Popularity2

Limited adoption so far

Community2

Small or concentrated contributor base

Maturity32

Early-stage or recently created project

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

1d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/d6badb643431042078ba3f16d20198ad30f90aebcb667e01642175007774e0bd?d=identicon)[aditkuma](/maintainers/aditkuma)

---

Tags

laravelexcelcsvqueueimportuploadbulk upload

### Embed Badge

![Health badge](/badges/aditkuma-laravel-bulk-upload/health.svg)

```
[![Health](https://phpackages.com/badges/aditkuma-laravel-bulk-upload/health.svg)](https://phpackages.com/packages/aditkuma-laravel-bulk-upload)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3345.3M347](/packages/psalm-plugin-laravel)[laravel/scout

Laravel Scout provides a driver based solution to searching your Eloquent models.

1.7k55.0M631](/packages/laravel-scout)[laravel/pulse

Laravel Pulse is a real-time application performance monitoring tool and dashboard for your Laravel application.

1.7k15.1M136](/packages/laravel-pulse)[fleetbase/core-api

Core Framework and Resources for Fleetbase API

1235.9k21](/packages/fleetbase-core-api)[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

9762.4M133](/packages/roots-acorn)[api-platform/laravel

API Platform support for Laravel

58174.6k17](/packages/api-platform-laravel)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
