Hero image for the blog post Long Polling Is Sneakily Brilliant

Long Polling Is Sneakily Brilliant

Long polling works because the server waits instead of forcing the client to ask again and again.

In system design interviews, when a client needs to receive events from a server, there are usually three answers people reach for:

  • polling
  • websocket
  • webhook

That answer became concrete when I started building a small Telegram bot: a personal process running somewhere on my own setup, reacting when I send it a message.

Telegram gives you two main ways to receive updates:

  • polling
  • webhook

My first instinct was: webhook.

Because of course. Telegram sends the update to my server. My server reacts. Very clean. Very grown-up. Very architecture diagram friendly.

Then the setup started whispering nonsense at me.

HTTPS. DNS. Reverse proxy. Request protection. Whitelisting. Exposing something from my home setup. Securing the endpoint properly.

And at some point I had the only reasonable reaction:

Flemme.

French for being tired before even beginning.

Too much ceremony for a tiny bot.

So I looked at polling.

In my head, polling meant the dumb version: a loop hitting the API every 5s asking, “anything new?”

While going down that path, I stumbled upon the actual mechanism Telegram uses for this mode.

Long polling.

And honestly: what a good idea.

Webhook Was Ceremony

Webhooks are great when they fit.

But for this thing? A small Telegram bot, probably running on a ZimaBlade at home, used by me? The setup was already heavier than the bot.

Yes, it would work.

But I do not want every side project to become an ops exercise before it becomes useful.

In general, I prefer the simplest dumb route first. Build the stupid thing. Make it breathe. Then add complexity when reality earns the right to ask for it.

My old mental model of polling was the dumb version:

every 5 seconds:
  ask Telegram: "anything new?"
  Telegram: "no"
  ask again
  Telegram: "still no"
  ask again

That works, but it feels wasteful and kind of sad.

Long polling changes one thing: the server does not rush to answer no.

The Server Just Waits

Long polling keeps the client-side behavior almost offensively simple.

From the bot’s point of view, it is just a request.

But the server does something clever with it:

client sends request
server waits
event arrives
server responds
client immediately opens the next request

That is it. One request, held open at the right time.

Just a request that the server does not answer immediately.

That part is what got me.

I expected dumb repeated polling, but the server just holds the request open.

When a Telegram message arrives, the request returns. The bot handles the update. Then it opens the next request and waits again.

Simple behavior. Clever result.

The Speed Illusion

The funny part is that long polling feels fast because the server is allowed to be slow.

Usually, we try to make servers answer faster. Shorter response time. Lower latency. Less waiting. Faster everything.

Here, the server delays the answer on purpose.

And that delay creates the speed illusion.

With naive polling every 5s, a message can arrive just after the last poll. The user waits until the next tick.

message arrives
client waits...
next 5s poll happens
client receives message

So the response lands somewhere between 0 and 5s later. Sometimes instant. Sometimes mildly annoying. Always a little random.

With long polling, the request is already hanging there, waiting.

client is already waiting
message arrives
server responds immediately

To the user, it feels fast.

The waiting moved to the right place.

Long polling is the trick of delaying a request to make the product feel more responsive.

That is the part I love.

Dead Simple For The Client

Yes, you can get instant-ish behavior with webhooks.

Yes, you can get real-time behavior with websockets.

Both are valid. Both have their place.

Long polling hits a sweet spot that I had not appreciated enough: it gives you a push-like feeling while keeping the client model boring.

And boring is good when boring is enough.

From that process, long polling is beautiful because the mental model stays tiny:

  • Ask for updates.
  • Wait.
  • Receive updates.
  • Repeat.

That is the whole dance.

No public callback URL. No TLS setup rabbit hole. No reverse proxy.

The Underrated Middle Option

Long polling sits in a useful middle place.

Naive polling is simple but clumsy.

Webhooks are elegant but need a reachable, secured server.

Websockets are powerful but bring their own shape, lifecycle, and operational concerns.

Long polling is the weird middle child that says:

What if we keep HTTP, keep the client dumb, and just wait a bit before answering?

Its charm is practical.

I like systems that start simple. Not because simple is morally superior, but because complexity lies. It shows up dressed as professionalism, then eats the weekend.

Sometimes the proper architecture is overkill.

Sometimes the boring request is enough.

Sometimes the clever move is not to add more machinery, but to let the server wait.

Long polling is a clever solution on top of dead-simple behavior.

That is the kind of engineering trick I love: small surface area, good user feel, almost no ceremony.

Start with the simplest dumb route first.

Build on top when reality forces you.

Until then, let the request hang.