Weave 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

File Laravel Package

amphp/file

amphp/file provides non-blocking file access for PHP 8.1+ applications built with fibers and concurrency. Read, write, and stream files without blocking, using process, thread, or extension-based drivers for responsive I/O.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. amphp/file is a fiber-based non-blocking filesystem layer built on Amp v3 and Revolt. Laravel's default request lifecycle is synchronous (php-fpm/mod_php), which means the package's core value—keeping the event loop responsive during I/O—provides little benefit in the standard Laravel deployment. Value only materializes in long-lived process models: Laravel Octane (Swoole/RoadRunner), queue workers doing parallel file I/O, or Octane-hosted streaming/export endpoints. In those contexts, the package's File handles, seek()/tell(), and the newly added lock()/tryLock()/unlock() (v4.0.0) offer genuinely useful primitives that plain file_get_contents() cannot. However, the package does not integrate with Laravel's Filesystem/Flysystem abstraction, so the "fit" is really "an escape hatch for hot paths," not a replacement for Storage:: or File::.

Integration feasibility. Composer-installable, MIT-licensed, PHP 8.1+ — all compatible with modern Laravel (10/11/12). No hard extension requirements; falls back to a blocking driver if eio/uv/parallel are absent, but that fallback defeats the purpose. Real integration requires: (1) a service provider to bootstrap a FilesystemDriver singleton, (2) adapters bridging Amp\File\File to Laravel's Illuminate\Filesystem contracts where callers expect them, and (3) careful coordination with whichever event loop the runtime uses. Octane's Swoole/RoadRunner loops are not Revolt, so there is a genuine question of whether Amp's event loop can be safely entered inside an Octane worker request. That integration seam is the primary feasibility risk.

Technical risk. Medium-to-high for the intended deployment targets:

  • Event loop contention. Running Revolt's loop under Swoole or RoadRunner can deadlock or silently degrade to blocking; Octane's event worker is not designed for nested async runtimes.
  • Worker pool lifecycle. The v4 ParallelFilesystemDriver creates its own LimitedWorkerPool; in long-lived Octane workers this pool must be managed per-worker and torn down on reload, or you leak child processes.
  • Fiber context leakage. Amp callbacks capture request()/container state; anything that touches the fiber after the request ends can access stale container state—a well-known Octane pitfall that this package makes more likely.
  • Debug surface. Stack traces across fibers and worker processes are materially harder to reason about than synchronous fopen.

Key questions.

  • Which concrete Laravel paths justify non-blocking I/O (large exports, log shipping, artifact streaming, media pipelines)? If none are hot, the ROI is negative.
  • Is the target Octane (Swoole/RoadRunner) or classic FPM? Only the former makes this package's premise viable.
  • Do we have a documented adapter strategy between Amp\File\File (which implements ReadableStream/WritableStream) and Illuminate\Filesystem / League\Flysystem\FilesystemOperator? If we shim incorrectly, we break the Storage facade contract.
  • What is the acceptable failure mode when the parallel driver pool is exhausted—queue, block, or throw?

Integration Approach

Stack fit. Poor as a broad replacement; viable as a targeted utility. In an Octane-hosted Laravel app, amphp/file can slot into: (a) streaming downloads/exports where a File handle is piped into Response::stream() or StreamedResponse, (b) queue jobs that currently file_get_contents many small files serially (S3 mirrors, log aggregation, media thumbnailing), and (c) a KeyedFileMutex wrapper around concurrent writers where flock() would otherwise block. It does not fit as the backend for Storage, File, or Flysystem — those contracts assume synchronous semantics and would need a parallel adapter layer that increases risk without replacing the existing API for callers.

Migration path. Do not migrate; introduce incrementally.

  1. Wrap the driver behind an internal interface (AsyncFilesystem) so application code depends on us, not Amp\File directly.
  2. Keep Illuminate\Support\Facades\Storage as the default; add the async path only where the profiling data shows blocking I/O is a bottleneck.
  3. Gate the async path behind a feature flag keyed per job/endpoint so rollback is a config change, not a deploy.
  4. If/when Octane is adopted, evaluate the async path in isolation before enabling globally.

