Pusher Alternative. Same Protocol. No Fan-Out Tax.

Your real-time bill scales with the wrong thing. Every broadcast you send to a channel gets multiplied by the number of subscribers on it, then multiplied by your overage rate. We built Vask to keep the wire protocol you already use and remove the per-fan-out multiplier. Same SDKs. Same three lines of code. Up to 80% less bill.

Get started

Realtime made simple.

Dev plan is free locally. $10/mo when you ship.

Why developers leave Pusher

The reason is rarely latency. It is rarely uptime. It is the bill, and the bill has a specific mechanism that nobody warns you about until you cross a threshold. The mechanism is the per-fan-out multiplier.

Here is how it works in plain terms. You publish one message to a channel. That channel has 50 subscribers. The pricing model counts the broadcast as 51 messages: one publish, 50 deliveries. Add another subscriber and it becomes 52. Run a notifications channel with 1,000 connected users and a single broadcast becomes 1,001 billable messages. Run a typing-indicator over a busy room and you can rack up tens of thousands of billable messages from a single user pressing a key.

This is not a quirk. It is documented in the protocol vendor's own engineering reference:

A message that is sent to 100 subscribers will be counted as 100 messages.
pusher-docs

So the bill scales with the thing you cannot control (the number of people listening) rather than the thing you can control (how often you publish). The category has a name for the workload: "fan-out." We call the surcharge attached to it the fan-out tax. Pricing pages do not say "fan-out tax" because pricing pages do not name the mechanism. The mechanism is the product.

There are three predictable moments when developers feel this and start shopping for an alternative:

  1. The viral moment. A feature works. Subscribers grow ten times overnight. The bill grows a hundred times overnight because every existing broadcast now fans out across ten times the audience and the per-message overage rate stacks on top.
  2. The product change. Someone ships presence indicators, typing indicators, online-status dots, or live cursor positions. Each of these emits broadcasts at human-keystroke or human-mouse-move frequency, fanned out across every viewer. Costs per active user can rise by an order of magnitude in a week.
  3. The audit. Finance pulls a year of invoices, asks why the line item doubles every quarter, and the engineering lead has to explain that "broadcasting to your own users is the priced unit, and the price scales with success."

We don't think any of this is a moral failing of the incumbent. It is just a billing model from a previous era of real-time, when broadcasts were rare and connections were the scarce resource. What changed is the work pattern. Modern apps fan out constantly. The model has not caught up.

How Vask is different

Three pieces of mechanism, no marketing varnish.

The Pusher protocol, kept on purpose. The Pusher wire protocol is one of the cleanest channel-based real-time protocols in the wild. It has good SDKs in every language a working developer is likely to use. It has well-defined semantics for public channels, private channels, presence channels, and channel auth. We did not invent a competing protocol because there is no reason to invent one. We kept the protocol. Your client SDKs work unchanged. Your server SDKs work unchanged. Laravel Echo, pusher-js, pusher-php-server, pusher-http-ruby, pusher-http-python: all of them connect to Vask the same way they connect today.

Cloudflare's edge instead of a centralized region. Connections terminate at the closest of 330+ Cloudflare cities, not a single home region. P99 within-region latency stays under 40ms because the WebSocket never crosses an ocean. You inherit a network footprint roughly 30% of the internet already runs on. There is no separate "global" tier to upgrade to and no per-region charge.

Flat broadcast billing. A broadcast to a channel is one broadcast on the bill, regardless of how many subscribers are on it. There is no per-fan-out multiplier. There is no surcharge for presence channels with thousands of members. There is no surprise line item for the typing indicator that ships in a sprint. We don't throttle, drop, or charge for fan-out.

The receipts:

  • P99 sub-60ms within region, served from Cloudflare's edge in 330+ cities
  • Pusher protocol drop-in. No SDK swap, no event-name rewrite, no auth rewrite
  • Up to 80% lower bill on broadcast-heavy workloads with significant fan-out, because the per-fan-out multiplier disappears
  • Most teams ship the migration in around ten minutes
  • Built by people who ship. Answered by the same people.

Side-by-side

