Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Async Laravel Package

spatie/async

Run PHP tasks in parallel with a simple Pool API built on PCNTL. Add closures, handle results via then/catch, and wait for completion. Ideal for speeding up batch jobs, CPU-heavy work, and IO-bound processing with multiple processes.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Strengths:

    • PCNTL Wrapper: Provides a clean abstraction over PHP’s native pcntl extension, enabling true parallelism (not just concurrency) for CPU-bound tasks. This is a critical fit for Laravel applications requiring high-performance batch processing, real-time data transformations, or parallelized background jobs.
    • Laravel Synergy: Designed to integrate seamlessly with Laravel’s job queues (e.g., Illuminate\Bus\Queueable), allowing async job execution without blocking the main process. Complements Laravel’s existing queue:work system.
    • Lightweight: Minimal overhead (~500 LOC), making it ideal for microservices or monoliths where performance is prioritized over abstraction complexity.
    • Process Isolation: Enables true parallel execution (unlike Laravel’s default queue workers, which are single-threaded). Useful for tasks like image/video processing, heavy computations, or parallel API calls.
  • Weaknesses:

    • PCNTL Dependency: Requires pcntl (Linux/Unix only; Windows support is limited to WSL or custom setups). Blocker for Windows-hosted Laravel apps without WSL.
    • No Built-in Retries/Supervision: Unlike Laravel Queues, this package lacks retry logic or process supervision. Requires manual handling (e.g., wrapping in a try-catch or using a queue worker as a fallback).
    • State Management: No built-in shared memory or inter-process communication (IPC). Developers must handle data sharing explicitly (e.g., via Redis, databases, or files).
    • No Persistent Workers: Processes are ephemeral; no built-in way to manage long-running workers (unlike Laravel’s queue:work --daemon).

Integration Feasibility

  • Laravel Ecosystem Compatibility:
    • Jobs: Can replace or augment Laravel’s queue system for CPU-heavy jobs. Example: Use Async::parallel() to run multiple ShouldQueue jobs in parallel.
    • Commands: Integrates with Laravel Artisan commands for CLI-driven parallel tasks (e.g., bulk data processing).
    • Events/Listeners: Can trigger async processes in response to events (e.g., Async::run(fn() => processLargeFile())).
  • Database/ORM Impact: None. Works at the PHP process level, independent of Eloquent or database connections.
  • Caching: No direct integration with Laravel’s cache, but can be combined with cache() helper for shared state.

Technical Risk

  • High:
    • PCNTL Limitations: Debugging parallel processes is harder than single-threaded code. Tools like strace or htop may be needed to monitor child processes.
    • Resource Management: Risk of overloading the server if parallel processes aren’t throttled (e.g., spawning 100 processes for a single request).
    • Error Handling: Exceptions in child processes are silent by default. Requires explicit logging or signal handling (e.g., pcntl_signal_dispatch()).
    • Stateful Operations: Shared state (e.g., database transactions) must be managed carefully to avoid race conditions.
  • Mitigation:
    • Use Async::parallel() with a fixed pool size (e.g., ->pool(4)).
    • Wrap async calls in try-catch and log errors to a service like Sentry.
    • Combine with Laravel Queues for idempotency/retry logic where needed.

Key Questions

  1. Deployment Environment:
    • Is the Laravel app hosted on Linux/Unix (where pcntl is natively supported)? If Windows, is WSL or a custom setup viable?
  2. Use Case Priority:
    • Is the primary goal throughput (parallelizing many small tasks) or latency (reducing wait time for a single heavy task)?
  3. Error Resilience:
    • Are there SLAs for task completion? If so, how will retries/fallbacks be implemented (e.g., hybrid async + queue approach)?
  4. Monitoring:
    • How will child process health/performance be monitored (e.g., process count, memory usage, execution time)?
  5. State Management:
    • Are tasks stateless, or will shared memory (e.g., Redis) be required for coordination?
  6. Scaling:
    • Will this replace existing queue workers, or run alongside them? How will load be balanced?

Integration Approach

