Why did my flag change take minutes to reach my app?

Last updated:

Because the streaming connection is not established, so the client picks the change up on its next poll instead. Streaming is on by default and delivers changes within seconds, so a delay of roughly thirty seconds points at the poll interval taking over. Proxies that buffer responses and HTTP clients with a short timeout are the usual reasons the stream drops.

A flag change should reach a connected SDK in seconds. When it takes noticeably longer, the shape of the delay tells you what happened.

SDKs stream updates by default and fall back to polling when streaming is turned off. A change that consistently lands about thirty seconds late is arriving on the default poll interval, which tells you the stream is not carrying it. If the change only ever lands when the process restarts, nothing is refreshing at all.

Why the stream drops

Both of the common causes look like a broken feature when they are really a broken connection.

The first is an HTTP client applying its overall timeout to a long-lived stream. A flag stream is meant to stay open indefinitely, so a client configured to abort any request after ten seconds will tear it down on schedule and keep reconnecting. We shipped exactly this bug in our own C# SDK once. It presented as flags being slow, never as a network fault, which is what makes it worth checking first.

The second is something between you and the service buffering the response. Reverse proxies and some corporate egress paths hold a response until it completes. For a stream, that is never. The connection looks healthy from both ends and no events arrive.

Confirming which one you have

// Streaming on (the default): changes arrive in seconds
const client = new FeatureflipClient({ sdkKey, streaming: true });
// Streaming off: changes arrive on the poll interval instead
const client = new FeatureflipClient({ sdkKey, streaming: false, pollInterval: 30_000 });

One detail matters when you read those timings. With streaming enabled, polling is disabled, and there is no quiet safety net running underneath, which is deliberate, because two update paths racing each other can apply snapshots out of order and lose an edit entirely.

So a stream that silently fails does not degrade to slow updates. It degrades to no updates at all until the client reconnects.

The fix

Give the streaming connection its own timeout settings instead of letting it inherit your general HTTP client’s, and confirm nothing in the path buffers responses. If you operate somewhere a stream genuinely cannot survive, turn streaming off explicitly and set a poll interval you are happy to live with. A predictable thirty seconds gives you something you can actually design around.

Transport behaviour is documented in Streaming, with the reliability model in Reliability.

Still stuck?

The docs cover every SDK, and the free Solo plan is enough to reproduce most of these locally.