ComparisonVaskPusher Channels
Headline workload2,000 concurrent · 10M broadcasts/moIndie · $20/moPro · $99/mo
Free tierSandbox onlyDev plan · free locally, $10/mo when shipped100 connections · 200K messages/day
Entry paid tier500 conn · 1M msgs/daySide · $10/moStartup · $49/mo
Mid tier2K conn · 4M msgs/dayIndie · $20/moPro · $99/mo
High tier5K conn · 10M msgs/dayTeam · $50/moBusiness · $299/mo
Top published tier30K conn · 90M msgs/dayBusiness · $100/moGrowth Plus · $1,199/mo
Billing mechanicPay for broadcasts you send, not who is listeningSubscriber × message — fanout multiplies cost
Free for local devForever, on the Dev planLimited (Sandbox app counts toward quota)
Connection limitsSoft caps tied to plan; lift on requestDaily caps per tier
Self-hostReverb-compatible; bring your own infraNo
Protocol compatibilityDrop-in via Pusher protocol — same client SDKsNative (Pusher Channels protocol)
SupportDirect founder support on every paid tierTiered (chat/email by plan)

Pusher Channels pricing reflects published list rates as of 2026-04. Workloads above the top tier require contacting Pusher sales.

The table renders from a dated competitor fixture, so the numbers reflect published pricing as of the last verification stamp on the row. If a tier has shifted since then, the timestamp tells you so. Refresh, do not trust.

What the migration looks like

Three lines. One environment variable. Around ten minutes. The wedge is the protocol. Because we kept it, you do not rewrite anything that touches the protocol.

The change is at the configuration layer. You point your existing real-time client at the Vask host and supply Vask credentials. Your channel names, event names, payload shapes, presence semantics, and auth flow stay exactly the same. The Laravel example below is illustrative. The same pattern works for any framework with a Pusher SDK; framework-specific recipes for Rails, Next.js, Django, Express and FastAPI are next on the list.

Pusher → Vask · Laravel
Index: app/Broadcasting.php
===================================================================
--- app/Broadcasting.php
+++ app/Broadcasting.php
@@ -1,7 +1,5 @@
 use Illuminate\Support\Facades\Broadcast;
 
-// Pusher client setup
-$pusher = new \Pusher\Pusher(env('PUSHER_KEY'), [
-    'cluster' => env('PUSHER_CLUSTER', 'mt1'),
-]);
-$pusher->trigger('orders', 'created', $payload);
+// Vask drop-in via Laravel broadcasting
+Broadcast::channel('orders', fn () => true);
+broadcast(new OrderCreated($payload))->toOthers();

A few things worth saying out loud:

  • Nothing breaks at the SDK layer. The Pusher protocol is the contract. The protocol does not know which host is on the other end of the WebSocket.
  • Presence channels work. Private channels work. Channel auth works. We use the same auth pattern.
  • You can run both endpoints in parallel during the cutover. Spin up a feature flag, send a percentage of traffic to Vask, and verify the bill against your existing one in flight. Roll back at any time by flipping the env var.
  • If the migration runs into an edge case in your stack, email [email protected] and you will get an answer from someone who can read the diff.

Run the numbers on your own bill

The frame above is the argument. The number is what closes it. Plug in your concurrent users, your broadcasts per minute, and the average subscribers per channel, and the calculator will show you what the per-fan-out multiplier is doing to your current bill, and what it would look like without it.

Calculator

What you'd actually pay.

Pick the shape of your workload. We'll match it to the right Vask tier - and to whatever Pusher would charge for the same headroom.

Peak concurrent connections2,000
Server broadcasts / month5.0M
Avg. subscribers per broadcast10
Vask tier that fitsIndie
Pusher tier that fitsPro
Pusher avg messages / day (broadcasts × (1 + fanout) ÷ 30)1,833,333
Vask counts5,000,000 broadcasts / mo
Pusher monthly cost$99/mo
Vask monthly cost$20/mo
You save$79/mo · 80% cheaper

Pusher limits are daily; this assumes even usage over a 30-day month. See the full Pusher vs Vask comparison.

If you want a written breakdown for your team or your finance lead, the calculator will email you a formatted report keyed to your inputs. Same numbers, different format. Use it as the supporting doc for the switch decision.

When NOT to switch

