Routing Around the Void: What We Learn When Telegram Goes Dark
From administrative blackouts in India to infrastructure wobbles in Singapore, Aarav Mehta dissects the mechanics of network failure and client resilience.
The monsoon in Bengaluru has a way of exposing fragile infrastructure. Last night, as the rain drummed against my balcony, my terminal started throwing a sequence of ETIMEDOUT errors. My local monitoring dashboard lit up. To the average user, "Telegram is down" is a singular frustration. To a systems engineer, it is a diagnostic puzzle. Is it a DNS-level block, a BGP routing black hole, or a genuine server-side database lockup?
We saw both extremes of this failure spectrum in 2026. In June, the Indian government temporarily banned the platform to prevent cheating in the NEET medical entrance exams, a move reported by the BBC and subsequently upheld by the Delhi High Court as detailed by the Internet Freedom Foundation and etvbharat.com. Then, in September 2026, thousands of users in Singapore experienced a classic infrastructure outage, according to The Straits Times.
One failure was administrative routing manipulation; the other was a physical, technical bottleneck. Yet, from the perspective of a client-side socket, they look remarkably similar.
In the NEET exam leak context, ISPs often rely on DNS hijacking—returning a loopback address or a sinkhole IP. This fails instantly with a connection refused error. Contrast this with Singapore’s infrastructure wobble, where packets likely dropped into a silent routing black hole, forcing the client to wait for the OS-level TCP timeout.
When a massive distributed network goes dark, client applications often make the problem worse. Millions of mobile apps globally enter a tight loop of aggressive reconnection attempts. This is the "thundering herd" problem at a planetary scale. If your system design relies on a naive reconnect-on-fail policy, your clients will inadvertently DDOS your load balancers the moment they recover.
To mitigate this, mechanical sympathy demands that we design clients to fail gracefully. We must implement exponential backoff with jitter to spread the connection load.
Here is how we handle this deterministically in TypeScript:
interface ConnectionResult {
success: boolean;
latencyMs: number;
error?: string;
}
async function connectWithBackoff(
endpoint: string,
maxAttempts: number = 5
): Promise<ConnectionResult> {
let delay = 100; // ms
const startTime = Date.now();
for (let i = 0; i < maxAttempts; i++) {
try {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 5000);
await fetch(endpoint, { signal: controller.signal });
clearTimeout(timeoutId);
return { success: true, latencyMs: Date.now() - startTime };
} catch (err) {
const errorMsg = err instanceof Error ? err.message : String(err);
if (i === maxAttempts - 1) {
return {
success: false,
latencyMs: Date.now() - startTime,
error: errorMsg
};
}
// Exponential backoff with simple jitter
const jitter = Math.random() * 50;
delay = delay * 2 + jitter;
await new Promise<void>((resolve) => setTimeout(resolve, delay));
}
}
return {
success: false,
latencyMs: Date.now() - startTime,
error: "Max attempts reached"
};
}
Notice the math in the backoff calculation. We do not just double the delay; we inject random jitter. Without jitter, every disconnected client would retry at the exact same synchronized intervals, creating massive, cyclical traffic spikes that can easily keep a recovering gateway down.
There is a quiet dignity in building software that expects the network to be hostile. Whether the block comes from an ISP implementing a High Court order or a fiber cut under the Singapore Strait, the system must degrade gracefully. We must stop assuming infinite bandwidth and perfect routing. The real world is noisy, highly regulated, and physically fragile. Design your systems for the dark, and they might just survive the light.