Download the PHP package laith343/laravel-fcm-blast without Composer

On this page you can find all versions of the php package laith343/laravel-fcm-blast. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package laravel-fcm-blast

laravel-fcm-blast

laith343/laravel-fcm-blast

Packagist Version PHP Version

High-throughput Firebase Cloud Messaging sender for Laravel. Pushes 10k+ req/s from PHP by driving a reused curl_multi handle pool with persistent TCP — OAuth handled by kreait/firebase-php, delivery handled by the engine.

This package is backend only. It exposes a programmatic API and a status DTO; build whatever UI/monitoring you want on top of status().

Contents

Requirements

Requirement Version Why
PHP ^8.3 Engine + typed contracts.
Laravel (illuminate/*) ^12.0 | ^13.0 Queue, Eloquent, container, facades.
ext-curl * curl_multi is the delivery engine.
ext-json * Payload encoding.
kreait/firebase-php ^7.0 Service-account OAuth token minting.
Redis Queue connection; required for the stale-job purge on start.
Database Postgres / MySQL Holds the per-run counters. The engine flushes atomic col = col + delta updates concurrently from every worker.

SQLite caveat: fine for the test suite and single-worker dev runs, but its single-writer lock serializes the concurrent counter flushes — do not use it for multi-worker production blasts. Use Postgres or MySQL there.

Supported versions

Package PHP Laravel
0.x 8.3+ 12.x, 13.x

Install

Configure

config/fcm-blast.php:

Real FCM needs HTTP/2. Over HTTP/1.1 every in-flight request needs its own TLS connection, so high concurrency to fcm.googleapis.com exhausts sockets (timeouts, broken pipes). http_version => '2tls' (the default) multiplexes thousands of requests over a handful of connections — set max_host_connections to something small (8-32). 2tls automatically uses HTTP/1.1 for plain-http endpoints, so a local mock is unaffected and can keep its many-connections setup (max_host_connections => null).

Environment variables

Every config key has an env override:

Env var Default What it does
FCM_BLAST_CREDENTIALS Service-account JSON path or string. Empty = fake-token mode (mock testing).
FCM_BLAST_PROJECT_ID Firebase project id; builds the FCM v1 endpoint.
FCM_BLAST_ENDPOINT Override endpoint. Empty = real FCM. Set to a mock URL for load testing.
FCM_BLAST_RATE_CAP 10000 Global sends/sec cap, split across workers (10000 = 600k/min).
FCM_BLAST_RATE_BURST 5% of rate Max instantaneous burst per worker (paced limiter). Lower = smoother; doesn't change sustained rate.
FCM_BLAST_MAX_HOST_CONNECTIONS 16 TCP connections per worker. Null = rateCap*0.3 (HTTP/1.1 mock).
FCM_BLAST_MAX_CONCURRENT_STREAMS 100 Max concurrent HTTP/2 streams per connection (FCM drops >~100).
FCM_BLAST_HTTP_VERSION 2tls 2tls (HTTP/2 over TLS, 1.1 over cleartext), 2, or 1.1.
FCM_BLAST_MAX_RETRIES 5 Attempts per token for 429/503 + transient transport errors.
FCM_BLAST_QUEUE fcm-blast Queue name the jobs run on.
FCM_BLAST_CONNECTION redis Queue connection (must be redis for stale-job purging).

max_host_connections is per worker. Total connections to FCM = workers × max_host_connections. In-flight capacity per worker = max_host_connections × max_concurrent_streams (the engine sizes its concurrency to exactly this).

Sizing for your target RPS

Throughput is governed by Little's Law:

To hit a target RPS, make capacity ≥ in-flight needed, and keep FCM_BLAST_RATE_CAP at the rate you want (it caps emission so you never exceed it).

Worked example — 10,000 RPS (600k/min):

avg latency in-flight needed example config (capacity)
300 ms 3,000 4 workers × 8 × 100 = 3,200
600 ms 6,000 4 workers × 16 × 100 = 6,400
1,000 ms 10,000 4 workers × 25 × 100 = 10,000

with 4 workers → 6,400 in-flight, enough for 10k RPS up to ~640ms latency; rate_cap then holds the ceiling at 10k.

Three real limits, in order of what you'll hit first:

  1. Network egress — a single host (especially residential/cellular) tolerates only so many simultaneous connections. Failures show as transport errors (timeouts/resets), now auto-retried. Keep max_host_connections to what your link handles; scale out across hosts for more.
  2. Latency — higher latency needs more in-flight for the same RPS. Measure avg_latency_ms from a run and plug it into the formula.
  3. FCM project quota — above it, FCM returns 429/503 (the throttled counter). Check/raise it in Google Cloud Console → IAM & Admin → Quotas → "Firebase Cloud Messaging API".

Don't over-provision connections. Use the smallest connections × streams that covers your latency — extra connections only increase the handshake burst (more transport failures) without raising throughput, since rate_cap is the real ceiling.

Integrate

Implement two contracts. The package never touches your database directly.

Per-token context (localization, custom logic)

To tailor the message per user, have your TokenSource yield an OutboundToken (token + arbitrary context) instead of a plain string. The context reaches build() unchanged. It's fully optional — yielding a string keeps $context null, so existing sources/builders are unaffected.

context can be any value (array, DTO, model) — it's passed in-process, not serialized.

Per-run context (which campaign am I serving?)

Per-token context covers the message; per-run context tells the resolved TokenSource / MessageBuilder / InvalidTokenHandler instances which run they're serving. Workers resolve those classes from the container with no arguments, so without this they can't know the campaign. Implement ContextAware and pass the payload via withContext():

The context travels through the queued job, so it must be serializable (arrays/scalars, or SerializesModels-friendly values) — unlike per-token context, which stays in-process. Opt-in: classes that don't implement ContextAware are untouched.

Optional — prune permanently invalid tokens (FCM 404/400):

Per-request debug logging

Enable to capture every request's full body, context, outcome, HTTP code and latency for later debugging:

Output is one NDJSON record per request, in a daily-rotated file (fcm-blast-requests-YYYY-MM-DD.log):

Performance: records are buffered in memory and appended in bulk on the engine's existing 0.5s flush tick (with a hard buffer cap), so the send loop does one file append per half-second per worker — not one write per request. This is far cheaper than a per-request log queue (which would dispatch more jobs than the sends themselves), so logging stays in the worker. Keep it off in production unless actively debugging.

Run a blast

start() returns the run id. Spin up one queue worker process per worker — the process count must match the workers arg, since each job streams its own non-overlapping slice of the tokens.

Run locally

For development you don't need real Firebase credentials. Two modes:

1. Fake-token mode — leave credentials empty. The token provider returns a dummy bearer instead of minting a real OAuth token, so you can exercise the full dispatch/queue/counter pipeline without Firebase:

2. Mock endpoint — point the sender at a local HTTP server to load-test the engine without hitting FCM. Over plain http the 2tls setting auto-falls back to HTTP/1.1, so let the pool grow:

Start a worker and kick off a blast (one worker shown):

For multiple local workers, start that many queue:work processes:

Linux / macOS (bash/zsh)

Windows (PowerShell)

Run the test suite:

Run in production

Run the workers under a process supervisor instead of by hand, and make the process count match the workers you pass to start().

Supervisor (Linux)

/etc/supervisor/conf.d/fcm-blast.confnumprocs=4 must match the workers you pass to start():

macOS (Homebrew supervisor)

Use the same [program:fcm-blast] block as above, adjusting command to your artisan path and user to your account.

Windows (production)

PowerShell Start-Process is fine for ad-hoc runs. For a managed service, wrap each queue:work in NSSM or run the workers inside WSL/Docker under Supervisor as above.

Monitor

throttled vs transportRetries tells you which ceiling you're hitting: throttled climbing = FCM project quota (request more); transportRetries climbing = network/connection limits (fewer connections, scale hosts). Both are retried automatically and only become failed once max_retries is exhausted.

A Laith343\FcmBlast\Events\FcmBlastCompleted event fires when a run finishes — listen for it to trigger follow-up work.

How it hits 10k RPS

Ephemeral port range (one-time host tuning)

At thousands of RPS the OS can run out of ephemeral ports for outbound connections. Widen the range once:

Windows (admin PowerShell)

Linux

macOS

The reused handle pool keeps sockets alive across requests, so this mainly matters during connection ramp-up and on hosts under other network load.


All versions of laravel-fcm-blast with dependencies

PHP Build Version
Package Version
Requires php Version ^8.3
ext-curl Version *
ext-json Version *
illuminate/contracts Version ^12.0|^13.0
illuminate/support Version ^12.0|^13.0
illuminate/database Version ^12.0|^13.0
illuminate/queue Version ^12.0|^13.0
illuminate/console Version ^12.0|^13.0
kreait/firebase-php Version ^7.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package laith343/laravel-fcm-blast contains the following files

Loading the files please wait ...