How TiniTalk works
This technical overview is for anyone curious about what happens under the hood. You do not need to understand these details to use TiniTalk.
Overall architecture
TiniTalk consists of an Android calling app, an experimental web client, a server on your VPS, and a separate TiniTalk Admin app for the server owner. There is no central TiniTalk cloud between them: each server operates independently and serves only its own users.
Android client
Kotlin, Jetpack Compose, WebRTC, system notifications, Android's incoming call screen, and screen sharing.
Web client
An experimental PWA client for iPhone and browsers: audio and video calls, contacts, history, and Web Push.
Server
Go, one main binary, an HTTPS API, WSS signaling, built-in TURN, and SQLite.
TiniTalk Admin
A separate Android app for installing the server, checking its status, and managing users.
Persistent data
SQLite stores users, devices, contacts, and a compact call history.
How a call works
-
The client contacts the server
When someone taps “Call”, the app sends a request to its server. The server checks authorization, finds the other person, and determines whether the call can begin.
-
The server relays signaling events
The secure WSS channel carries only call control messages: call, accept, decline, end, and exchange WebRTC offers and ICE candidates. The conversation itself does not travel over this channel.
-
The phone wakes up for an incoming call
If the app is closed or the phone is asleep, the server sends a short Web Push notification. TiniTalk uses Android's standard push notification mechanism and Google's infrastructure to deliver it, allowing the app to wake up and show the incoming call. Only an encrypted signaling notification passes through Google's servers; audio and video do not.
-
The phones connect through WebRTC
Once the call is accepted, the phones try to connect directly. This is usually the best route, with lower latency and less load on the VPS. WebRTC encrypts audio, video, and screen sharing between the phones.
-
TURN helps when a direct connection is blocked
When NAT or network restrictions prevent a direct connection, a TURN server is used. The media stream then passes through the VPS, and the load depends on how many calls take this route.
Multiple servers
You can keep accounts from several compatible TiniTalk servers on one phone. This is not federation: servers do not share users with each other. The app shows contacts and call history from different accounts in a single interface. The contact you select automatically determines which account and server are used for the call.
Data and privacy
TiniTalk's authors do not maintain a central database of users or calls. The main data is stored on the selected server owner's VPS: users, devices, contacts, sessions, and call history. The app saves the information needed to sign in and connect on your phone. Audio, video, and screen sharing travel through WebRTC, either directly or through TURN when there is no other route. For incoming calls, the Web Push distributor receives an encrypted signaling notification; audio and video are not transmitted through Web Push.
The names you give your contacts are saved on your server. The contact photos you choose are stored only on your phone and are not sent to the server.
The privacy described here applies to your own server, which you control. It depends on how you configure and secure that server. If you connect the app to someone else's TiniTalk server, you need to trust its owner or administrator: they control the server software, database, and logs, and can change how the server operates. TiniTalk cannot be responsible for what happens on someone else's installation.
TiniTalk's authors do not have access to your server. We do not track users, collect telemetry, or embed analytics.
Unreliable networks
Calls require an internet connection. TiniTalk includes mechanisms to help maintain and restore calls over weak mobile connections, complex international routes, switches between Wi-Fi and mobile data, and brief outages.
- voice is transmitted using WebRTC and Opus;
- audio takes priority over video;
- on a poor connection, WebRTC reduces video and screen sharing quality; if the media connection is lost, the app temporarily stops the camera and resumes it after the connection is restored;
- after a network change, the app attempts to restore signaling and the WebRTC connection;
- if a direct connection is impossible, TURN on your server is used;
- distinct audio cues help you tell whether a call is ringing, the other person is busy, the connection has dropped, or reconnection is still in progress.
Server load
Normally, the server handles authorization, signaling, Web Push, call history, and user management. When phones connect directly, audio and video do not add load to the VPS. Even a modest server with 1 vCPU and 512 MB of RAM is suitable for a family, a small community, hundreds of registered users, and dozens of simultaneous calls. Extra capacity is usually needed only if you expect many simultaneous video calls.