Signal
$0
- 200 peak subscribers
- 1 namespace · 3 topics
- 60-second retention · 1 region
- Community support
Realtime topic mesh
Your broker moves events between services you control. topcmesh moves them the rest of the way — out to every browser, device and agent runtime holding a connection, in order, with replay from the last cursor they acknowledged.
p99 40 ms regional · 95 ms cross-region
Migrating in Cohort 10
orders.status
1,284 subscribers · cursor 84f21c
runs.tokens
318 subscribers · cursor 9b0e47
fleet.telemetry
42,907 subscribers · cursor 2ad5f0
The problem
The first half runs inside your infrastructure: services emitting events to a broker over stable connections between processes you deploy. Kafka, NATS, RabbitMQ, SQS, Postgres LISTEN/NOTIFY — mature, well understood, boring in the way infrastructure should be. This half works.
The second half is the last hop — getting that event out to the clients actually watching. Open connections to devices you don't operate, on networks that fail constantly, at a concurrency that scales with your user count instead of your event volume. Almost nobody sets out to build this. It arrives as a side effect of shipping one live feature, and then it compounds.
no delivery state
A broadcast to 60,000 connections is 60,000 independent writes into socket buffers. Most homegrown tiers cannot answer “did this user receive it?” because nothing recorded the answer.
no resume
Tunnels, elevators, backgrounded tabs, carrier handoffs. Without a resumable cursor every one of these is data loss, and the resulting bug reports are unreproducible by definition.
scale-in severs
A stateless service drains over seconds. A socket tier scales in by cutting live connections and triggering a reconnect stampede — so teams stop scaling in and pay peak capacity permanently.
cost tracks viewers
Egress is a function of subscribers, not events. Product success shows up as a nonlinear infrastructure bill, usually noticed a quarter late.
The contract
“Ordered per topic, per subscriber, with replay from the last acknowledged cursor.”
What holds
A subscriber that presents a cursor cannot then receive a message older than it. Order is guaranteed within a topic, per subscriber — not across topics, and not across namespaces.
What holds
Reconnect within the topic's retention window with your last acknowledged cursor and the mesh replays everything you missed, in order, before resuming live delivery.
Where it ends
Sixty seconds to twenty-four hours, by tier and by topic. A cursor older than the window returns 409 cursor_expired and the client resynchronizes from your own source of truth.
Where it ends
If nothing is attached, nothing is delivered. The mesh holds the gap for the retention window and nothing longer. It is not a queue, and it will not wake a sleeping device.
Capabilities
The surface area is the product. Everything below fits in one sitting, the client SDK is nine kilobytes, and there is no seventh item waiting behind a feature flag.
Every message carries a monotonic cursor. A subscriber sees a topic in publish order, and a client that reconnects with a cursor cannot receive an older message after a newer one.
Acknowledge a cursor, disconnect, come back ninety seconds later and present it again. The mesh replays the gap from the topic's retention buffer, then resumes live. Tunnels stop generating bug reports.
Topics, tokens, quota, retention and regional placement all scope to a single namespace. A token minted for one namespace cannot read another, and there is no cross-namespace API surface to misconfigure.
One publish to fifty thousand subscribers is one billable message. Connection-hours meter separately and generously. Adding viewers does not multiply the invoice.
A subscriber that stops reading is buffered to its topic's limit, then disconnected with slow_consumer. It appears in the namespace log by connection ID — not as an aggregate you have to go correlate.
Pin a namespace to a set of regions. Subscribers attach at the nearest edge, the topic name is identical everywhere, and the ordering guarantee holds across regions at 95 ms p99.
Scope
Every item here is a decision, not a roadmap gap. If you need one of them you need a different tool, and we would rather you found that out on this page than in month three.
No consumer groups, no offsets you manage, no dead-letter queues, no work distribution. Two subscribers on a topic both receive every message. That is fan-out, not competing consumers, and it is not configurable.
Keep Kafka, NATS, SQS, whatever you already run and understand. topcmesh sits at the edge of that system and takes the one leg your broker was never designed for.
No presence API, no typing indicators, no rooms, no moderation, no history API beyond the retention buffer. These are the features that make client SDKs ninety kilobytes.
No transforms, no joins, no windowing, no filtering, no enrichment. A message leaves the mesh byte-for-byte as it arrived.
If the client is not connected, the mesh holds the gap for the retention window and delivers on reconnect. It will not wake a device, and it never will.
The shape of it
Publish over HTTP from anything that can make a request. Subscribe over WebSocket from anything that can hold one open. Examples use namespace q2m9r1 — substitute your own.
# Publish once. The mesh handles every attached subscriber.
curl -X POST https://bus.topcmesh.com/bus/namespace/q2m9r1/topic/orders.status \
-H "Authorization: Bearer $TOPCMESH_PUBLISH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"order_id":"ord_8f2a","state":"picked","at":"2026-07-26T14:02:11Z"}'
# 202 Accepted
# { "cursor": "84f21c", "topic": "orders.status", "fanout": 1284 }import { connect } from '@topcmesh/client'; // 9 KB gzipped
const mesh = connect({
namespace: 'q2m9r1',
token: await mintSubscriberToken(), // scoped, short-lived
cursor: localStorage.getItem('cursor') ?? 'latest',
});
mesh.topic('orders.status').on('message', (msg) => {
render(msg.data);
localStorage.setItem('cursor', msg.cursor); // acknowledge
});
mesh.on('replay', ({ from, count }) =>
console.log(`replayed ${count} from ${from}`)); // after a reconnectField notes
“We had a two-person rotation whose entire job was the socket tier. The migration took about a week per topic and we shut the rotation down.”
Mara Ellison
Staff engineer · Palletworks
“The cursor is the whole thing. Our reconnect bugs were never reconnect bugs. They were resume bugs, and we didn't have a resume.”
Arun Sethi
Platform lead · Fernway
“I asked what happens when a subscriber stalls and got a straight answer with an error code in it. That is not usually how those calls go.”
Ines Koster
Principal engineer · Vantry
Quotes are from teams in Cohorts 7 through 10, published with permission.
Pricing
Peak concurrent subscribers is a ceiling, not a meter — you are not billed per connection. Every tier requires a cohort seat, including the last one.
$0
$180 /mo
Custom
Overage on Mesh is $4 per additional million published messages. Peak subscribers is measured as the 99th percentile of concurrent connections over a billing period, so a single spike does not reprice your month.
Cohort 11 opens when Cohort 10 finishes migrating — fourteen teams, each with an engineer through the migration. That is the reason there is a queue.