Pulse is a high-performance, self-hosted WebSocket server that implements the Pusher protocol for real-time bidirectional messaging. It is a fork of Soketi with significant enhancements, modernized dependencies, and production-ready features built on top of uWebSockets.js β a C++-compiled WebSocket and HTTP library.
It provides a drop-in replacement for Pusher.com Channels, allowing you to run your own real-time infrastructure behind your firewall, on your own hardware, or in any cloud environment.
- Pusher Protocol Compatible β Works seamlessly with Pusher JS SDK, Laravel Echo, and Pusher backend SDKs (PHP, Node.js, Python, etc.)
- High Performance β Powered by uWebSockets.js, a C++-native engine capable of tens of thousands of concurrent connections
- Node.js v18 β v24 Support β Fully compatible with the latest Node.js runtimes up to version 24
- Channel Types β Public, Private, Encrypted Private, and Presence channels
- Client Events β Enable client-to-client messaging on private channels
- Horizontal Scaling β Multiple adapters: Local, Redis, NATS, Cluster
- Rate Limiting β Granular rate limiting for backend events, client events, and read requests
- Webhooks β HTTP webhook notifications with optional AWS Lambda support
- Webhook Logger β Persist webhook deliveries to daily log files (webhook-YYYY-MM-DD.log) or database (MySQL/PostgreSQL)
- Production-Ready Bundling β Single-file bundle via esbuild for zero-dependency deployment
- Prometheus Metrics β Expose real-time server metrics on a dedicated HTTP endpoint
- Queue System β Async event processing via sync or Redis (BullMQ)
- Multi-App Support β Serve multiple applications with isolated credentials
- Graceful Shutdown β Drain active connections before terminating
- SSL/TLS Support β Serve secure WSS connections
- Docker Support β Containerized deployment ready
- PM2 Support β Process management via PM2 clustering
- CORS β Fully configurable CORS headers
- Why Pulse? (vs Soketi)
- Requirements
- Architecture Overview
- Installation
- Configuration
- Usage
- Channel Types
- Horizontal Scaling
- Webhook Logger
- Production Bundling
- Monitoring & Metrics
- API Endpoints
- Webhooks
- Rate Limiting
- Project Structure
- Development
- Known Limitations
- Contributing
- License
Pulse is a fork of Soketi β an excellent open-source WebSocket server. This fork introduces additional features and improvements that align with specific production requirements. We are grateful to the Soketi maintainers and contributors for their foundational work.
| Aspect | Soketi | Pulse |
|---|---|---|
| Node.js Support | v14 β v18 | v18 β v24 |
| Webhook Logging | Not available | File & Database (MySQL/PostgreSQL) |
| Production Bundling | Requires npm install on server | esbuild single-file bundle |
| Environment Prefix | SOKETI_ |
PULSE_ |
| AWS Lambda Webhooks | Not available | Supported |
| Database Pooling | Not available | Knex connection pooling |
| Graceful Shutdown | Basic | Configurable grace period |
| CLI Binary | soketi |
pulse |
| Dependency | Version |
|---|---|
| Node.js | v18 β v24 |
| npm | v8+ |
| Memory | Minimum 256 MB (recommended: 1 GB+) |
Optional:
- Redis β For Redis adapter, rate limiter, cache, and queue
- NATS β For NATS adapter
- MySQL / PostgreSQL β For database-backed app managers and webhook logging
- Docker β Containerized deployment
- PM2 β Production process management
Note: Due to uWebSockets.js limitations, Pulse cannot run on CentOS 7. Tested on CentOS 8 and Ubuntu.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Pulse Server β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β ββββββββββββ ββββββββββββ ββββββββββββ ββββββββββββββ β
β β HTTP β β WebSocket β β Metrics β β Queue β β
β β Handler β β Handler β β (Prom) β β Processor β β
β ββββββ¬ββββββ ββββββ¬ββββββ ββββββ¬ββββββ ββββββββ¬ββββββ β
β β β β β β
β ββββββΌββββββββββββββΌββββββββββββββΌββββββββββββββββΌβββββββ β
β β Core Engine β β
β β (uWebSockets.js / Node.js) β β
β ββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββ β
β β β
β ββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββ β
β β Adapter Layer β β
β β βββββββββ βββββββββ ββββββββ ββββββββββ β β
β β β Local β β Redis β β NATS β βCluster β β β
β β βββββββββ βββββββββ ββββββββ ββββββββββ β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β App Manager Layer β β
β β βββββββββ βββββββββ ββββββββββββ β β
β β β Array β β MySQL β βPostgreSQLβ β β
β β βββββββββ βββββββββ ββββββββββββ β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Webhook Logger Layer β β
β β ββββββββββββββββ ββββββββββββββββββββ β β
β β β File Logger β β Database Logger β β β
β β β (Daily Rotate)β β (MySQL/Postgres) β β β
β β ββββββββββββββββ ββββββββββββββββββββ β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
git clone https://github.com/oneaxxall/pulse.git
cd pulse
npm install
npm run build
npm linkNow use the pulse command anywhere:
pulse startdocker build -t pulse .
docker run -d --name pulse -p 6001:6001 pulseOr use docker-compose:
docker-compose up -dpm2 start pulse -- start./production.sh
# Creates pulse-production.tar.gz (~35MB)
# Contains a single bundled JS file β no npm install needed on target server!Configuration methods (in order of precedence):
- JSON config file β
pulse --config=app.json - Environment variables β
.envfile (prefix:PULSE_) - Default configuration β Defined in
src/server.ts
| Parameter | Default Value |
|---|---|
| App ID | app-id |
| App Key | app-key |
| App Secret | app-secret |
| Port | 6001 |
| Variable | Default | Description |
|---|---|---|
PULSE_DEBUG |
1 |
Enable debug logging |
PULSE_ADAPTER_DRIVER |
local |
Adapter driver |
PULSE_PORT |
6001 |
Server port |
PULSE_MANAGER_DRIVER |
array |
App manager driver |
PULSE_WEBHOOKS_LOGS_ENABLED |
false |
Enable webhook logging to files |
PULSE_WEBHOOKS_LOGS_DB_ENABLED |
false |
Enable webhook logging to database |
const pusher = new Pusher('app-key', {
wsHost: 'your-server.com',
wsPort: 6001,
forceTLS: false,
enabledTransports: ['ws', 'wss'],
});
const channel = pusher.subscribe('my-channel');
channel.bind('my-event', data => {
console.log('Received:', data);
});import Echo from 'laravel-echo';
window.Pusher = require('pusher-js');
window.Echo = new Echo({
broadcaster: 'pusher',
key: 'app-key',
wsHost: 'your-server.com',
wsPort: 6001,
forceTLS: false,
disableStats: true,
});$pusher = new Pusher\Pusher('app-key', 'app-secret', 'app-id', [
'host' => 'your-server.com',
'port' => 6001,
'scheme' => 'http',
]);
$pusher->trigger('my-channel', 'my-event', ['message' => 'Hello World!']);curl -X POST http://your-server.com:6001/apps/app-id/events \
-H "Content-Type: application/json" \
-d '{"name": "my-event", "channel": "my-channel", "data": "{\"message\":\"Hello World!\"}"}'| Type | Prefix | Description |
|---|---|---|
| Public | (none) | Open to all clients |
| Private | private- |
Requires auth; supports client events |
| Encrypted Private | private-encrypted- |
End-to-end encrypted private channel |
| Presence | presence- |
Tracks connected users |
| Cache | cache-* |
Caches channel state |
| Architecture | Adapter | Rate Limiter |
|---|---|---|
| Single node, single thread | local |
local |
| Single node, multi-thread (PM2) | cluster |
cluster |
| Multi-node, same network | cluster / redis |
cluster / redis |
| Multi-node, multi-network | redis |
redis |
Pulse includes a built-in Webhook Logger that persists all webhook deliveries for auditing, debugging, and compliance.
PULSE_WEBHOOKS_LOGS_ENABLED=true
PULSE_WEBHOOKS_LOGS_DIR=logsLog files are rotated daily: webhook-YYYY-MM-DD.log
PULSE_WEBHOOKS_LOGS_DB_ENABLED=trueNote: Database logging works with mysql/postgres manager driver. Run the SQL schema from
configurations/pds-pusher-manager.sql.
Pulse uses esbuild to compile the entire application into a single JavaScript file.
| Feature | Traditional | Pulse Bundled |
|---|---|---|
| npm install on server | Required | Not needed |
| Deployment size | ~200MB+ | ~35MB (compressed) |
| Startup time | Slow | Instant |
| Dependency conflicts | Possible | Eliminated |
| File count | Thousands | Single JS file |
./production.sh
# Output: pulse-production.tar.gz (~35MB)tar -xzf pulse-production.tar.gz
./run-pulse-server.shPulse exposes Prometheus-compatible metrics on port 9601:
PULSE_METRICS_ENABLED=true
PULSE_METRICS_SERVER_PORT=9601| Method | Endpoint | Description |
|---|---|---|
GET |
/ready |
Health check |
GET |
/health |
Detailed health |
GET |
/usage |
Memory usage |
GET |
/accept-traffic |
Traffic capacity check |
GET |
/apps/:appId/channels |
List channels |
POST |
/apps/:appId/events |
Trigger event |
POST |
/apps/:appId/events/batch |
Batch trigger events |
Events: client_event, channel_occupied, channel_vacated, member_added, member_removed. Supports AWS Lambda triggers.
| Limiter | Scope | Default |
|---|---|---|
| Backend events | POST /events | Unlimited (-1) |
| Client events | Per socket | Unlimited (-1) |
| Read requests | Read APIs | Unlimited (-1) |
pulse/
βββ bin/ # CLI entry points
βββ certs/ # SSL examples
βββ configurations/ # DB schemas, Nginx, Supervisor configs
βββ docs/ # Documentation
βββ sdk/ # SDK examples
βββ src/
β βββ adapters/ # Local, Redis, NATS, Cluster adapters
β βββ app-managers/ # Array, MySQL, PostgreSQL managers
β βββ cache-managers/ # Memory, Redis cache
β βββ channels/ # Public, private, presence, encrypted
β βββ cli/ # CLI implementation
β βββ metrics/ # Prometheus drivers
β βββ queues/ # Sync, Redis queue drivers
β βββ rate-limiters/ # Local, Redis, cluster
β βββ types/ # TypeScript definitions
β βββ webhook-log-adapters/ # File & DB webhook log storage
β βββ server.ts # Core server
β βββ ws-handler.ts # WebSocket handler
β βββ http-handler.ts # REST API handler
β βββ webhook-logger.ts # Webhook logging system
βββ tools/
β βββ build.js # esbuild bundling script
βββ main.ts # Entry point
βββ production.sh # Production bundling script
βββ package.json
βββ tsconfig.json
βββ Dockerfile
βββ docker-compose.yml
npm run dev # Hot-reload development
npm run build # Compile TypeScript
npm test # Run tests
npm run test:local # Verbose tests
npm run lint # Lint source
npm run bundle # Production bundle- CentOS 7 not supported
- Windows not extensively tested
- Subset of Pusher HTTP API implemented (core features complete)
- Fork the repository
- Create a feature branch
- Commit your changes
- Push and open a Pull Request
- Soketi β The original project that Pulse is forked from
- Pusher.com β For the protocol specification and inspiration
- uNetworking/uWebSockets.js β The high-performance WebSocket engine
- Laravel β For Laravel Echo and broadcasting integration
AGPL-3.0 License