Compatibility. Composer constraints are clean (php >=8.1, revolt/event-loop, amphp/amp ^3, amphp/byte-stream ^2). The friction points are runtime, not package version: PHP 8.1 is now below Laravel 12's effective floor, so pin to the latest 4.x; and ext-eio/ext-uv/ext-parallel availability varies across hosting (Forge, Vapor, container images) — Vapor is essentially a non-starter since Lambda freezes after the response and child worker pools cannot survive. Forge/Docker is fine if the extensions are baked in.

Sequencing.

  1. Instrument first. Add timing instrumentation around existing blocking file calls to prove the bottleneck. Do not skip this—opportunity score is 44.97 with 110 stars and 0 listed dependents; adoption evidence is thin.
  2. Pilot one endpoint. Pick a single high-volume read path (e.g., a large CSV export streamed via StreamedResponse) under Octane. Measure p95 latency and memory under load.
  3. Decide on the event loop model. If Amp's Revolt loop cannot be cleanly nested inside Octane's Swoole loop, the pilot fails and the initiative should stop. This is the go/no-go gate.
  4. Adapter build. Only after a passing pilot, build the AsyncFilesystem adapter and the Storage-to-File bridge.
  5. Expand per use case, never globally.

Operational Impact

Maintenance. Low-to-moderate on the package itself — AMPHP's release cadence is disciplined, semver is respected (v3→v4 had a narrow breaking surface: custom File implementations and ParallelFilesystemDriver construction), and the maintainers are responsive. The maintenance burden lands on our adapter code and on keeping the driver pool lifecycle correct across Octane reloads. Realistically, treat the integration layer as owned code that requires quarterly review against AMPHP and Octane releases.

Support. The package has no commercial backing; support is the GitHub issues queue and the AMPHP Discord. Documentation is thin on operational topics: no guides on pool sizing, no Octane integration notes, no failure-mode documentation. For a TPM, that means we carry first-line support for our own engineers. The v4 release notes are informative but not operationally prescriptive.

Scaling. Scaling behavior depends entirely on the driver. The default parallel driver spawns child PHP processes; under high concurrency this can multiply process counts per Octane worker, and the LimitedWorkerPool sizing becomes a tuning parameter we must own. eio and uv avoid the process overhead but require PECL builds in every environment. The blocking fallback scales exactly like today (i.e., it does not solve the problem). Horizontal scaling of Octane workers plus vertical sizing of the file worker pool is the practical ceiling.

Failure modes. The realistic set: (1) worker pool exhaustion leading to queued or timed-out file operations; (2) leaked file descriptors from unclosed File handles — the README's close() advice is easy to miss under exceptions, and PHP's GC will not reliably clean up fibers holding open handles; (3) event-loop nesting failures under Octane causing silent blocking or deadlocks; (4) stale container/fiber state across requests, manifesting as authentication or tenant leakage — the highest-severity failure mode; (5) extension-related bugs, mitigated by preferring eio/uv and pinning versions. Every one of these should have an observability hook before the first line of integration code is written.

Ramp-up. The API is small and intuitive (read(), write(), openFile(), File methods mirror the standard library), so a mid-level Laravel engineer can use it in an afternoon. The hard part is not the API — it's operational literacy: understanding Revolt, fiber semantics, where await boundaries matter, how the multi-process driver interacts with Octane's worker model, and why close() on every path is mandatory. Budget one focused engineer-week for a senior dev to produce an internal standard and a working reference implementation; budget ongoing time for that engineer to remain the owner.

Bottom line. A well-built, narrowly useful package that is the wrong abstraction for most Laravel applications and a credible accelerator for a small subset. Recommend a time-boxed pilot against a single Octane-hosted streaming workload, gated on the event-loop nesting question and on profiling data that proves blocking file I/O is actually a bottleneck. Do not adopt as a Storage replacement.

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.
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator