cachewerk/bref-laravel-bridge
Run Laravel on AWS Lambda with Bref. This bridge connects Laravel's HTTP kernel, queue workers, scheduler, and filesystem to Bref's serverless runtime, so you can deploy a familiar Laravel app without managing servers. Includes sensible defaults for serverless storage, logging, and configuration.
Architecture fit. cachewerk/bref-laravel-bridge is a thin adapter between Laravel and Bref's Lambda runtime. It fits an event-driven serverless topology: HTTP served by Lambda (php-fpm runtime), background work on SQS-triggered Lambda invocations, and schedule:run on EventBridge. It is a poor fit for workloads needing >15-minute execution, persistent connections, WebSockets, or high-throughput Redis queues where Lambda connection churn and VPC cold starts dominate.
The v0.3.0 change — replacing a bespoke queue handler with Laravel's native queue handler — is architecturally the correct direction. It collapses a fork of Laravel's worker loop back onto upstream behavior, which means --max-time, --rest, backoff, tries, job middleware, and the JobProcessing/JobProcessed/JobFailed event surface should now behave as documented rather than as the package author reimplemented them. For a TPM this trades one class of risk ("does the bridge behave like Laravel?") for another ("does Laravel's worker behave correctly under Lambda's execution model?"). The second is better understood and better documented, but it is not zero: Laravel's worker relies on pcntl signals (SIGALRM for --timeout, SIGTERM/SIGQUIT for graceful shutdown) and Lambda does not deliver a real SIGTERM before freezing or killing the sandbox. Graceful shutdown semantics are therefore best-effort, not guaranteed, regardless of handler.
Integration feasibility. High. Composer-installable, config-publishable, wired up through a handful of Bref function definitions. A team already running Bref can integrate in days, not weeks. The work is dominated by infrastructure configuration (SQS, EventBridge, IAM, DLQ, visibility timeouts) rather than application code.
Technical risk.
--max-time configuration instead of package-internal logic. This must be verified, not assumed.maxReceiveCount, in addition to Laravel's own tries/backoff. The two retry budgets interact and are a classic source of duplicate side effects. At-least-once delivery makes idempotency a hard requirement for every job.--max-time, or jobs will be processed concurrently by a second invocation while the first is still running.Key questions to resolve before adoption.
--max-time / --rest, or must the operator configure it? What happens on an unconfigured deployment — clean exit or hard Lambda kill mid-job?ReportBatchItemFailures so only failed SQS messages are retried, or does a single failure fail the whole batch?pcntl compiled into the Bref runtime in use, and does the worker degrade safely if signal handling is unavailable?Stack fit. Laravel 10/11, PHP 8.1+, Bref 2.x, AWS SQS + EventBridge + S3 + CloudWatch. Best fit for teams already standardized on AWS and Bref, with bursty or low-average background workloads. Explicit overlap warning: Laravel Vapor is the first-party paid serverless offering and solves the same problem with vendor support. If the organization is Vapor-eligible and support matters more than cost/control, this package is the wrong default. Adopt this only where Bref is already the platform standard or where Vapor's cost model is disqualifying.
Migration path. Stage it, do not big-bang it:
cachewerk/bref-laravel-bridge to an exact version; do not float ^0.3.schedule:run via EventBridge) as a separate function. Low volume, easy to verify, no queue semantics involved.Compatibility. Verify the Laravel version floor against the pinned release before committing; if the native-handler change raised it, this may force a framework upgrade, which changes the project's critical path entirely. Confirm pcntl and required extensions in the Bref runtime image. Confirm the package's expectations against the Bref major version in use — Bref 2.x changed runtime and function-definition conventions, and stale bridge docs frequently target 1.x.
Sequencing and gating. Gate production cutover on: (a) a soak test at realistic job volume, (b) a deliberate failure injection proving DLQ routing and idempotency, (c) a timeout test proving the worker exits before the Lambda limit, and (d) documented rollback to the prior deployment — Lambda aliases and weighted routing make this cheap; use them.
Maintenance. Net positive: the native-handler change removes bespoke queue-loop code from the dependency, which is exactly the code most likely to drift and break on Laravel upgrades. The residual maintenance burden is version-tracking — the bridge must keep pace with Laravel's worker internals, and pre-1.0 releases may break on minor bumps. Budget for a scheduled dependency review, not ad-hoc upgrades.
Support. Community package, no SLA, small maintainer base. Mitigations: (a) maintain an internal fork-ready posture — keep a patch branch and a documented composer override path; (b) wrap the package's integration points behind your own config/abstraction so it can be replaced; (c) treat it as one of several dependencies on the critical path and include it in supply-chain review.
Scaling. Lambda + SQS scales concurrency automatically, which relocates the bottleneck rather than removing it. The real ceilings are: AWS account concurrency limits and reserved concurrency, database connection pool exhaustion under fan-out, downstream API rate limits, SQS batch size vs. Lambda duration, and cold-start latency for the worker function (mitigate with provisioned concurrency only if justified by measured p99). For low-volume or spiky workloads this is a strong fit; for sustained high throughput, per-invocation overhead and connection churn usually lose to a long-running worker on ECS or EC2.
Failure modes to instrument and runbook.
ApproximateNumberOfMessagesVisible on the DLQ and on Lambda Errors/Throttles.maxReceiveCount is finite and DLQ retention is long enough for triage.ReportBatchItemFailures, one bad message re-drives the entire batch and multiplies duplicate work.Ramp-up. A Laravel developer new to serverless needs roughly one to two weeks to be productive here, and the curve is steeper than it looks because competence requires two mental models simultaneously: Laravel's queue lifecycle (dispatch, reserve, attempt, release, fail) and AWS's delivery lifecycle (receive, visibility timeout, redrive, DLQ). Most production incidents live in the seam between them, where engineers reason correctly about one model and incorrectly about the other. Plan for: a written runbook covering DLQ triage, timeout diagnosis, and rollback; a staging environment that actually exercises SQS rather than the sync driver; and at least one engineer who owns the queue semantics end to end. Do not distribute that ownership.
How can I help you explore Laravel packages today?