Applies to: Chat, Video, Feeds | All SDKs
Error code covered: 48
Quick Answer (2 minutes)
Most timeout and performance issues fall into one of these categories:
- Client timeout too low: The default client timeout is 3000ms. Increase it to 6000ms for complex queries.
-
Wrong base URL: Use the edge URL
https://chat.stream-io-api.comfor automatic region routing. - Unfiltered queries: Add filters to channel queries. Unfiltered or overly broad queries are the number one cause of timeouts.
-
Network latency vs. server time: Check the
durationfield in API responses to separate server processing time from network latency.
Understanding Timeouts
There are several layers where a timeout can occur. Understanding which layer is responsible is the key to fixing the problem.
| Timeout Type | Default Value | Description |
|---|---|---|
| Client-side timeout | 3000ms (most SDKs) | How long the SDK waits for a response from the server before aborting the request. The error message Timeout of 3000ms exceeded comes from the client SDK, not the server. |
| Server-side query timeout | 3s for DB queries | How long the server allows a database query to run. Channel queries have a configurable timeout. If the server-side query times out, it returns error code 48. |
| HTTP request timeout | 10s standard, 15min uploads | The overall time the server allows for processing a request. Upload endpoints have a much longer timeout to accommodate large file transfers. |
Key insight: If you see Timeout of 3000ms exceeded, the server may still be processing your request successfully — the client simply gave up waiting. Increasing the client timeout or optimizing your query will resolve this.
Decision Tree
Work through these steps in order. Each step either resolves the issue or tells you where to go next.
Step 1: Is this a platform-wide issue?
Visit status.getstream.io and confirm all systems are operational.
- If there is an active incident: Wait for resolution. Subscribe to status updates for notifications.
- If all systems are operational: Continue to Step 2.
Step 2: Check the duration field in API responses
Every Stream API response includes a duration field that shows server-side processing time. Compare this to your total request time measured on the client.
-
Low duration (< 500ms) + high total time: This is a network latency problem. The server processed your request quickly, but the response took a long time to reach you. Verify you are using the edge URL (
https://chat.stream-io-api.com) and check the Network Debugging section. - High duration (> 2000ms): This is a slow query problem. The server is spending too long processing your request. Go to Query Optimization.
- No response at all: This is a network or DNS issue. The request is not reaching the server. Go to Network Debugging.
Increasing Client Timeout
If you are hitting client-side timeouts, increasing the timeout gives the server more time to respond. This is a quick fix while you work on the underlying cause (usually query optimization).
JavaScript
const client = StreamChat.getInstance('API_KEY', {
timeout: 6000, // 6 seconds (default is 3000)
});
iOS (Swift)
let config = ChatClientConfig(apiKeyString: "API_KEY") config.timeoutIntervalForRequest = 10 // seconds let client = ChatClient(config: config)
Android (Kotlin)
val client = ChatClient.Builder("API_KEY", context)
.requestTimeout(6000) // milliseconds
.build()
Note: Increasing the timeout is not a permanent solution. If your queries regularly take more than 3 seconds, optimize them using the guidance in the Query Optimization section below.
Region Configuration
Stream operates multiple regions. Our edge network automatically routes requests to the correct datacenter based on your app’s region, so you do not need to configure region-specific URLs.
Always use the edge URL
The edge URL automatically routes requests to the correct datacenter for your app:
https://chat.stream-io-api.com
Check your app’s region
Navigate to Dashboard > Your App > Overview to see which region your app is deployed to. The edge URL will automatically route to the correct region for your app.
Query Optimization (The Most Common Fix)
The number one cause of timeouts is unfiltered or overly broad channel queries. An unfiltered query forces the server to scan all channels in your application, which is slow and will time out for any non-trivial dataset.
Bad — loads all channels, very slow
// DO NOT DO THIS — will time out as your app grows
const channels = await client.queryChannels({});
Good — filtered, paginated, and sorted
const channels = await client.queryChannels(
{
type: 'messaging',
members: { $in: [userId] },
last_message_at: { $exists: true }
},
[{ last_message_at: -1 }],
{ limit: 20, message_limit: 25 }
);
Optimization checklist
-
Always filter by
type. This reduces the query scope dramatically because the server can partition by channel type. -
Always filter by
members(client-side). This is required for permissions and is also critical for performance. Without it, the server must check permissions on every channel. -
Filter out empty channels. Use
last_message_at: { $exists: true }to skip channels that have never had a message. -
Sort by
last_message_at. This is the most optimized sort path on the server. Sorting by custom fields or other attributes is slower. -
Set
limitexplicitly. The default is 10, but be explicit. Never request more channels than you display on screen. -
Set
message_limit. Only load the messages you need per channel (for example, 25 for a chat list preview). Loading full message history for every channel is expensive. -
Use
state: falseif you only need metadata. If you do not need full channel state (members, messages, reads), setstate: falseto skip loading it.
Network Debugging
If the API is unreachable or extremely slow, use these steps to identify where the problem is.
1. Test basic connectivity
Run this command to measure each phase of the connection:
curl -w "@-" -o /dev/null -s "https://chat.stream-io-api.com/health" <<'EOF'
time_namelookup: %{time_namelookup}s
time_connect: %{time_connect}s
time_appconnect: %{time_appconnect}s
time_total: %{time_total}s
EOF
Interpret the results:
| Metric | Healthy Value | If Slow |
|---|---|---|
time_namelookup |
< 100ms | DNS resolution is slow. Try a different DNS resolver (for example, 8.8.8.8 or 1.1.1.1). |
time_connect |
< 200ms | TCP connection is slow. This suggests network congestion or geographic distance. Check region configuration. |
time_appconnect |
< 400ms | TLS handshake is slow. Could be a proxy or firewall intercepting connections. |
time_total |
< 500ms | Overall latency is high. Work through the previous metrics to identify the bottleneck. |
2. Check DNS resolution
nslookup chat.stream-io-api.com
This should resolve to one or more IP addresses. If it fails or takes a long time, your DNS resolver may be the issue.
3. Check for proxy or firewall interference
Corporate networks often block WebSocket connections or add latency through SSL inspection proxies. If you are on a corporate network:
- Try the same request from a personal network or mobile hotspot.
- Ask your network administrator if outbound connections to
*.stream-io-api.comon port 443 are allowed without inspection.
4. Check for VPN issues
VPNs can add significant latency or route traffic through distant locations. If you are using a VPN:
- Try disconnecting the VPN and retesting.
- If the VPN is required, check if split tunneling is available so that Stream API traffic bypasses the VPN.
WebSocket-Specific Performance
- WebSocket connections use the same base URL as REST API calls. Region configuration applies equally.
- If a WebSocket connection fails, SDKs fall back to long-polling, which is significantly slower. If you are experiencing degraded real-time performance, check that WebSocket connections are succeeding.
- WebSocket connections require port 443 to be open for outbound traffic. Some firewalls or proxies block WebSocket upgrade requests even on port 443.
- Compression is negotiated automatically between the SDK and the server to reduce bandwidth usage.
- To verify WebSocket is working, check your browser’s network tab (or equivalent) for a successful
101 Switching Protocolsresponse.
Large Channel Considerations
- Channels with 100,000 or more members can be slower to query than smaller channels.
- The default member limit per query is 100 members returned. Use pagination to load more.
- The default message limit per query is 100 messages returned. Use pagination to load more.
- For very large channels, use pagination rather than requesting all members or messages at once.
- Consider dynamic partitioning for channels with extremely high concurrency. Contact support for guidance on enabling this.
Performance Metrics to Collect
The duration field in every API response is your most important diagnostic tool. It shows the server-side processing time only, which lets you isolate server performance from network latency.
const response = await client.queryChannels(filter, sort); // Every API response includes a "duration" field: // "duration": "45.12ms" — this is SERVER processing time only // // If your total request time is 2000ms but duration is 45ms, // the remaining 1955ms is network latency.
When investigating performance issues, always record both values:
-
Server duration (from the
durationfield in the response): How long the server took to process the request. - Total client time (measured in your application): How long the entire round trip took from the client’s perspective.
The difference between these two values is your network latency. If the server duration is low but the total time is high, the problem is in the network, not the query.
Diagnostics Checklist
If you need to escalate, copy this template, fill it out, and include it in your support request:
Timeout / Performance Diagnostics ================================== 1. Error message (exact text): 2. Error code (if any): 3. Endpoint being called: 4. Client timeout setting (ms): 5. Base URL configured: 6. App region (from Dashboard): 7. User's geographic location: 8. API response "duration" field value: 9. Total request time (client-measured): 10. Query filter (paste): 11. Query sort (paste): 12. Query options (limit, offset, state, message_limit): 13. Approximate number of channels in app: 14. Network type: [ ] Home [ ] Corporate [ ] Mobile [ ] VPN 15. SDK + version:
Escalation
- Check the status page first. If status.getstream.io shows an active incident, wait for resolution. Subscribe to updates so you are notified when it is resolved.
- Optimize your queries. The majority of timeout issues are resolved by adding proper filters and pagination. Review the Query Optimization section before escalating.
- File a support ticket. If you have optimized your queries, verified your region configuration, and still experience timeouts, include the completed diagnostics checklist above in your support request. The more detail you provide, the faster we can help.
Comments
0 comments
Please sign in to leave a comment.