Diagnosing Silent Realtime Events in Appwrite: A Step‑by‑Step Guide
When Appwrite Realtime events never arrive or stop after a few minutes, the problem often lies in permissions, session state, channel naming, or proxy configuration. This guide walks through a diagnostic checklist, common causes, and practical fixes.
16 Nov 2025, 23:58 UTC

Problem Statement
A client that has subscribed to an Appwrite Realtime channel receives no events, or events cease after a few minutes or hours, while normal SDK reads and writes continue to work. The silence is not accompanied by an error message or a closed socket; the connection appears healthy in the browser’s Network tab.
Recognizable Condition
- Developer opens the app, subscribes to a channel such as
databases..collections..documents. - After a write from another client, the subscribed client never sees the
document.createordocument.updateevent. - After a few minutes of idle time, the events stop entirely, even though new writes still succeed on the server.
Common Causes & Why They Happen
1. Permission‑Filtered Delivery
Realtime pushes only events for resources that the current session’s roles can read. If a document is not readable by the subscriber’s user or the guest role, the event is silently dropped.
2. No Valid Session
Private channels require an authenticated session. Anonymous visitors receive events only for publicly readable resources. If the session has expired or was never created, the subscription is effectively hidden from the server.
3. Incorrect Channel String
Channel strings must match the exact grammar: databases.{databaseId}.collections.{collectionId}.documents. A typo or a reference to a non‑existent collection yields a connection that never matches any events.
4. No Replay After Reconnect
Appwrite Realtime does not backfill missed events after a disconnect. If a client reconnects, it only receives new events, potentially leaving the UI out of sync.
5. Payload Size Limit
Large documents are truncated or dropped if they exceed the realtime payload size limit (a few kilobytes by default in self‑hosted deployments). The write succeeds, but the subscriber never receives the event.
6. Self‑Hosted Proxy Pitfalls
Reverse proxies must forward WebSocket Upgrade and Connection headers and must not buffer or time out idle secure connections. Incorrect proxy settings can silently drop frames after a few minutes.
Diagnostic Checklist
- Confirm WebSocket Connection
- Open
DevTools → Networkin the browser. - Filter by
WSand locate the connection torealtime.appwrite.io(or your self‑hosted URL). - Verify that the connection status is
OPENand that ping frames are being exchanged.
- Open
- Verify Session State
- In the console, run
appwrite.auth.getSession()(or the equivalent SDK method) to ensure a session object is returned. - Check
session.expiresAtto confirm it has not passed.
- In the console, run
- Check Read Permissions
- Navigate to the Appwrite console, open the target collection, and review the
Readrules. - Ensure that the current user’s role (or the
publicrole for guests) is allowed to read the document.
- Navigate to the Appwrite console, open the target collection, and review the
- Validate Channel String
- Print the channel string used in the
subscribecall. - Compare it against the channel list from the official documentation for your SDK version.
- Print the channel string used in the
- Test with a Second Client
- Open a second browser tab, authenticate with a different user, and subscribe to the same channel.
- Perform a write from the first client and observe if the second client receives the event.
- Self‑Hosted Proxy Test
- Bypass the reverse proxy (e.g., connect directly to the Appwrite container) and repeat the subscription.
- If events arrive, the proxy configuration is likely the culprit.
- Inspect Payload Size
- Attempt to write a document just below the known payload limit (e.g., 4 KB) and observe if the event arrives.
- If it does, increase the document size gradually to locate the threshold.
Troubleshooting & Fixes
| Cause | Diagnostic Check | Fix |
|---|---|---|
| Permission‑filtered delivery | Check read rules on collection/document. | Grant read permission to the user’s role or to public for guests. |
| No valid session | Verify session exists and is not expired. | Re‑authenticate or refresh the session token. |
| Incorrect channel string | Log the channel string and compare to SDK docs. | Correct the string; ensure databaseId and collectionId match the project. |
| No replay after reconnect | Observe UI drift after a network hiccup. | On onReconnect, trigger a fresh listDocuments call to re‑hydrate state. |
| Payload size limit | Write a large document and monitor event arrival. | Reduce payload size or store large data in Appwrite Storage and sync a pointer. |
| Proxy mis‑configuration | Bypass proxy; events appear. | Ensure proxy forwards Upgrade and Connection headers and disables buffering for WS connections. |
Example: Subscribing with the JavaScript SDK
// Ensure the SDK is initialised
const sdk = new Appwrite();
// Replace placeholders with your project data
sdk.setEndpoint('https://cloud.appwrite.io/v1')
.setProject('YOUR_PROJECT_ID');
// Subscribe to all document events in a collection
const channel = sdk.realtime.subscribe('databases.YOUR_DB_ID.collections.YOUR_COLLECTION_ID.documents');
channel.$on('document.create', (event) => {
console.log('New document created:', event);
});
channel.$on('document.update', (event) => {
console.log('Document updated:', event);
});
channel.$on('document.delete', (event) => {
console.log('Document deleted:', event);
});
// Listen for reconnection to re‑sync state
channel.$on('reconnect', () => {
sdk.database.listDocuments('YOUR_DB_ID', 'YOUR_COLLECTION_ID')
.then(res => console.log('Re‑fetched docs:', res))
.catch(err => console.error(err));
});
Escalation Criteria
- All diagnostic checks pass but events still do not arrive.
- The issue occurs only on a specific deployment (self‑hosted) and not on Appwrite Cloud.
- You suspect a deeper server‑side bug or a new SDK version incompatibility.
At this point, gather the following before reaching out:
- SDK version and language (e.g., JavaScript v3.0.0).
- Appwrite server version and deployment type.
- Minimal reproducible code snippet and console logs.
- Network trace showing the WebSocket frames.
Submit the information to the Appwrite support channels or the official GitHub issues page.
Limitations & Verification Notes
- Payload size limits and environment variables differ between Appwrite Cloud and self‑hosted releases; check the
APPWRITE_REALTIME_MAX_PAYLOADvariable for your version. - Permission filtering is a feature, not a bug; if you intentionally want to hide events from certain roles, design your UI accordingly.
- Proxy settings vary widely; the example assumes an Nginx or Traefik setup. Verify your stack’s documentation for WebSocket support.
- Always test changes in a staging environment before applying to production.
Practical Result Check
After applying a fix, perform the following quick test:
- Open two browser tabs, authenticate with different users.
- Subscribe the first tab to the target channel.
- From the second tab, create a new document in the collection.
- Verify that the first tab logs the
document.createevent within a few seconds. - Disconnect and reconnect the first tab; ensure the UI remains in sync by observing the
reconnecthandler.
Successful completion of these steps confirms that Realtime events are now reliably delivered.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.