PHPackages                             alihaiderx/laravel-spool - 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. [Caching](/categories/caching)
4. /
5. alihaiderx/laravel-spool

ActiveLibrary[Caching](/categories/caching)

alihaiderx/laravel-spool
========================

Fast, non-blocking buffer for Laravel. Writes to Redis Streams or sharded filesystem files with automatic fallback, rotation, and batch flushing.

1.0.0(1mo ago)10MITPHP

Since May 3Pushed 1mo agoCompare

[ Source](https://github.com/alihaiderx/laravel-spool)[ Packagist](https://packagist.org/packages/alihaiderx/laravel-spool)[ RSS](/packages/alihaiderx-laravel-spool/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (4)Versions (11)Used By (0)

 [![Laravel Spool](art/logo.png)](art/logo.png)

Laravel Spool
=============

[](#laravel-spool)

 **Batch and defer expensive database writes in Laravel — no Redis, no queues, no background workers required.**
 Works on shared hosting. Drop 1,000 individual DB inserts down to a single batch operation.

 [ ![Latest Version](https://camo.githubusercontent.com/b50d34bf71310ddc499c72fe19963a53c40dfb038ee68bf085168106c2eee82e/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f616c69686169646572782f6c61726176656c2d73706f6f6c) ](https://packagist.org/packages/alihaiderx/laravel-spool) [ ![Total Downloads](https://camo.githubusercontent.com/e5ff75f952a70c72bd306f4df636ef054efef16659e63a0fc6575b80a8d18453/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f616c69686169646572782f6c61726176656c2d73706f6f6c) ](https://packagist.org/packages/alihaiderx/laravel-spool) [ ![GitHub Stars](https://camo.githubusercontent.com/11148d472b912fd37cec969dceea79188e5714be9785ca22c16d492ba225d2b2/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f616c69686169646572782f6c61726176656c2d73706f6f6c3f7374796c653d666c6174) ](https://github.com/alihaiderx/laravel-spool/stargazers) [ ![License: MIT](https://camo.githubusercontent.com/fdf2982b9f5d7489dcf44570e714e3a15fce6253e0cc6b5aa61a075aac2ff71b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d79656c6c6f772e737667) ](https://opensource.org/licenses/MIT) [ ![PHP 8.2+](https://camo.githubusercontent.com/5fe05c705bf034839bda7651781e4d0a9d42f4a840478ca5e343873a0361bb89/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e322b2d626c75652e737667) ](https://php.net) [ ![Laravel 12.x](https://camo.githubusercontent.com/b72e0aa3b09f6ee9f1cd47f19792a8204408312803c6b277768a5d2c99ffd60c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d31322e782d7265642e737667) ](https://laravel.com)

The Problem
-----------

[](#the-problem)

Every time a user visits a page, triggers an event, or hits your API, your Laravel app likely writes to the database. Once. Per event. Every time.

Under normal traffic that's fine. Under load it becomes a bottleneck: lock contention, slow response times, and a database that can't keep up.

The standard fix — Laravel queues, Redis, Horizon, Supervisor — adds real infrastructure complexity. And if you're on **shared hosting**, those options simply aren't available.

The Solution
------------

[](#the-solution)

Laravel Spool captures high-frequency writes to a **fast local buffer first**, then processes them as a single batch on a schedule you control.

- **1,000 individual inserts → 1 batch insert**
- **No Redis required** — the filesystem driver works anywhere PHP runs
- **No background workers** — flush runs as a scheduled Laravel task
- **No configuration overhead** — one install command and you're buffering

It's a lightweight performance layer that fits between your application events and your database.

Key Features
------------

[](#key-features)

FeatureWhy It Matters**Filesystem buffering**Works on any host — no Redis, no extensions, no extra services**Sharded writes**Spreads data across multiple files to avoid write contention under load**Atomic processing**File rename guarantees no two workers process the same shard**Three-stage lifecycle**`active → processing → completed` gives you visibility and auditability**Multiple buckets**Separate buffers per data type (`page-views`, `api-logs`, `metrics`)**Redis Streams driver**Optional upgrade path when your infra supports it**Health check command**Verify your setup is correct before going to production**TTL-based cleanup**Completed shards auto-expire — no manual disk managementUse Cases
---------

[](#use-cases)

- **Page view / analytics tracking** — buffer every hit, insert hourly in bulk
- **Activity logs** — accumulate user actions, write in batches instead of per-action
- **API usage metering** — count calls without a DB write on every request
- **Bulk form submissions** — queue submissions to a buffer, process on a schedule
- **Shared hosting optimization** — get performance gains without Redis or queue workers

Quick Start
-----------

[](#quick-start)

### 1. Install

[](#1-install)

```
composer require alihaiderx/laravel-spool
```

Laravel auto-discovers the service provider. No manual registration needed.

### 2. Set Up

[](#2-set-up)

```
php artisan spool:install
```

This publishes `config/spool.php` and creates the buffer directories under `storage/app/private/buffer/`.

### 3. Buffer Data

[](#3-buffer-data)

```
use Alihaiderx\LaravelSpool\Facades\Buffer;

// Call this on every page view, event, API hit, etc.
Buffer::buffer([
    'payload' => [
        'user_id' => $user->id,
        'event'   => 'page_view',
        'url'     => request()->path(),
    ]
], 'page-views');
```

### 4. Flush in Batches

[](#4-flush-in-batches)

In `routes/console.php`, schedule a flush:

```
use Alihaiderx\LaravelSpool\Facades\FileSystemBuffer;

Schedule::call(function () {
    FileSystemBuffer::flush(function (string $file, ?string $bucket): bool {
        $lines = file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
        $rows  = array_map(fn ($line) => unserialize($line), $lines);

        // One DB insert for potentially thousands of events
        DB::table('page_views')->insert($rows);

        return true;
    }, 'page-views');
})->everyMinute();

Schedule::call(function () {
    FileSystemBuffer::clean(50, 'page-views');
})->daily();
```

That's it. Your app now buffers writes and processes them in batches.

How It Works
------------

[](#how-it-works)

### Filesystem Driver (Default)

[](#filesystem-driver-default)

Every call to `Buffer::buffer()` serializes the payload and appends it to a shard file. Writes are distributed across up to `max_shards` files using a hash, which reduces file-level lock contention when multiple requests write simultaneously.

When `flush()` runs:

1. Shard files in `active/` are **atomically renamed** to `processing/` — this is a single OS-level rename, so two concurrent flush jobs can never pick up the same shard.
2. Your callback receives each shard file path. You read the lines, process them however you need, and return `true`.
3. Processed shards move to `completed/` and are held for `shards_ttl_days` days before `clean()` removes them.

```
storage/app/private/buffer/
├── active/       ← new payloads are written here
├── processing/   ← shards claimed by a flush job
└── completed/    ← successfully processed, kept for audit

```

### Redis Streams Driver (Optional)

[](#redis-streams-driver-optional)

When Redis is available, set `SPOOL_BUFFER_DRIVER=redis`. The package writes to a Redis Stream via `XADD`. A long-running consumer process reads batches from the stream and fires a `RedisBufferConsumeEvent` that your application handles.

```
php artisan spool:start-redis-consume
```

Why Not Just Use Laravel Queues?
--------------------------------

[](#why-not-just-use-laravel-queues)

Laravel SpoolLaravel Queues**Works on shared hosting**YesUsually not**Requires Redis**No (filesystem driver)Often yes**Requires Supervisor**NoYes, for reliability**Best for**Batching identical writesIndividual background jobs**Processing model**Scheduled batch flushPer-job async**Infrastructure overhead**MinimalQueue worker + process monitor**Use Spool when** you need to batch many similar writes (analytics, logs, counters) and want zero extra infrastructure.

**Use Laravel queues when** you need per-job async processing, retries, failed job handling, or complex background workflows.

They are not mutually exclusive — many apps use both.

Performance Impact
------------------

[](#performance-impact)

**Without Spool** — direct writes on every event:

```
1,000 page views → 1,000 individual INSERT statements
Response time per request: ~15–40ms (DB write cost added)
DB load: constant, spiky, high under traffic

```

**With Spool** — buffered and batched:

```
1,000 page views → buffer to disk (microseconds per write)
Scheduled flush → 1 batch INSERT of 1,000 rows
Response time per request: no DB write overhead
DB load: predictable, batched, low

```

The write cost moves off your HTTP response cycle entirely.

Shared Hosting Advantage
------------------------

[](#shared-hosting-advantage)

Most Laravel performance packages assume you have Redis, a queue worker, and Supervisor. On shared hosting, you have none of those.

Laravel Spool's filesystem driver removes those requirements entirely:

- **No Redis** — buffers to local disk files
- **No background workers** — flushing runs via Laravel's scheduler (a single cron entry)
- **No Supervisor** — nothing to keep alive
- **No extra dependencies** — just PHP and a writable filesystem

The only thing required is the standard Laravel scheduler cron entry in your cPanel or server cron:

```
* * * * * cd /path-to-project && php artisan schedule:run >> /dev/null 2>&1

```

That's standard Laravel. If your app already runs on shared hosting, Spool works immediately.

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

[](#configuration)

Published to `config/spool.php` after running `spool:install`.

```
return [
    'buffer_driver'    => env('SPOOL_BUFFER_DRIVER', 'file'),
    'max_shards'       => env('SPOOL_MAX_SHARDS', 30),
    'max_shard_size'   => env('SPOOL_MAX_SHARD_SIZE', 307200),
    'max_flush_shards' => env('SPOOL_MAX_FLUSH_SHARDS', 5),
    'shards_ttl_days'  => env('SPOOL_SHARDS_TTL_DAYS', 3),
    'redis_batch_size' => env('SPOOL_REDIS_BATCH_SIZE', 500),
];
```

VariableDefaultDescription`SPOOL_BUFFER_DRIVER``file``file` or `redis``SPOOL_MAX_SHARDS``30`Number of shard files per bucket. More shards = less write contention.`SPOOL_MAX_SHARD_SIZE``307200` (300 KB)Shard file size limit before rotation.`SPOOL_MAX_FLUSH_SHARDS``5`Max shards processed per `flush()` call. Keeps jobs short.`SPOOL_SHARDS_TTL_DAYS``3`Days to retain completed shards before deletion.`SPOOL_REDIS_BATCH_SIZE``500`Messages read per Redis consumer iteration.Health Check
------------

[](#health-check)

Before deploying, verify your setup:

```
php artisan spool:health
```

This checks that buffer directories exist and are writable, and that all config values are valid.

```
All checks passed.

```

```
ERROR  Buffer 'active' directory does not exist: .../storage/app/private/buffer/active
ERROR  max_flush_shards (10) cannot exceed max_shards (5).

```

The command exits with code `0` on success and `1` on failure — safe to use in deployment pipelines and Docker health checks.

Redis Driver Setup (Optional)
-----------------------------

[](#redis-driver-setup-optional)

If your infrastructure supports Redis and you want lower write latency:

**1.** Install predis if not using the `phpredis` extension:

```
composer require predis/predis
```

**2.** Set the driver:

```
SPOOL_BUFFER_DRIVER=redis
```

**3.** Start the consumer (manage with Supervisor in production):

```
php artisan spool:start-redis-consume
```

**4.** Listen for batched events in your application:

```
use Alihaiderx\LaravelSpool\Facades\Buffer;
use Alihaiderx\LaravelSpool\Events\RedisBufferConsumeEvent;

Buffer::listenRedis(function (RedisBufferConsumeEvent $event) {
    $pageViews = array_filter(
        $event->batch,
        fn ($item) => $item['bucketSlug'] === 'page-views'
    );

    DB::table('page_views')->insert(array_column($pageViews, 'payload'));
});
```

Requirements
------------

[](#requirements)

- PHP 8.2+
- Laravel 12.x
- Redis driver: `phpredis` extension or `predis/predis`

Roadmap
-------

[](#roadmap)

- Dashboard UI for monitoring buffer state
- Artisan command to manually trigger a flush
- Laravel 11.x support
- Benchmarks and performance comparison guide

Contributing
------------

[](#contributing)

Pull requests are welcome. For significant changes, open an issue first to discuss what you'd like to change.

1. Fork the repository
2. Create a feature branch (`git checkout -b feature/your-feature`)
3. Commit your changes
4. Open a pull request

License
-------

[](#license)

Laravel Spool is open-source software released under the [MIT license](https://opensource.org/licenses/MIT).

###  Health Score

37

—

LowBetter than 81% of packages

Maintenance93

Actively maintained with recent releases

Popularity2

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity40

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

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

36d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/89eb87bc9448667f1a20a9af0193e65f7208542ba6ac571c5251dfce2c40d6d2?d=identicon)[alihaiderx](/maintainers/alihaiderx)

---

Top Contributors

[![alihaiderx](https://avatars.githubusercontent.com/u/46569511?v=4)](https://github.com/alihaiderx "alihaiderx (39 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/alihaiderx-laravel-spool/health.svg)

```
[![Health](https://phpackages.com/badges/alihaiderx-laravel-spool/health.svg)](https://phpackages.com/packages/alihaiderx-laravel-spool)
```

###  Alternatives

[rhubarbgroup/redis-cache

A persistent object cache backend for WordPress powered by Redis. Supports Predis, PhpRedis, Relay, replication, sentinels, clustering and WP-CLI.

52799.8k1](/packages/rhubarbgroup-redis-cache)[monospice/laravel-redis-sentinel-drivers

Redis Sentinel integration for Laravel and Lumen.

103839.1k](/packages/monospice-laravel-redis-sentinel-drivers)[namoshek/laravel-redis-sentinel

An extension of Laravels Redis driver which supports connecting to a Redis master through Redis Sentinel.

39764.5k](/packages/namoshek-laravel-redis-sentinel)[symfony-bundles/redis-bundle

Symfony Redis Bundle

291.2M6](/packages/symfony-bundles-redis-bundle)[yangusik/laravel-balanced-queue

Laravel queue management with load balancing between partitions (user groups)

8512.6k](/packages/yangusik-laravel-balanced-queue)[millipress/millicache

WordPress Full-Page Cache based on Rules &amp; Flags. Delivers flexible, scalable caching workflows backed by Redis and ValKey in-memory stores.

622.0k2](/packages/millipress-millicache)

PHPackages © 2026

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