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

Http Client Laravel Package

amphp/http-client

A fully asynchronous HTTP/1 and HTTP/2 client for PHP built on Revolt, with no cURL dependency. It supports concurrent requests, connection pooling, redirects, compression, streaming bodies, cookies, and proxies through a composable interceptor API.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. amphp/http-client is a fiber-based, event-loop-driven HTTP client built on Revolt, not a drop-in replacement for Laravel's default Guzzle-backed Http facade. Laravel's request lifecycle (PHP-FPM or Octane workers) is fundamentally synchronous and request-scoped, while this package is designed for long-lived processes that own an event loop. The realistic fit is narrow and high-value: CLI-side workloads where fan-out concurrency dominates latency — bulk API aggregation, webhook/notification dispatch, third-party sync jobs, scraping/mirroring, and health-check sweeps. Inside a normal FPM request it is architecturally mismatched; inside Octane it competes with Swoole/RoadRunner's own loop rather than composing with it. The correct mental model is "a dedicated async worker library that happens to live in the same Composer project," not "a faster Guzzle."

Integration feasibility. Installation is trivial (composer require amphp/http-client), but integration cost is in the seams. Three friction points dominate:

  1. Type mismatch. Request/Response are mutable, non-PSR-7, and the client is not a PSR-18 implementation. Any Laravel code, middleware, or package typed against Guzzle/PSR-7 responses needs an adapter layer or a clean internal abstraction.
  2. No ext/curl. HTTP is implemented over raw TCP sockets with TLS via OpenSSL. This is a genuine advantage in restricted environments where cURL is unavailable or unwanted, but it means proxy handling (amphp/http-tunnel), TLS edge cases, and corporate egress behavior differ from what the platform team has already validated for Guzzle.
  3. Loop ownership. Under FPM, driving Revolt per request is wasteful and prone to lifecycle leaks; the viable deployment is a standalone Artisan command/worker or a queue job that deliberately runs the loop for its duration. nghttp2 FFI (optional, for HTTP/2 perf) requires ffi.enable, which is often disabled by security policy — treat it as a nice-to-have, not an assumption.

Technical risk. Medium. The library itself is mature, MIT-licensed, actively released, and standards-compliant with good failure-mode hygiene (documented inactivity timeouts, HTTP/2 window management, redirect policy). The risk is organizational: a small ecosystem relative to Guzzle/Symfony HttpClient, effectively a single-primary-maintainer bus factor, no first-class Laravel/Telescope/Horizon instrumentation, and a Dependents: 0 signal that — whether a data artifact or not — means few public reference implementations to crib from. Team risk is real: fibers and interceptors are a different debugging model, and stack traces through suspended fibers are harder to read than synchronous Guzzle failures.

Key questions.

  • What is the measured concurrency bottleneck? If a job makes 50 sequential calls at 200 ms each, that's a 10-second win — worth it. If it makes 5, it isn't.
  • Where will this run: FPM, Octane, standalone CLI worker, or queue job? This determines whether the package is viable at all.
  • Do we need PSR-18/PSR-7 interop for existing abstractions, or can we isolate behind our own interface?
  • Is ext/curl genuinely unavailable, or are we optimizing for a constraint we don't have?
  • Are the target endpoints HTTP/2-capable, and does corporate egress permit it?
  • What is the team's current fluency with Revolt/fibers, and who owns the internal wrapper?
  • Is FFI permitted in production, and does the perf case survive without nghttp2?
  • What is the contingency if upstream stalls — can we vendor/patch, and is the license compatible with that?

Integration Approach

