KVCall
A calling and messaging app backed by a self-hosted WebRTC SFU and a billing ledger.
Overview
KVCall pairs an Expo mobile client with a NestJS backend that runs its own WebRTC SFU (mediasoup) for calls, alongside contacts, messaging, presence/status, and subscriptions. A ledger service tracks call usage against subscription plans, so billing and call history stay consistent with what actually happened on the media layer.
The challenge
Voice/video calling needs low-latency signalling and media routing that scales beyond simple peer-to-peer, while usage-based billing needs to reconcile cleanly with call events that can end abruptly (dropped connections, backgrounded apps). Both had to work together without the ledger drifting from what the SFU actually delivered.
What I built
- React Native (Expo) client with calling, messaging, contacts, and presence/status
- NestJS backend running a mediasoup SFU for group and 1:1 calls
- Socket.io signalling layer with a Redis adapter for horizontal scaling
- Subscription plans and a ledger service that records usage against them
- Push notifications and in-app status/marquee messaging
Screenshots









Architecture
Engineering highlights
Self-hosted SFU
Media is routed through a mediasoup SFU under our control rather than a third-party calling SDK, which keeps latency and cost predictable at scale.
Usage-linked billing
A dedicated ledger module records call usage against subscription plans, so billing reflects what the SFU logged rather than relying solely on client-reported call duration.
Scalable signalling
Socket.io with a Redis adapter lets signalling scale across multiple backend instances without pinning users to a single node.
Results
Self-hosted SFU
Media layer
Socket.io + Redis
Signalling
Calls · Ledger · Subscriptions
Core modules
Paintcart
E-commerce · Mobile · Backend