Appwrite Realtime Subscriptions: Real‑time updates for collaborative apps
Learn how Appwrite’s Realtime subscription feature lets you push database changes instantly to clients, with setup steps, a live example, and key trade‑offs.
28 Aug 2026, 07:04 UTC

Why a live‑collaborative app feels stuck without realtime
You are building a shared to‑do list that should update instantly for every user. Without a mechanism that pushes changes as they happen, each client must poll the server, which adds latency and load. The problem is not just “delay” – it is the extra code you must write to sync state, handle race conditions, and keep the UI responsive.
Thesis: Appwrite’s Realtime subscription gives you a ready‑made, low‑latency channel
Appwrite’s Realtime feature uses a persistent WebSocket connection to push database, storage, and function events to every client that has subscribed. The SDK handles the connection lifecycle, token authentication, and automatic reconnection, so you can focus on reacting to the data instead of managing the transport.
How the subscription works
When a client calls the subscribe method, it tells the server which collection, document ID, or bucket it wants to monitor. The server opens a WebSocket, authenticates the client with a JWT, and then sends a JSON payload for each create, update, or delete event that matches the subscription criteria. Because the channel is persistent, the latency is typically sub‑100 ms after the initial handshake.
Query strings can be added to the subscription request to filter events server‑side, reducing the amount of data sent over the wire. For example, you can listen only to documents where a field status equals “open”.
Setting up a local instance for testing
Run the official Docker image and enable the Realtime service in the console:
docker run -d -p 80:80 -p 443:443 --name appwrite-appwrite appwrite/appwrite:1.5
After the container starts, open the Appwrite UI at http://localhost, go to the “Realtime” section, and toggle the service on. The UI will show a green indicator that the WebSocket endpoint is active.
Required permission: the user that creates the subscription must have read access to the target collection. If you use the default “admin” account, you have full rights; otherwise, create a scoped user with the realtime.read role.
Worked example: live updates in a to‑do list
Below is a minimal browser‑side example using the Appwrite Web SDK.
- Include the SDK script:
- Initialize the client with your endpoint and API key:
- Subscribe to the “tasks” collection:
- Insert a new task through the API (you can do this from another terminal or a separate page):
- Observe the console log instantly after the POST succeeds. The callback receives the full document, allowing you to update the UI without a refresh.
<script src="https://cdn.jsdelivr.net/npm/appwrite@1.5.0/dist/appwrite.min.js"</script>
const client = new Appwrite.Client()
.setEndpoint('https://localhost/v1')
.setApiKey('YOUR_API_KEY');
client.collection('tasks')
.subscribe(doc => {
console.log('Task changed:', doc.id, doc.text);
});
fetch('https://localhost/v1/tasks', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ text: 'Buy milk', status: 'open' })
});
To verify that the WebSocket stays alive after a network glitch, disconnect your Wi‑Fi for a few seconds and then reconnect. The SDK will automatically attempt reconnection, and the server log should show a “realtime reconnect” entry.
Trade‑off and limitation
Each active subscription holds a WebSocket on the Appwrite server. At scale, many concurrent clients can increase memory consumption and CPU load, especially if the server hosts many collections. The documentation recommends capping the number of subscriptions per client or using coarse‑grained filters to limit the number of open channels.
Another practical concern is message ordering. Events are guaranteed in the order they arrive on a single connection, but after a reconnection the server may resend missed events out of order. Implement idempotent handling on the client – for instance, store the latest document ID and ignore duplicates.
Actionable closing: get started in three steps
- Spin up Appwrite (Docker command above) and enable Realtime in the console.
- Create a user with read permission on the collection you want to monitor.
- Integrate the
subscribecall into your front‑end code, test with a simple document update, and verify the server logs and browser console show the instant callback.
If you notice high memory usage, consider grouping related documents into a single subscription or reducing the frequency of writes. With these steps you can turn a static app into a live collaborative experience using a feature that is built into Appwrite.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.