Stack fit. Treat this as a specialized internal capability, not a platform-wide HTTP layer. Keep Guzzle (via Laravel's Http facade) as the default for request-scoped, blocking, observability-integrated calls. Introduce amphp/http-client behind a single internal contract, e.g. BulkHttpClient::fetchMany(array $requests): array, with the Amp implementation scoped to CLI workers and fan-out jobs. This contains blast radius and keeps the 95% of HTTP traffic on the path the team already knows.

Migration path. Nothing needs to migrate. This is additive. The sequencing that de-risks it:

  1. Measure — instrument the top 3–5 highest-volume outbound jobs and record call counts, p50/p95 wall-clock, and current worker concurrency.
  2. Prototype — one job, one endpoint family, Amp client vs. Guzzle Pool, same timeout/retry semantics.
  3. Benchmark honestly — wall-clock, memory high-water mark, connection count, failure rate under 429/5xx, and cost per 1k requests on the actual infrastructure.
  4. Abstract — land the BulkHttpClient interface with the Guzzle implementation first, so the Amp version is a swap, not a rewrite.
  5. Pilot — one production job, feature-flagged, with a kill switch back to the synchronous path.
  6. Expand — only by pattern, not by ambition.

Compatibility. Confirm PHP 8.1+ (fiber requirement) against the Laravel version matrix and any Octane/Swoole version pins. Verify OpenSSL availability and CA bundle configuration matches Guzzle's — this is the most common silent-breakage vector when switching from cURL. Verify proxy support needs against amphp/http-tunnel. Confirm the HTTP/2 egress path with the network team before assuming multiplexing benefits. If FFI is disabled, benchmark HTTP/1.1 keep-alive pooling as the baseline, since that may be the production reality.

Sequencing. Do not introduce both a new HTTP client and a new execution model (CLI workers) at once unless the target workload already runs in CLI. If the first candidate lives in an FPM request path, either defer it or restructure it into a queued job first — the queue refactor is the prerequisite, not a nice-to-have.

Operational Impact

Maintenance. Low-to-moderate code footprint, but non-trivial ownership. Semantic versioning is respected and the changelog is well-kept, so upgrade work is predictable. The real maintenance burden is the internal wrapper, adapter layer, and the async idioms the team invents — those are ours to maintain forever. Pin to a minor range and review releases on a quarterly cadence; avoid float-latest on a package with a single primary maintainer.

Support. Community support only (GitHub issues, AMPHP channels). There is no Laravel-native integration, no Telescope HTTP recorder, no Horizon-aware instrumentation. Budget for in-house instrumentation: request/response logging, timing, error classification, and correlation IDs. The LogHttpArchive HAR listener is a genuine gift here — it gives production-grade timing forensics that the Guzzle side typically lacks — but it writes files and can capture sensitive headers, so it needs a retention and redaction policy, not just a config flag.

Scaling. Strong on the dimension that matters: N concurrent calls collapse from N × latency to roughly max(latency). HTTP/2 multiplexing reduces socket and file-descriptor pressure versus N parallel curl handles, and connection pooling amortizes handshakes across a batch. Memory scales with in-flight bodies — streaming via Payload is the mitigation for large transfers, but it forces the team to be explicit about buffer-vs-stream, and the changelog shows this is a live tuning area (window sizes, slow consumers). Vertical, not horizontal: one process handles far more work, which is a cost win but also creates a fatter failure domain per worker.

Failure modes. The ones to plan for, in order of likelihood:

  • Loop not running / fiber never resumed → silent hang or timeout. The most common integration bug, and it looks like a network problem.
  • Timeout semantics differ from Guzzle. Connect, TLS, inactivity, and total-request timeouts are distinct and configured differently; teams routinely ship without setting them and get 300-second hangs. Interceptor-based SetRequestTimeout should be the default in the wrapper, not opt-in.
  • Interceptor ordering bugs. Cross-origin redirects drop application headers, and FollowRedirects being outermost means header behavior depends on where your interceptor sits. This is a subtle correctness trap for auth headers.
  • Silent body discard on redirects — previous response bodies are consumed, so any retry/audit logic that inspects them breaks.
  • TLS divergence from cURL. OpenSSL path may reject chains that cURL tolerated, or vice versa, producing a production-only outage invisible in staging.
  • Egress/proxy mismatch — no automatic HTTP_PROXY env handling equivalent to what Guzzle/curl provides.
  • Memory growth on slow consumers under HTTP/2 — historically an active fix area.
  • Worker starvation — a CLI job running the loop blocks that worker for the batch duration; if the batch is large, queue depth builds on the Horizon side.

Ramp-up. This is the dominant cost. Expect 2–4 weeks for one engineer to become genuinely productive, longer to become the team's authority on fibers, Revolt, and interceptor semantics. Debugging requires new habits: async stack traces, suspended-fiber states, and a mental model where "it returned" and "it completed" are different events. Mitigate by (a) confining the package to one or two owners, (b) publishing an internal wrapper with sane defaults so product engineers never touch HttpClient directly, (c) writing two or three reference examples mirrored on real jobs, and (d) keeping the Guzzle path alive as a documented fallback so a stalled adoption doesn't become a stalled roadmap.

Net TPM read. Worth pursuing if — and only if — the measured workload has genuine fan-out concurrency in a CLI/worker context and the team can absorb the async learning curve. The score profile (low overall, high opportunity) matches that read: high ceiling for the right use case, poor general-purpose return, and a real cost in organizational attention. Approve as a scoped spike with a hard checkpoint at the benchmark stage; reject as a platform-wide HTTP 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.
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
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