Sarıkaya Dev Logo

Real-Time Event Streaming in Laravel with Apache Pulsar and Serverless Consumers

Mahmut Sarıkaya 4 min read 3 Views 0
Real-Time Event Streaming in Laravel with Apache Pulsar and Serverless Consumers

Why real-time streaming matters for Laravel applications

Imagine a marketplace where a new order must appear on the seller’s dashboard within milliseconds. Delayed notifications translate into lost revenue and frustrated users. Modern Laravel projects increasingly rely on websockets, push notifications, and analytics pipelines that demand sub‑second latency. Real‑time event streaming provides the backbone for these use cases, turning discrete HTTP requests into a continuous flow of data that can be processed, filtered, and reacted to instantly.

Apache Pulsar vs. traditional message brokers

Apache Pulsar combines a distributed log architecture with built‑in multi‑tenant isolation, making it more scalable than classic brokers such as RabbitMQ or Kafka in certain scenarios. Pulsar separates storage (BookKeeper) from the serving layer, allowing horizontal scaling without downtime. For a Laravel API that serves 10,000 concurrent users, Pulsar can sustain over 1 million messages per second with sub‑10 ms end‑to‑end latency, according to the official benchmark released in 2023.

Setting up Pulsar for Laravel

System requirements are modest: a Linux server with at least 4 CPU cores, 8 GB RAM, and Java 11. Installation can be performed via Docker for rapid prototyping. Open a terminal and run:

docker run -d --name pulsar \
  -p 6650:6650 -p 8080:8080 \
  apachepulsar/pulsar:3.2.1 bin/pulsar standalone

The command launches a single‑node Pulsar instance listening on the default binary port 6650 and the HTTP admin port 8080. Verify the health endpoint at http://localhost:8080/admin/v2/brokers/health. Once the broker is up, create a dedicated namespace for Laravel events:

docker exec -it pulsar bin/pulsar-admin namespaces create public/laravel

Now you have a clean isolation boundary for all topics that Laravel will publish to.

Integrating Laravel event broadcasting with Pulsar

Laravel’s broadcasting system is driver‑agnostic. By adding a custom driver you can push events directly to Pulsar. First, add a service provider:

<?php namespace App\Providers;\n\nuse Illuminate\Support\Facades\Broadcast;\nuse Illuminate\Support\ServiceProvider;\nuse App\Broadcasting\PulsarBroadcaster;\n\nclass PulsarBroadcastServiceProvider extends ServiceProvider\n{\n    public function boot()\n    {\n        Broadcast::extend('pulsar', function ($app) {\n            return new PulsarBroadcaster(\n                $app['config']['broadcasting.connections.pulsar']\n            );\n        });\n    }\n}\n?>\n

Next, register the connection in config/broadcasting.php:

<?php return [\n    'default' => env('BROADCAST_DRIVER', 'log'),\n    'connections' => [\n        'pulsar' => [\n            'driver' => 'pulsar',\n            'host' => env('PULSAR_HOST', 'localhost'),\n            'port' => env('PULSAR_PORT', 6650),\n            'topic' => env('PULSAR_TOPIC', 'laravel-events'),\n        ],\n    ],\n];\n?>\n

Finally, create a simple event that implements ShouldBroadcast:

<?php namespace App\Events;\n\nuse Illuminate\Broadcasting\Channel;\nuse Illuminate\Broadcasting\InteractsWithSockets;\nuse Illuminate\Broadcasting\PresenceChannel;\nuse Illuminate\Broadcasting\PrivateChannel;\nuse Illuminate\Contracts\Broadcasting\ShouldBroadcast;\nuse Illuminate\Foundation\Events\Dispatchable;\nuse Illuminate\Queue\SerializesModels;\n\nclass OrderPlaced implements ShouldBroadcast\n{\n    use Dispatchable, InteractsWithSockets, SerializesModels;\n\n    public $orderId;\n    public $amount;\n\n    public function __construct($orderId, $amount)\n    {\n        $this->orderId = $orderId;\n        $this->amount = $amount;\n    }\n\n    public function broadcastOn()\n    {\n        return new PrivateChannel('orders');\n    }\n}\n?>\n

When you dispatch event(new OrderPlaced(1234, 99.99)); Laravel will hand the payload to the PulsarBroadcaster, which publishes a message to public/laravel/laravel-events. Consumers subscribed to that topic receive the event instantly.

Deploying serverless consumers

Serverless functions are perfect for processing high‑volume streams without managing dedicated worker nodes. Below is a minimal AWS Lambda written in Node.js that pulls messages from Pulsar using the official client library.

const Pulsar = require('pulsar-client');\n\nexports.handler = async (event) => {\n  const client = new Pulsar.Client({\n    serviceUrl: 'pulsar://YOUR_PULSAR_HOST:6650'\n  });\n  const consumer = await client.subscribe({\n    topic: 'public/laravel/laravel-events',\n    subscription: 'lambda-sub',\n    subscriptionType: 'Shared'\n  });\n  const msg = await consumer.receive();\n  const data = msg.getData().toString();\n  console.log('Received event:', data);\n  await consumer.acknowledge(msg);\n  await client.close();\n  return { statusCode: 200, body: 'Processed' };\n};\n

Deploy the function via the AWS console or the Serverless Framework. Set the timeout to at least 30 seconds to allow the client to establish a connection. Because the subscription type is Shared, multiple Lambda instances can process the same topic in parallel, giving you elastic scaling based on the incoming event rate.

Best practices and performance tips

1. **Batch publishing** – Use Pulsar’s batch settings (e.g., batchingMaxMessages and batchingMaxPublishDelayMs) inside the broadcaster to reduce network overhead. A 10 ms batch window can cut HTTP calls by up to 70 % while adding only microseconds of latency.\n2. **Schema enforcement** – Define an Avro schema for Laravel events. This prevents version drift and enables downstream consumers to evolve independently.\n3. **Back‑pressure handling** – Laravel’s queue workers should respect the maxMessagesPerPoll setting to avoid overwhelming the Pulsar client.\n4. **Monitoring** – Enable Pulsar’s Prometheus exporter and integrate it with Grafana dashboards. Track msgRateIn and msgRateOut to spot spikes before they affect SLA.\n5. **Security** – Use TLS encryption and token‑based authentication for production clusters. Store the token in .env as PULSAR_TOKEN and inject it in the client configuration.

Conclusion

By wiring Laravel’s native broadcasting layer to Apache Pulsar, developers gain a horizontally scalable, low‑latency backbone that can feed both traditional websockets and modern serverless consumers. The combination eliminates the need for separate message queues, simplifies code, and future‑proofs the architecture against traffic bursts. Start with a local Docker Pulsar, add the custom broadcaster, and experiment with a Lambda consumer – within a day you’ll have a production‑grade real‑time pipeline.

Sources

  • Apache Pulsar Official Documentation
  • Laravel Broadcasting Documentation
  • Serverless Framework AWS Lambda Guide

Author: Mahmut Sarıkaya — sarikayadev.com

Tags: #Laravel #Apache Pulsar #real-time streaming #serverless functions #Laravel event broadcasting
Share:
M

Written by

Mahmut Sarıkaya

Software Developer

Comments

No comments yet. Be the first to share your thoughts!

Leave a Comment

4 + 5 =