Honesty is a load-bearing part of an alternatives page. Vask is not the right fit for everyone, and we would rather you stay on what you have than pay for something you do not need. The cases below are the ones where we would tell you not to switch:

  • You are below the free tier and paying nothing. If your concurrent connection count and message volume sit comfortably inside the incumbent's free plan, switching does not save money. It costs you migration time you could spend on the product. Come back when the bill shows up.
  • You are running Supabase as a bundle. If you are using Supabase auth + Postgres + storage + realtime as one stack and the bundled real-time channel is fine for what you are doing, the value is in the bundle. Pulling realtime out alone breaks the integration math and replaces a single bill with two. Don't.
  • You are running Laravel Reverb in-process for a small app, and the ops are fine. Reverb is a solid first-party Laravel option that runs alongside your app server, with no per-message billing and no extra vendor in the stack. If your traffic fits inside one server, your team is comfortable operating it, and you do not need multi-region edge presence, Reverb is the right answer for you. Vask is the hosted Pusher-protocol option for teams that want the protocol without operating their own WebSocket server, or that need edge delivery beyond what an in-process server can give them.
  • You are evaluating real-time as a science project, not for production. If the goal is "I want to learn how WebSockets work end-to-end," Vask is not the teaching surface. Read the protocol spec, run a server locally, then come back when the question is "what hosts this in production."
  • You need a non-Pusher protocol on the wire. If your existing system is on Ably's protocol, MQTT, or a proprietary contract you cannot change, the protocol-compatibility wedge is not a wedge for you. The Pusher protocol is the through-line of the migration story.

If none of those apply, the math will work in your favor. Run the calculator above and check.

Is Vask actually Pusher-protocol-compatible?
Yes. Same wire protocol, same client SDKs, same channel and event semantics. Point your existing app at Vask by changing the host and the key. No SDK swap, no event-name rewrite, no auth model rewrite. Most teams are broadcasting through Vask in around ten minutes.
How much cheaper is Vask than Pusher in practice?
Up to 80% lower for broadcast-heavy workloads with significant fan-out. Real savings depend on your fan-out factor (subscribers per channel) and broadcast volume; the calculator on this page shows the math against your own numbers. The reason the ceiling is so high is mechanical, not promotional. Pusher counts each subscriber copy of a broadcast as a billable message. We do not. A single broadcast to 100 subscribers is one broadcast on Vask, one hundred messages on the per-fan-out model.
What does the migration actually look like?
Three lines. One environment variable. Around ten minutes for most teams. You change the host, the key, and the secret. Your existing client SDKs keep working because the wire protocol is identical. Laravel is documented today; Rails, Next.js, Django and other framework-specific recipes are next on the list.
Will my Pusher client SDKs and integrations break?
No. The Pusher protocol is the contract. Your pusher-js, laravel-echo, pusher-php-server, pusher-http-ruby, pusher-http-python and similar integrations connect to Vask without code changes. Presence channels, private channels and channel auth all work the same way.
What's the latency story compared to a centralized real-time service?
P99 sub-60ms within region, served from Cloudflare's edge in 330+ cities. Connections terminate at the closest edge to your user, not a single home region. You can verify this against your existing real-time bill before you commit. The calculator above shows the math against your own numbers.
How does Vask price broadcasts?
Per broadcast, not per fan-out copy. If you publish one broadcast to a channel with 10,000 subscribers, that is one broadcast on the bill. Within your tier, we don't throttle, drop messages, or charge per subscriber copy. If you cross your plan limits we give you a grace period to adjust before caps kick in. Tier limits are published openly. The free Dev tier covers 100 concurrent connections and 1M broadcasts per month for local development. Paid tiers run from $10/mo (Side: 500 concurrent, 2M broadcasts) up to $100/mo (Business: 10K concurrent, 100M broadcasts). The recommended tier for most production apps is Indie at $20/mo: 2K concurrent connections and 10M broadcasts per month.
When should I NOT switch to Vask?
If you are below the Pusher free tier and not paying anything, you do not need us yet. If you are already on Supabase using auth, database and realtime as a single bundle, the bundle is the value. Switching realtime alone breaks the math. If you are running Laravel Reverb in-process for a small app and the ops are fine, Reverb is a great first-party fit; we are the option when you need hosted Pusher-protocol on the edge.

Get going

Same protocol. Same three lines. Different bill. Drop in your existing keys, keep your existing SDKs, and watch the per-fan-out multiplier disappear from your invoice.

Make the switch

Three lines. Then you're done.

Drop in your existing keys, keep your existing SDKs. Most teams ship the migration in around ten minutes.