
A dashboard showing 5,000 connected drivers proves very little if the locations stop moving when passengers subscribe. Tracking capacity depends on how frequently drivers publish, how many people receive each update, and whether disconnected devices regain current state. An idle socket count leaves those questions unanswered.
This article defines a reproducible Laravel Reverb load-test plan, not a completed benchmark. No verified run artifacts accompany it. Every workload quantity, duration, and acceptance target proposed below is a hypothetical planning assumption, not a measured result, customer deployment, or capacity guarantee. Replace those assumptions with a documented forecast or observed product telemetry before making a release decision.
The intended output is a repeatable experiment: another engineer can reconstruct the environment, generate the same traffic, inspect failed deliveries, and understand the limit reached. A useful result describes a workload the complete tracking service can sustain, including recovery, rather than presenting Reverb as an isolated connection counter.
Define what the tracking promise measures
Start with the dispatch decision. A passenger wants to know where the assigned vehicle was last observed; a dispatcher wants to identify a driver whose feed stopped updating. Neither needs a reassuring green dot backed by an old coordinate. Define “current” and “stale” in terms the product can display and the experiment can measure.
For an illustrative test contract, require the 95th percentile of server-accepted updates to reach authorized subscribers within two seconds during the steady phase. Separately measure the age of the latest accepted position visible for each active trip. These are hypothetical targets for discussion, not recommendations for every operation. A five-second publishing interval alone can make a position several seconds old even with negligible delivery latency.
Record acceptance criteria before starting. Include permitted delivery failures, reconnect recovery, queue age, and resource headroom, plus failures that invalidate a run. An unauthorized location disclosure should fail correctness regardless of the latency percentile. Generator saturation should make the experiment inconclusive rather than count as proof of server capacity.
Count drivers, connections, and messages separately
Use a simple hypothetical baseline first: 5,000 simulated drivers each submit a location every five seconds. That produces 1,000 attempted updates per second before retries. It does not establish that all drivers need a WebSocket connection. Drivers might upload over authenticated HTTP while Reverb delivers updates to observers.
If the product also keeps a driver socket open for assignment changes, count those sockets separately. Add passenger sessions, dispatcher sessions, and support observers. A passenger opening the trip on two devices may create additional connections; a dispatcher can subscribe to many trips through one connection. Subscription count and connection count are different measurements.
Then define a hypothetical delivery mix. If each update reaches one passenger and two dispatch views, the baseline generates 3,000 intended location deliveries per second. That calculation excludes protocol messages, retries, and other application events. Measure actual serialized bytes and wire traffic rather than multiplying coordinate size and calling the result network demand.
For the next scenario, distinguish moving, waiting, and offline drivers. Apply independent starting offsets and reproducible jitter so every device does not transmit on the same artificial timer. Keep a synchronized burst as a separate stress case. The courier delivery app blueprint helps identify which real roles the test must represent.
Specify the message path before selecting tools
Write down the actual route: simulated device, ingress endpoint, validation, current-location store, broadcast job, Reverb, authorized subscriber, and rendered marker. Some systems omit a queue or use a broker for ingestion. Test the architecture being considered, and identify every shortcut in a comparison run.
Laravel's broadcasting documentation distinguishes queued broadcast events from the synchronous ShouldBroadcastNow path and explains private-channel authorization. An HTTP response acknowledging location ingestion is not an acknowledgement that a passenger received it. A successful broadcast request is also not evidence that the map rendered the coordinate.
Use separate experiments to isolate expensive segments. A direct publisher-to-Reverb run can establish a transport baseline. The release candidate must also pass through its normal authentication, validation, persistence, and broadcasting path. Label these results differently; otherwise a fast transport result can conceal an overloaded queue or database.
Include transaction boundaries in the review. If a broadcast depends on committed trip state, ensure the event cannot expose an update based on a transaction that later rolls back. The exact implementation belongs with the application's Laravel development plan, while the benchmark must verify the resulting behavior.
Give synthetic events enough identity to verify them
Generate fictional tenants, trips, drivers, and passenger accounts. Use a fixed seed and synthetic routes rather than replaying identifiable customer journeys. State which route properties matter: movement speed, stationary periods, zone changes, and points deliberately made invalid. Avoid contacting live dispatch, notification, payment, or messaging integrations from the test environment.
Each accepted event should carry an opaque trip reference, session identifier, sequence, captured time, accepted time, and schema version. Scope sequence comparisons to the correct driver session so restarting a device does not make every new point appear older. Retain the last accepted sequence in the authoritative state used for recovery.
Use the generator's ledger to reconcile attempted, accepted, rejected, and observed events. For each intended recipient, distinguish received, late, duplicated, and missing deliveries. If the product deliberately coalesces superseded points, record that category separately instead of calling it accidental loss or claiming that every point was delivered.
Validate out-of-range coordinates, malformed identifiers, unreasonable timestamps, and oversized bodies before normal broadcasting. Test a delayed old point arriving after a newer one. It must not move the authoritative location backward merely because its request arrived later.
Keep authorization in the measured workload
Create identities with representative tenant and trip relationships. Reusing an administrator token across all simulated users bypasses the work and restrictions the application will need. Measure the channel authorization endpoint independently, including its database or cache dependencies, because reconnects can turn it into a busy HTTP service.
Attempt cross-tenant subscriptions, guessed trip identifiers, expired credentials, and passenger access after the trip's tracking window ends. Verify denial by observing that no protected event arrives, not only by reading a response code. Test revocation on an already subscribed connection; authorization at subscription time does not automatically prove that later permission changes terminate existing access.
Use secure transport and explicit browser origin controls alongside identity checks. Origin validation does not authorize a passenger to see a trip. The OWASP WebSocket Security Cheat Sheet covers transport, origin, session, message validation, and resource-exhaustion controls. Exercise the controls configured for your client protocol rather than assuming an upgrade handshake provides them.
Separate security abuse traffic from ordinary load in the results. A bounded flood or oversized-message test should show whether enforcement protects legitimate tracking, while preserving enough capacity to inspect the rejection behavior. Use only the isolated environment authorized for the experiment.
Pin the environment and inspect effective limits
Record framework, Reverb package, PHP, Redis, client, and generator versions alongside dependency lockfiles. This plan references Laravel 12.x documentation to match the existing article's implementation context; it does not describe 12.x as the latest release. A different version requires its own checked configuration and repeat run.
Laravel's Reverb production guidance describes open-file limits, event-loop choices, proxy configuration, process management, and Redis-based horizontal scaling. Its default stream_select loop has an open-file limitation; the documentation identifies ext-uv as an alternative. Confirm the active loop in the actual running process rather than assuming an installed extension is being used.
Capture effective process and container limits, CPU allocation, memory, open descriptors, proxy connection capacity, idle timeouts, TLS termination, and network placement. A reverse proxy can require resources for both client and upstream connections. Do not treat its connection setting as a direct count of drivers supported.
Check the traffic generators too. Ephemeral ports, network translation, TLS work, and operating-system limits can restrict the clients before Reverb saturates. Document which host owns each connection leg. Increasing a limit without locating the constrained process produces an unreproducible tuning story.
Build a generator that speaks the application protocol
A raw WebSocket connection is insufficient for a Reverb subscription test. The harness must handle the application's protocol handshake, subscription acknowledgements, authorization, heartbeats, disconnects, and event envelopes. A successful HTTP upgrade does not mean a passenger joined the correct private channel.
Grafana's k6 WebSocket guidance recommends the k6/websockets module for new tests. Whichever tool you choose, verify its protocol behavior against the application's real client before scaling. A small functional run should prove that each synthetic passenger receives only assigned trips and that intentional invalid subscriptions fail.
Calibrate the harness with known event counts and controlled delays. Monitor generator CPU, memory, network use, timer lateness, and connection failures. Split the same offered load across additional generator hosts and compare results. If the result changes substantially, investigate the harness rather than declaring that more test machines improved server performance.
Schedule location arrivals independently of response time. If a driver simulator waits for each response before scheduling its next update, an overloaded service can receive less work just when the test should reveal the overload. Record planned and actual send times, including attempts the generator could not issue on schedule.
Measure latency without losing missing events
Assign timestamps to ingress acceptance, queue availability, worker start, broadcast request completion, and subscriber receipt. Add client-render timing in a smaller representative device test. Report what each interval spans; do not call worker execution time “end-to-end latency.”
Use monotonic clocks for durations inside one process. Synchronize hosts and record clock offsets for cross-host comparisons. Device-captured timestamps are useful for freshness but cannot be assumed accurate. Include synthetic clock skew so the server and interface demonstrate how uncertain timestamps are handled.
Report median, tail percentiles, timeouts, and the share exceeding the agreed objective for each phase and recipient type. Missing events do not contribute a normal latency sample, so publish their count beside the latency distribution. A low percentile among successful receipts can coexist with substantial missing delivery.
Measure current-location age throughout each observer session, including intervals with no messages. This catches the passenger who silently stops receiving updates while everyone else's receipt samples remain fast. Track connection setup, subscription readiness, and first usable snapshot separately from ordinary update delivery.
Keep metric labels bounded. Putting every trip identifier into a continuously exported time series can make the monitoring system itself expensive and difficult to query. Aggregate by scenario phase, recipient role, node, and outcome; retain sampled event identifiers in a separate reconciliation artifact with controlled access. Confirm the measurement pipeline can keep up before interpreting a flat chart as stable traffic.
Report the monitoring overhead as part of the environment. Full message logging, verbose protocol debugging, and per-event database writes can alter the workload being measured. Run a small comparison with the intended production instrumentation and the detailed diagnostic mode, then explain which mode produced the published result. Preserve failure examples without exporting credentials or precise personal routes.
Exercise queues as an independent capacity boundary
Broadcast workers compete with other jobs unless deliberately separated. Put tracking on an identified queue with known worker allocation, then measure incoming job rate, completed jobs, oldest waiting job, retries, and failed jobs. Queue depth alone is ambiguous: the same count can represent a brief burst or a growing delay.
Pause the tracking workers while ingestion continues, then resume them under controlled conditions. Determine whether the product should send every historical point or discard superseded points and refresh current state. The correct answer depends on the workflow: a live marker and an auditable route history need different retention and delivery semantics.
Inspect payload construction as well. A queued job that reloads “latest location” when executed may publish a different value from the accepted event it supposedly represents. Either publish the intended immutable event or define the job as a current-state notification, then make reconciliation match that definition.
Laravel's queue documentation explains worker timeouts, retry settings, and worker restarts. Align those settings and make handlers tolerate duplicate processing. Adding workers is not a substitute for checking database contention or a downstream broadcast service already at its limit.
Test slow consumers and bounded backlog
A dispatcher watching many active trips can receive more updates than a passenger. Introduce slow readers, constrained bandwidth, and a client that stops consuming while its socket remains connected. Watch per-connection backlog where measurable, process memory, write failures, and the effect on healthy observers.
Choose an overload policy before the stress run. For replaceable position updates, the application might reduce publication frequency or coalesce to the latest point. It must preserve trip transitions and other events whose loss would change business state. Reverb transport does not decide which events your product can safely omit.
The browser WebSocket API does not provide automatic backpressure for incoming messages. Measure browser work and memory separately; do not interpret an outbound bufferedAmount value as a complete measure of inbound backlog. Test bounded client update queues and a snapshot refresh when the client falls too far behind.
Acceptance requires predictable degradation. A slow dispatcher should not trigger unbounded memory growth or leave passengers frozen indefinitely. If the chosen architecture cannot expose useful backlog signals, report that observability limitation and use indirect measurements rather than inventing a queue metric.
Scale through Redis after establishing a baseline
First measure a single-node curve under increasing offered load. Then repeat the workload with multiple Reverb nodes and the documented scaling configuration. Compare both equivalent total load and equivalent per-node load, while recording each node's connections, subscriptions, CPU, memory, and network traffic.
Place intended subscribers on different nodes to prove cross-node delivery. Test uneven load-balancer distribution and a hot dispatch channel. Adding nodes does not guarantee proportional improvement: shared authorization, persistence, Redis, or network resources may become the next bottleneck.
Redis Pub/Sub documentation specifies at-most-once delivery. A disconnected subscriber cannot rely on Pub/Sub to replay missed updates. Keep authoritative current state separately and test snapshot recovery after Redis disruption. Do not describe Redis persistence settings as making these Pub/Sub messages replayable.
Keep benchmark resources isolated from other environments. Redis Pub/Sub is not scoped by database number, so a different logical database alone does not isolate channel traffic. Use separate test infrastructure or deliberately distinct channel namespaces and verify that synthetic traffic cannot reach production subscribers.
Run staged load with declared stopping conditions
An illustrative sequence begins with a small correctness run, ramps toward the hypothetical 5,000-driver workload, holds steady, adds observer fan-out, and finishes with a longer soak. Declare actual durations in the scenario file. For planning discussion, a ten-minute ramp, thirty-minute steady hold, and two-hour soak are hypothetical starting choices, not sufficient evidence for every workload.
Change one dimension at a time when locating a limit. Increase driver count with cadence fixed, then cadence with driver count fixed, then fan-out. Keep initial synchronized connection setup separate from steady traffic. Repeat runs after a clean reset and retain variability rather than selecting only the best attempt.
Stop when the agreed resource guardrail is crossed, location correctness fails, the generator loses timing, or any test resource touches an unintended environment. Capture diagnostics before resetting. Predeclare warm-up exclusions and do not remove an inconvenient reconnect spike from the steady phase after inspecting the charts.
Define the quiet workload too. Long-lived idle observers exercise heartbeat and proxy timeout behavior, while repeated trip starts and completions exercise subscription churn. A soak containing only active trips can miss accumulated channel state after users leave. Compare connections, subscriptions, memory, and pending work before and after the generator closes its sessions; investigate resources that remain unexpectedly allocated.
Use the cloud architecture guide to plan comparable infrastructure. Keep the resulting benchmark decision tied to the tested topology and deployment process, not to a framework-wide claim.
Reconnect from current state on real mobile devices
Synthetic sockets cannot establish that mobile location collection survives background restrictions. Use physical devices and the supported app builds to examine foreground, background, screen lock, network change, permission loss, and resumed operation. Record platform configuration and observed behavior separately from backend capacity.
A reconnecting observer should resubscribe with current credentials and obtain an authorized snapshot. Prevent the race in which a delayed snapshot overwrites a newer live event: coordinate subscription and snapshot handling, then compare sequence or state versions within the correct session. Confirm only the intended active subscriptions remain after repeated resumes.
Introduce reconnect backoff with jitter and test a bounded carrier-outage simulation. Measure the authorization surge and time until observers regain a usable position. Distinguish a connected socket from fresh GPS availability. If the driver cannot collect or transmit, show the last observation time instead of implying continued live tracking.
Map rendering deserves its own measurement. A fast received event can still appear late because the device spends too long rebuilding markers. The Flutter map performance article addresses that client boundary; server latency cannot validate frame rendering or battery behavior.
Rehearse failure, rollback, and the result package
In an isolated environment, fail one component at a time: pause workers, remove a Reverb node, delay a dependency, or interrupt Redis connectivity. Record when the disturbance began, what users would see, how alerts responded, and when correct state returned. Combine failures only after the individual recovery paths are understood.
Rehearse rolling deployment and rollback with active subscriptions. Restore the previous compatible application version, reconnect clients as needed, and verify snapshot and event-schema compatibility. Do not purge a shared queue to make a chart recover. Any disposal of synthetic obsolete work must be scoped and included in the report.
Package scenario definitions, seed, scripts, version manifest, redacted configuration, metric definitions, raw summaries, failure timelines, and acceptance outcomes. Report the first violated threshold and a proposed operating envelope with headroom for reconnects and deployments. If no run occurred, leave the result unmeasured; do not fill the report with illustrative performance numbers.
Finally, connect findings to the dispatch dashboard requirements and logistics operating workflow. Dispatchers need a visible stale state and a recovery action when tracking degrades. A capacity decision is useful when those operational consequences are explained alongside the graphs.
Implementation references
Further reading: Redis Pub/Sub Documentation.
Frequently asked questions
Can one Reverb server support 5,000 drivers?
This plan does not establish that result. Driver count, sockets, publishing frequency, fan-out, hardware, runtime, and upstream services jointly define the workload. Run the complete release path and report the tested envelope. A passing idle-connection test answers only whether that environment held those idle connections during that run.
How many messages does the hypothetical workload create?
The illustrative 5,000 drivers publishing every five seconds create 1,000 attempted updates per second. Three intended recipients per accepted update would produce 3,000 intended location deliveries per second if all attempts are accepted. Protocol traffic, retries, rejections, and deliberate coalescing need separate accounting. These calculations describe assumptions, not observed throughput.
Must drivers upload coordinates over WebSockets?
No particular ingestion transport follows from choosing Reverb for outbound broadcasting. Test the authenticated upload path your product uses, including validation, acknowledgements, and retries. If drivers also maintain sockets for assignments, count and exercise those connections independently. Do not add artificial driver subscriptions just to reach a headline connection count.
Does Redis recover missed tracking events?
Redis Pub/Sub does not replay missed messages to a disconnected subscriber. Recover the current authorized position from the application's authoritative state, then reconcile newer live events. If complete route history is required, design durable ingestion and history retrieval separately instead of assuming a transient broadcast is a historical record.
Is a fast average latency enough to pass?
No. Report tail latency, missing deliveries, stale-position duration, unauthorized receipts, and reconnect recovery. Separate phases and recipient types. Also confirm the generator maintained its offered schedule. A fast average among the messages that arrived can hide observers who received nothing and therefore contributed no normal latency samples.
Should we add workers or more Reverb nodes first?
Locate the delay. Growing oldest-job age points toward queue processing or its dependencies; healthy queues with overloaded socket processes suggest another boundary. Redis and authorization can limit both configurations. Change one resource dimension, repeat the scenario, and check whether the original symptom improved without shifting unacceptable delay elsewhere.
What makes this benchmark reproducible?
Provide the script, deterministic seed, synthetic identities, workload phases, dependency versions, effective infrastructure limits, metric definitions, and complete outcomes. State exclusions and unresolved measurement gaps. Another engineer should be able to reproduce the offered traffic and challenge the conclusion without needing access to private customer journeys or an undocumented production setup.
Comparison register
Tracking measurements and the conclusions they support
| Test dimension | What to measure | Limit on interpretation |
|---|---|---|
| Idle connections | Successful connections and effective process limits | Does not establish moving-location throughput |
| Driver ingestion | Scheduled, attempted, accepted, and rejected updates | Acceptance does not prove subscriber receipt |
| Observer fan-out | Intended deliveries, receipt latency, loss, and duplicates | Recipient count differs from socket count |
| Queue processing | Oldest-job age, throughput, retries, and failed jobs | More workers may expose another shared bottleneck |
| Reconnect recovery | Authorization surge and time to current snapshot | Connected does not mean GPS data is fresh |
| Mobile rendering | Visible marker delay and device resource use | Backend throughput cannot establish client frame performance |
- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
Reviewed by the App Clone Labs product strategy team
This guide is written for founders and operators planning clone-inspired platforms, SaaS products, marketplaces, and mobile apps. It is reviewed against App Clone Labs delivery patterns, product scoping standards, and current implementation realities before being published.
Review the editorial team structureRelated product paths
Continue with the services, solutions, guides, and articles that connect this topic to a real software build.