Stack Fit

  • Best For:
    • Laravel Monoliths: Ideal for replacing synchronous batch jobs (e.g., Artisan::call() loops) with parallel execution.
    • Microservices: Useful in PHP-based services where pcntl is available (e.g., API workers, data processors).
    • CLI Tools: Enhances Laravel’s Artisan commands for parallel CLI operations (e.g., php artisan process:parallel).
  • Poor Fit:
    • Windows-Only Environments: Without WSL or custom PCNTL polyfills, this is a non-starter.
    • Stateful Distributed Systems: If tasks require complex coordination (e.g., distributed locks), consider alternatives like Laravel Horizon or RabbitMQ.
    • Serverless: Not compatible with PHP-FPM or serverless platforms lacking pcntl support.

Migration Path

  1. Pilot Phase:
    • Start with non-critical, CPU-bound tasks (e.g., image resizing, report generation).
    • Replace synchronous loops with Async::parallel():
      // Before (synchronous)
      foreach ($files as $file) {
          processFile($file);
      }
      
      // After (parallel)
      Async::parallel([
          fn() => processFile($files[0]),
          fn() => processFile($files[1]),
      ]);
      
  2. Hybrid Approach:
    • Use Laravel Queues for retries and spatie/async for parallelism:
      Async::parallel([
          fn() => dispatch(new ProcessFileJob($file1)),
          fn() => dispatch(new ProcessFileJob($file2)),
      ]);
      
  3. Full Adoption:
    • Replace Artisan::call() in batch scripts with Async::run().
    • Migrate queue workers to use Async::parallel() for sub-tasks (e.g., parallel API calls in a job).

Compatibility

  • Laravel Versions: Compatible with Laravel 8+ (PHP 8.0+). Tested up to Laravel 11 (as of 2026).
  • PHP Extensions: Requires pcntl, posix, and proctitle. Verify with:
    php -m | grep -E 'pcntl|posix'
    
  • Dependencies: No conflicts with Laravel’s core or popular packages (e.g., laravel/framework, spatie/laravel-queue-s3).
  • Database: Agnostic; works with MySQL, PostgreSQL, SQLite, etc.

Sequencing

  1. Pre-Integration:
    • Add to composer.json:
      "require": {
          "spatie/async": "^2.0"
      }
      
    • Install pcntl and dependencies:
      pecl install pcntl
      docker-php-ext-install pcntl posix  # For Docker
      
  2. Core Integration:
    • Create a service class to wrap Async calls (e.g., app/Services/AsyncProcessor.php):
      use Spatie\Async\Async;
      
      class AsyncProcessor {
          public function parallelize(array $tasks, int $poolSize = 4) {
              return Async::parallel($tasks)->pool($poolSize);
          }
      }
      
    • Inject into controllers/jobs/commands via Laravel’s IoC.
  3. Testing:
    • Mock Async in unit tests (e.g., using Mockery or spatie/async's test helpers).
    • Test on a staging environment with pcntl enabled to validate process isolation.
  4. Monitoring:
    • Add logging for process IDs and execution times:
      Async::run(fn() => processData())->then(
          fn() => Log::info('Process completed', ['pid' => getmypid()])
      );
      
    • Use htop or ps aux to monitor process counts during load testing.

Operational Impact

Maintenance

  • Pros:
    • Minimal Boilerplate: The API is simple (e.g., Async::run(), Async::parallel()), reducing maintenance overhead.
    • No External Dependencies: Self-contained; no need to manage additional services (e.g., Redis for queues).
    • Laravel Native: Uses familiar Laravel patterns (e.g., closures, dependency injection).
  • Cons:
    • Debugging Complexity: Parallel processes introduce non-deterministic behavior. Debugging may require:
      • Logging process IDs (getmypid()).
      • Using strace -p <PID> to inspect system calls.
      • Implementing circuit breakers for critical paths
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport
twbs/bootstrap4
php-http/client-implementation
phpcr/phpcr-implementation
cucumber/gherkin-monorepo
haydenpierce/class-finder
psr/simple-cache-implementation
uri-template/tests