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

Process Laravel Package

amphp/process

amphp/process is an asynchronous process dispatcher for PHP 8.1+ built on the Revolt event loop. It runs child processes on all major platforms, including Windows, with non-blocking access to stdout and stderr, plus support for custom working directories and environment variables.

View on GitHub
Deep Wiki
Context7

Product Decisions This Supports

  • Build vs. buy on subprocess plumbing. The default state of most Laravel codebases is a scattering of exec(), shell_exec(), and proc_open() calls hidden in jobs, Artisan commands, and service classes — each with its own escaping bugs, its own timeout story, and no consistent way to stream output. This package is the "buy" option: a maintained, MIT-licensed abstraction covering process start, non-blocking stdin/stdout/stderr, exit codes, working directory, environment, signals, cancellation, and Windows parity. The decision it informs is whether subprocess handling becomes a standardized internal layer or stays ad hoc.
  • Roadmap scoping for process-heavy features. Anything that shells out to a tool — ffmpeg transcoding, PDF/office document rendering, image processing, git and deployment operations, log tailing, headless-browser or CLI-based scraping, static analysis runs, sandboxed code execution — carries a hidden spec decision: serial (simple, blocks a queue worker) versus concurrent (faster, more moving parts). Knowing an async dispatcher is available changes what latency and throughput you can credibly put in a spec.
  • Capacity and cost modeling. With blocking subprocess calls, concurrent children are capped by queue worker count, and raising that ceiling means more Horizon workers and more containers. An async dispatcher decouples "children running at once" from "PHP workers running," which is a real infrastructure-cost lever for bursty, I/O-bound workloads. That is a line item a PM can defend in a planning conversation.
  • Platform-parity commitments. Windows support is not a footnote here — the package ships a dedicated process wrapper specifically because Windows pipes are file handles and can't be polled non-blockingly. If your product is distributed to on-prem customers, Windows dev environments, or desktop-adjacent tooling, this materially changes whether a feature is shippable at all versus "Linux only."
  • Reliability commitments you can make in an SLA. Cancellation support on Process::join(), signal handling (getSignalName(), added in 2.1.0), and a documented history of fixing zombie processes under PHP-FPM and hung-process cases on Windows are the difference between "we run child processes" and "we can promise graceful shutdown, bounded runtimes, and no orphaned processes." Those are operational promises with product consequences.
  • Ecosystem-risk decisions. Adoption means adopting fibers, Revolt, and amphp/byte-stream alongside it. The defensible PM position is usually: adopt at the edges (a background worker, an internal CLI tool, a media pipeline) behind a narrow internal interface, rather than propagating Amp primitives through application code.

When to Consider This Package

Consider it when:

  • You are already inside the AMPHP ecosystem — amphp/http-client, amphp/socket, amphp/mysql, or any Revolt-based service. Here it is the obvious, idiomatic choice and adds no new paradigm.
  • You need to run many child processes at once and blocking one worker per child is the actual bottleneck (transcoding farms, batch document generation, fan-out scraping, parallel test or analysis runners).
  • You need to consume output incrementally while the process runs — live log tailing, streaming progress to a browser via SSE/websockets, or feeding a child's output into another stage as it arrives rather than buffering it all.
  • You are building a long-lived PHP daemon or supervisor that must start, monitor, signal, and reap child processes for hours, including graceful shutdown.
  • Windows is a first-class target, not an afterthought.
  • You are on PHP 8.1+ and the team is comfortable with fiber-based concurrency, or you can hide it behind an interface so most of the team never touches it.

Look elsewhere when:

  • The common case is one short command, awaited, inside a request or a single queue job. Laravel's built-in Process facade (Symfony Process underneath) is simpler, blocking is fine, and it needs no new dependency or mental model.
  • The team has no async PHP experience. Fiber-based code has different failure modes — suspension points, cancellation semantics, event-loop starvation — and debugging them under production pressure is real cost that outweighs the throughput gain.
  • You want a large, well-trodden community with abundant Stack Overflow answers and blog posts. Symfony Process wins decisively there; this package has 260 stars and, by this dataset's count, zero dependents. That last number is almost certainly undercounted (transitive use through other amphp packages isn't tracked well), but it is not evidence of broad adoption, and an org with a dependency-approval bar will notice.
  • You need isolation or sandboxing. This is a dispatcher, not a security boundary — it runs the command you give it with the permissions you have. Untrusted code needs containers, cgroups, or a purpose-built sandbox.
  • You need resource limits, cgroup accounting, or container orchestration. Use the platform, not a PHP library.
  • You need a hard timeout as a simple, declarative config knob. Cancellation exists but composition is your responsibility; Symfony Process's setTimeout() is a one-liner most teams already know.

How to Pitch It (Stakeholders)

For executives — one paragraph. amphp/process is a small, MIT-licensed PHP library for running and supervising child processes without freezing the application while they run. It is infrastructure glue, not a product feature: it replaces hand-rolled exec()/proc_open() code with a maintained abstraction that works identically on Linux, macOS, and Windows, supports streaming output and cancellation, and has a multi-year release history with steady bug-fix maintenance. Cost is effectively zero (no license, no service), and the strategic value is that process-heavy features — media processing, document generation, deployment tooling — become cheaper to run and possible to offer to Windows customers. The main risk is ecosystem concentration, which we contain by wrapping it behind an internal interface and piloting it in one non-critical worker.

For engineering — the case. One subprocess layer instead of N bespoke ones: consistent argument escaping, consistent environment and working-directory handling, non-blocking stdout/stderr through Amp\ByteStream with real backpressure, exit codes via Process::join(), cancellation via Cancellation, signal support, and a track record of fixing exactly the bugs you would otherwise hit — zombie processes under PHP-FPM (2.0.2), hangs on Windows when a child crashes (1.1.9), premature join() resolution when a child traps termination signals (1.1.0). Stable 2.x targets PHP 8.1+ and Revolt v1.x with a clean fiber-based API. The cost is adopting fibers and Revolt in the modules that use it; keep that surface small.

For engineering — the counter-case we should acknowledge. Laravel already depends on Symfony Process, and most teams' subprocess needs are "run one command, wait, read the exit code." For that, adding an async runtime is over-engineering. Reach for this package when concurrency, streaming, or long-lived supervision is the actual requirement — and only where the team can debug fiber-based code.

Recommendation. Treat as a contained, opportunistic adoption: wrap it behind a single internal ProcessRunner-style interface, pilot it on one throughput-sensitive workload (a media or document pipeline) with clear before/after numbers on wall-clock time and worker count, and keep the blocking Laravel/Symfony path as the default for ordinary one-shot commands. Revisit only if the dependency-count concern becomes an approval blocker, in which case the wrapper makes swapping out a contained change rather than a rewrite.

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.
gmostafa/php-graphql-client
xeviant/paystack
snowsoft/faker
meditationsteps/blogetc
animalyoung/laravel-influxdb
onix-solutions/sms-telera
lonely-lights/prosetta
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log