Telegram Webhook: How to Set One Up and Keep It Alive
A webhook is the moment your bot stops asking and starts being told. Instead of your code repeatedly calling Telegram to ask whether anything happened, Telegram calls you the instant something does. That inversion sounds like a small optimisation and is actually the difference between a bot that costs you a server loop and a bot that sits idle until it is needed.
It is also the point where a bot acquires a public address, and that changes what you have to think about. A polling bot needs no inbound network at all. A webhook bot needs a reachable endpoint over encrypted transport, on one of exactly four ports, with a certificate that survives inspection, and ideally a shared secret so you can tell Telegram's requests from anybody else's.
This article covers the switch itself, every parameter that shapes it, the three ways certificates fail, the header that authenticates incoming calls, how to read the diagnostic the platform gives you, the trick where your reply to the webhook is itself an API call, and the rate limits that start applying the moment you answer.
What a Webhook Actually Is
Strip the jargon and the mechanism is unremarkable, which is good news.
An address you give the platform
You tell Telegram where your bot lives, and from then on every update is delivered to that address as an ordinary request carrying the update in its body. There is no persistent connection, no special protocol and no client library requirement. If your stack can serve a web request, it can receive a webhook.
That is worth dwelling on because it removes most of the mystique. There is no library you must adopt, no framework that is blessed, and no long-lived socket to keep alive across restarts. A single route in whatever you already run is the entire integration, which is why a webhook is usually a smaller change than the people avoiding it expect.
What arrives
Each delivery contains an update object, which is the same structure a polling bot receives. Nothing about the content changes when you switch; only the direction of the call does. Code that already understands updates keeps understanding them, and the migration is almost entirely about transport.
One practical consequence is that you can write and test your handler long before you own a webhook. Feed it a saved update, assert on what it does, and the same function will work unchanged when real deliveries start. Treating the transport as a thin wrapper around a pure function is what makes the switch dull, and dull is the goal.
Why this is worth doing
Latency and cost. A polling bot is either asking too often, which wastes requests, or not often enough, which adds delay. A webhook removes that trade completely: nothing happens until something happens, and when it does, it arrives immediately. For anything user-facing that difference is visible.
There is a second benefit that only shows up on a bill. A polling loop consumes a process, a network request and a wake-up on a schedule you set, whether or not anybody is talking to your bot. A webhook consumes nothing at all until an update arrives, which suits every hosting model that charges for what you use rather than for what you reserve.
Push Versus Pull, and Why You Cannot Have Both
The two mechanisms are alternatives, not layers, and the documentation is blunt about it.
The stated rule
Long polling is a pull mechanism and a webhook is push. The method you use to pull updates will not work while an outgoing webhook is set up. That is not a warning about degraded behaviour, it is a refusal, and it is the correct design, because two consumers of one queue would produce duplicated or missing updates depending on who won each race.
The symptom when you forget
A local development script that suddenly returns errors while the deployed bot works perfectly is nearly always this. Somebody set a webhook in production, and the local script is now trying to pull from a queue that is being pushed elsewhere. Nothing is broken; the platform is enforcing exclusivity.
The confusing part is the direction of the error. It appears on the machine that is polling, which is usually the one you are actively working on, while the machine at fault is the server you deployed last week and are not looking at. Checking which webhook is currently registered takes one call and resolves this in seconds once you know to make it.
The clean way to work on both
Use separate bots. A development bot with its own credential polling locally, and a production bot with the webhook, is the arrangement that avoids the conflict entirely. Sharing one credential between a laptop and a server is the setup that produces the confusing failures, and the fix costs nothing but a second registration, which our walkthrough on how to create a Telegram bot covers.
The Requirements That Are Not Negotiable
Four constraints decide whether a webhook can work at all, and none of them bends.
Encryption is mandatory
A webhook requires encrypted transport no matter which port is used, and it is not possible to use a plain-text endpoint. There is no development exception, no local override and no flag. If your endpoint is not encrypted, there is no webhook.
This is the requirement that decides how people develop. Tunnelling a local port out to a public encrypted address is the usual answer, and it works, but it also means your development endpoint changes address every time the tunnel restarts, and each change is another registration. Knowing that in advance saves an afternoon of wondering why yesterday's setup stopped working overnight.
Only four ports work
The supported ports are 443, 80, 88 and 8443, and anything else simply will not function. This catches people running services on the ports their framework picked by default, and the failure is silent from the bot's point of view, because the platform cannot deliver and your code never sees a request that was never made.
The silence is the difficult part. A wrong port produces no error in your application, no entry in your access log and no exception anywhere, because nothing ever reached you. The only place the failure is visible is the platform's own diagnostic, which is why that call is the first step of every investigation rather than a later one.
The address must be reachable and final
Redirects do not work. An address that answers with a redirect to the real endpoint fails, which is a common accident when a host is configured to send everything to a canonical name. Give Telegram the final address rather than one that points at it.
Redirects are worth checking even when you did not configure one. Hosting platforms add them for their own reasons, most commonly forcing a canonical host or appending a trailing slash, and both are enough to break delivery. A request from outside your network, following nothing, is the only reliable way to see what the platform sees.
You need somewhere to put it
All of the above means a webhook needs real hosting with a real certificate on a real name. That is trivial if you already run infrastructure and a genuine obstacle if you do not, and it is the main reason small bots stay on polling longer than they should.
Certificates, and the Three Ways They Fail
Certificate problems are the single largest category of webhook failure, and the documentation names the specific traps.
Self-signed is allowed
You do not need a certificate from a commercial authority. A self-signed certificate works, provided you upload the public certificate in the standard text format as data when you register the webhook. That upload is what lets the platform trust a certificate nothing else would trust.
It is worth being clear about what this does and does not buy. The upload establishes trust between you and the platform for that one endpoint. It does not make the certificate valid anywhere else, so a browser will still complain, and anybody testing your endpoint by hand will see a warning that has nothing to do with whether the webhook works.
Wildcards may not be supported
A certificate covering every subdomain of a name may not work, and the documentation says so directly. This is a painful one, because wildcard certificates are extremely common in hosting setups and everything else about the deployment looks correct. If your certificate is a wildcard and deliveries are failing, that is the first thing to test.
The name has to match
A certificate whose common name does not match the address you registered will not work either. That mismatch is easy to create without noticing, particularly behind proxies and load balancers where the certificate presented to the outside world is not the one you think you configured.
Managed hosting makes this more likely rather than less. A platform that terminates encryption for you presents its own certificate, and whether that certificate carries your name depends on configuration you may not have touched. The certificate you inspect from outside is the only one that counts, regardless of what is sitting on your server.
How to test it properly
Test from outside your own network with a plain client that does not use your browser's certificate store, because browsers are far more forgiving than the platform is. A certificate that a browser accepts silently can still be rejected on delivery, and the difference is exactly the class of problem you are looking for.
The Secret Token, and Why Your Endpoint Needs One
Your webhook address is a public URL. Anybody who learns it can send it anything. There is a published defence and it takes one parameter.
What it is
You can register a secret token of one to two hundred and fifty-six characters, using letters, digits, underscores and hyphens. Once set, every request the platform sends to your endpoint carries that value in a dedicated header named for the platform's secret token.
What your endpoint does with it
Compare the header against your stored value and reject anything that does not match, before parsing the body. This turns your endpoint from a public letterbox into one that only accepts mail from a sender who knows a password. It costs a single comparison per request.
Why the alternative is worse
Without it, your only defence is obscurity of the address plus filtering by network origin. The platform publishes its address ranges, so origin filtering is possible, but it breaks the moment those ranges change and it is awkward behind most proxies. The token check works everywhere and depends on nothing external.
Treat it like the token it is
It belongs with your credentials, not in your source. Anybody holding it can forge updates into your bot, which means they can make your bot believe any user said anything. The credential that lets you set it in the first place carries even more weight, and our article on the Telegram bot token covers how to look after and replace that one.
Rotating the secret is deliberately easy, since it is just another registration with a new value. Doing it when somebody leaves the team, or after a credential has been in a place you would rather it had not been, is a cheap habit. The only thing to remember is to update your endpoint and the registration close together, because the gap between them is a window where every delivery is rejected.
Choosing Which Updates You Receive
By default your endpoint gets almost everything, and almost everything is usually more than you want.
The allow list
You can pass a list of update types you care about, and the platform will deliver only those. A bot that answers messages does not need every edit, every reaction and every membership change, and filtering at the source is cheaper than filtering in your handler after the request has already been made.
Why filtering matters more than it looks
Every delivery is a request your server has to accept, parse and answer. In a busy group, reaction and edit traffic can dwarf actual messages. Narrowing the list is the single cheapest performance change available on a webhook, and it also shrinks your logs to the things you actually read.
There is a privacy argument too, and it is stronger than the performance one. Updates you never asked for still arrive at your server, still land in your logs and still sit in whatever backup those logs end up in. Not receiving something is a better guarantee than promising to delete it, and it is one parameter away.
It is not permanent
The list is part of the webhook registration rather than a property of the bot, so changing it means registering again. That is a normal operation and not a migration, but it does mean the setting lives with your deployment configuration rather than in your code, which is worth writing down somewhere your future self will look.
Start narrow
Registering for exactly what your handlers implement, and widening later, produces a quieter system and makes an unexpected update type visible as a gap rather than as noise. The reverse order means you are permanently discarding traffic you asked for.
The Three Types You Do Not Get by Default
There is a specific and easily missed exception in the default behaviour.
What is excluded
If you do not specify a list, you receive all update types except three: chat member updates, and the two reaction update types. Those are opt-in, which means a bot that needs them and never asked will simply never see them.
Why this bites
Membership tracking is the classic case. Somebody builds a bot to watch who joins and leaves a group, tests it, and sees nothing at all, because the update carrying that information is one of the three excluded by default. Nothing in the code is wrong and no error is produced anywhere.
Anything that tracks membership runs into this, and membership is a common thing to want. Welcome messages, subscriber counts, gate checks and removal notices all depend on that one excluded type. Our guide on Telegram add member limits covers the other half of that subject, which is what happens when a bot or an account tries to change membership rather than watch it.
The fix, and its side effect
Ask for them explicitly in the allow list. Note that once you pass a list, it replaces the default rather than extending it, so a list containing only the membership type gets you membership updates and nothing else. Both halves of that sentence catch people.
A safe pattern is to keep the full list in one place in your deployment configuration and never hand-write a partial one. When somebody needs an extra type they add it to the list rather than passing a fresh one, which makes it impossible to silently drop the types the bot already depended on.
Connections and Throughput
One parameter controls how hard the platform will push, and its default is deliberately modest.
The default and the range
The maximum number of simultaneous connections used for delivery defaults to forty and can be set anywhere from one to one hundred. Lowering it reduces load on your server; raising it increases throughput if your endpoint can genuinely handle the concurrency.
When to lower it
If your handler talks to a database with a small connection pool, forty concurrent deliveries can exhaust the pool and turn a working bot into a queue of timeouts. Setting this to match what your infrastructure can actually serve is more effective than adding retry logic downstream.
Watch for the shape of the failure rather than the count. Pool exhaustion looks like every request suddenly becoming slow at the same moment, then recovering together, which is quite different from a steady increase in latency. If your graphs show that pattern, the ceiling is the first knob to turn and it takes effect immediately.
When raising it does nothing
Concurrency only helps if your handler returns quickly. If each delivery takes two seconds because you are calling an external service inline, more connections just means more simultaneous slow requests. The fix there is to answer immediately and do the work afterwards, which is the next section.
What Your Endpoint Must Return
The response contract is simple and the most common mistake is doing too much before you answer.
Answer fast, work later
Accept the update, put it somewhere durable, and return a success response immediately. Every second your handler spends calling an external service or writing a report is a second the platform is holding a connection open waiting for you. The correct shape is acknowledge first, process second.
Durable is doing real work in that sentence. Putting the update in an in-memory list and answering immediately is fast and loses everything on restart, which converts a delivery guarantee you were given into one you threw away. A queue, a table or even a file is enough; what matters is that the acknowledgement is a promise you can keep.
Errors are not free
If your endpoint returns an error, the delivery has not succeeded, and the update is still owed to you. That is the mechanism behind a bot that recovers after an outage, and it is also the mechanism behind a bot that drowns itself: an endpoint that fails on a poisonous update will keep being offered that update.
The blast radius is worth understanding. A bot stuck on one bad update is not merely failing that update; it is spending its delivery capacity on a request that will never succeed, while everything behind it waits. That is how a single malformed message turns into a bot that appears to be entirely offline.
The poison message problem
If one specific update crashes your handler every time, retrying forever is the natural consequence of failing forever. The defence is to catch broadly, acknowledge the delivery, and record the failure on your side rather than pushing it back. An update you cannot process is a bug to investigate, not a delivery to refuse.
Record enough to reproduce it. The raw body, the update identifier and the exception are usually sufficient, and storing them costs almost nothing compared with the alternative, which is discovering that your bot broke on a message you no longer have. This is the same discipline our piece on the Telegram auto reply bot applies to conversational state.
Idempotency is your job
Because a delivery can be retried, your handler can see the same update twice. Anything with a side effect, meaning a message sent, an order created or a balance changed, needs to tolerate that. The update identifier gives you a natural key for it, and using it is cheaper than reasoning about whether a duplicate is possible.
Duplicates are not only caused by retries. A deployment that runs two instances behind a load balancer can deliver the same update to both if your acknowledgement and your processing are not tied together properly. Keying on the update identifier protects you from both causes with the same few lines.
Answering the Webhook With a Method Call
There is a genuinely useful trick here that most tutorials skip entirely.
The mechanism
Instead of returning an empty success response and then making a separate call to send your reply, you can put an API method call into the body of your response. The method name goes in a field named for it, and the body is sent as ordinary form data or as structured data. The platform executes it as though you had called it.
Why it is fast
It removes a whole round trip. Your server receives the update and answers it with the reply in one exchange, rather than answering with nothing and then opening a new connection back to the platform. On a busy bot that halves the number of connections involved in a simple reply.
The saving compounds where it matters most. A bot answering a burst of messages in a group is doing the same small exchange dozens of times a minute, and each one avoided is a connection your server never opens and never waits on. For the simplest and most common case, which is replying with text, this is close to free performance.
The limitation that decides when to use it
You cannot know whether that request succeeded, and you cannot get its result. It is fire and forget by construction. That makes it ideal for a simple acknowledgement and wrong for anything whose outcome you need, such as a message whose identifier you intend to edit later.
A sensible rule
Use it for the reply that does not matter if it is lost, and use an ordinary call for anything you need to confirm. Mixing both in one bot is normal rather than inconsistent, and the choice per message is about whether you need the answer.
One more caveat is worth stating. Because the call travels inside your response, anything you send this way has to be ready at the moment you answer. If your reply depends on a slow lookup, using this technique forces you to do that lookup before acknowledging, which trades away the more important optimisation for the smaller one.
Reading the Diagnostic the Platform Gives You
There is a method that reports the current state of your webhook, and it answers most questions faster than any log.
What it tells you
The registered address, whether a custom certificate is in use, how many updates are waiting, the address being used for delivery, the maximum connections, the allowed update types, and the time and text of the most recent error. That last pair is the important one.
How to read the error fields
A recent error timestamp with a message is the platform telling you exactly why deliveries are failing, in its own words, without you needing to reproduce anything. Certificate problems, connection refusals and timeouts all show up here in plain text, which makes this the first thing to check rather than the last.
Treat the message as authoritative rather than as a hint. It is generated by the side that actually attempted the connection, which is the side you cannot observe. When it disagrees with what your server logs say, the platform is describing what happened on the wire and your logs are describing a request that may never have arrived.
The pending count is a health signal
A pending count that climbs is a bot that is not consuming its own queue. A pending count that is large and static usually means deliveries are failing entirely. Either way it is a number you can watch, and watching it is a cheaper monitor than parsing your own logs for absence.
Absence is the hardest thing to alert on, which is why this number is so useful. A bot that has stopped receiving looks identical to a quiet bot from the inside, and no amount of log analysis distinguishes them. A pending count that keeps rising while your handler sits idle is unambiguous, and it needs no instrumentation of your own.
Check it before you change anything
Most webhook debugging sessions start by re-registering the webhook, which discards the evidence. Reading the state first costs one call and frequently ends the investigation immediately, because the error message names the cause.
If you do decide to re-register, note the current state first. Copy the allowed types, the connection ceiling and whether a custom certificate is in play, because re-registering without them silently resets each one to its default. That is how a bot loses its membership updates during an unrelated fix.
Pending Updates, and When to Drop Them
Undelivered updates do not vanish, which is usually good and occasionally a problem.
The queue survives you
If your endpoint has been down, the updates that arrived meanwhile are still waiting. When you come back, they arrive. For a support bot that is exactly right, because a message sent during an outage still deserves an answer.
When you do not want them
After a long outage, or when switching a bot to a new purpose, a backlog of stale updates can be worse than useless. Answering a two-day-old message as though it just arrived is confusing at best. There is a flag on both registering and removing a webhook that discards everything queued.
Use it deliberately
Dropping pending updates is not a cleanup step to run on every deployment. Doing it routinely means every deployment quietly throws away whatever arrived during the restart, which is a data loss habit that hides itself. Reserve it for the cases where the backlog is genuinely stale.
A useful test is to ask whether you would be comfortable answering the oldest message in the queue right now. If the answer is yes, keep it, because somebody is waiting. If it is clearly no, drop it deliberately and consider telling the affected people something, since silence after an outage reads as being ignored rather than as being unlucky.
The Limits That Apply After Delivery
Receiving updates is unlimited in practice. Replying to them is not, and the published numbers are worth memorising.
Per chat and per group
The guidance is to avoid sending more than one message per second to a single chat, and groups carry a stricter ceiling of twenty messages per minute. A bot that answers every message in a busy group will hit the group limit long before it hits anything else.
That ceiling is lower than people expect and it is per group rather than per bot, which means a bot in fifty groups has fifty separate budgets. Designing around it usually means answering selectively rather than answering faster: a bot that replies only when addressed is both better behaved and structurally incapable of hitting the limit.
The bulk figure
For broadcasting to many different users, the free allowance is around thirty messages per second. Beyond the limits you receive a specific error rather than silent dropping, which is at least honest, and it is the signal to slow down rather than retry harder.
Retrying immediately on that error is the most common mistake and it makes the situation worse, because the retry consumes the allowance you are already over. Backing off, ideally with the delay the response suggests, is the only response that shortens the outage rather than extending it.
The paid tier
There is a paid broadcast option raising throughput to as much as a thousand messages per second, charged per message above the free threshold in the platform's own currency. That is a real option for a genuine broadcast product and an expensive way to paper over a design that sends too much. Our article on the Telegram broadcast bot covers the sending side in detail.
Worth separating the two audiences here as well. Broadcasting to people who chose to hear from you is a delivery problem with published limits. Reaching people who have not chosen anything is a different problem entirely, running on accounts rather than bots, which is what our Telegram DM automation guide covers and why the two rarely share tooling.
Why this belongs in a webhook article
Because a webhook removes the natural throttle that polling gave you. When you were asking for updates, your own loop set the pace. Now the platform sets it, and a busy moment arrives as a burst. The limits above are the ones that turn that burst into errors if your handler answers every item immediately.
The practical shape is a queue with a pacer in front of your sending code, entirely separate from the endpoint that receives. Receiving as fast as the platform will push and sending at the rate the platform will accept are two different jobs, and a bot that tries to do them in one function will be limited by the slower one at exactly the wrong moment.
Migrating Between Polling and Webhooks
The switch is a single call in each direction, which makes it easy to do carelessly.
Going to a webhook
Register the address, then verify the state rather than assuming. A registration that returns success only means the platform accepted the address, not that it can reach it. The first delivery, or the first error message in the diagnostic, is the real confirmation.
Send yourself a message as the very first test. It exercises the whole path, from the platform to your certificate to your route to your handler, in a way that no amount of configuration review does. If that one message arrives, everything structural is working and any remaining problems are in your own code.
Going back to polling
There is a method to remove the webhook, which exists precisely so that you can return to pulling updates. Until you call it, your polling code will keep refusing to work, and the error will not tell you that a webhook somewhere else is the reason.
Keep the removal call somewhere you can run without thinking, because you will want it at an inconvenient moment. Returning to polling is the standard emergency move when a certificate expires or a host disappears, and being able to do it in seconds turns an outage into an inconvenience.
The staging trap
Two environments sharing one credential is the most common self-inflicted webhook problem. Staging sets a webhook, production sets a different one, and whichever ran last wins for both. Separate credentials per environment removes an entire category of confusing incidents, and it costs one extra registration.
If You Run Several Bots
One webhook is a configuration. Several is an operational surface.
Every bot is a separate registration
There is no shared webhook and no inheritance. Each bot has its own address, its own secret, its own allow list and its own diagnostic to read. That is fine at two and tedious at ten, which is the point where the state of each one stops being something anybody remembers. Keeping that consistent is what our Bot Manager product handles, alongside the command surface covered in our piece on Telegram bot commands.
Route by path, not by port
Since only four ports are available, several bots on one machine cannot each take their own port. The workable pattern is one encrypted endpoint with a distinct path per bot, which also lets you use a different secret per path and keeps the certificate question to a single answer.
Distinct paths also make your logs readable. When every bot posts to the same route, telling them apart means parsing the body, and when something goes wrong you are reading payloads to work out which bot is affected. A path per bot answers that from the access log alone, before anybody opens a debugger. Our guide on how to automate a Telegram channel covers the same separation habit on the posting side.
Inbound is only half the system
A webhook handles people who already wrote to you. Reaching people first, at volume, is a different machine with different limits, which is what our Mass DMs tooling and Account Manager exist for, and finding them in the first place is what ProspectPulse scans for. A bot with a perfect webhook and no inbound traffic is a well-built room nobody walks into.
If the interface you actually want is richer than a chat exchange, that is a different build again, and our article on the Telegram Mini App covers it. A webhook and an app solve different halves of the same problem: one carries what people say to you, the other carries what they do inside something you built. Most serious bots eventually run both, and the webhook is still the part that has to be reliable first.
What All of This Adds Up To
A webhook trades a polling loop for a public address. Everything difficult about it follows from that one trade: encrypted transport with no exceptions, four permitted ports, a certificate that survives real inspection rather than a browser's leniency, and no redirects.
The parameters are few and each one matters. A secret token turns a public letterbox into an authenticated one for the cost of a header comparison. An allow list keeps traffic you never wanted off your server, with the specific catch that three update types are excluded unless you ask, and that asking replaces the default rather than adding to it. A connection ceiling of forty by default should match what your infrastructure can genuinely serve.
After that it is discipline. Answer immediately and process afterwards, because a slow handler is a held connection. Tolerate duplicates, because a retried delivery is a normal event rather than a bug. Read the diagnostic before re-registering, because the platform usually tells you the cause in plain text. And remember that receiving is the easy half, since the limits that actually bite start applying the moment you reply.
Frequently Asked Questions
What is a Telegram webhook?
It is an address you register with the platform so that updates are delivered to you as they happen, instead of your code repeatedly asking whether anything arrived. Each delivery is an ordinary web request carrying the same update structure a polling bot would receive, so only the direction of the call changes.
Which ports can a Telegram webhook use?
Four, and only four: 443, 80, 88 and 8443. Anything else will not work. Encrypted transport is required on all of them, and there is no plain-text option at any port, so a webhook cannot be tested without a working certificate.
Can I use getUpdates and a webhook at the same time?
No. The documentation states that the polling method will not work while an outgoing webhook is set up. If a local script has started failing while your deployed bot works, that is almost always the cause. The clean solution is a separate bot with its own credential for development.
What is the secret token for?
Your webhook address is a public URL that anybody could send data to. Registering a secret token of one to two hundred and fifty-six characters makes the platform include that value in a dedicated header on every request, so your endpoint can reject anything that does not carry it before parsing the body.
Why is my webhook not receiving anything?
Check the diagnostic method first, since it reports the most recent error in plain text. The usual causes are a certificate problem, an unsupported port, a redirect instead of a final address, a wildcard certificate that may not be supported, or a certificate whose name does not match the registered address.
Does a self-signed certificate work?
Yes, provided you upload the public certificate in the standard text format when registering the webhook. That upload is what allows the platform to trust a certificate no public authority vouches for. Without it, a self-signed certificate is simply an untrusted one and deliveries fail.
Why am I not receiving member join and leave updates?
Because three update types are excluded from the default: chat member updates and the two reaction types. They have to be requested explicitly in the allow list. Note that passing a list replaces the default entirely, so a list with only the membership type gets you that and nothing else.
What should my endpoint return?
A success response, as quickly as possible, before doing any real work. Store the update and process it afterwards. Returning an error means the delivery did not succeed and the update is still owed to you, which is useful after an outage and harmful if one specific update crashes your handler every time.
What happens to updates while my server is down?
They wait, and arrive when you come back. That is usually what you want. If the backlog is stale enough to be misleading, there is a flag on both registering and removing a webhook that discards everything queued, but using it on every deployment quietly throws away real traffic.
How many connections will Telegram open to my server?
Up to forty by default, adjustable between one and one hundred. Lower it if your handler holds a scarce resource such as a small database pool, since exhausting that pool turns a working bot into a queue of timeouts. Raising it only helps if your handler returns quickly.
Can I reply to the webhook request itself?
Yes. You can put an API method call into the body of your response and the platform will execute it, which removes an entire round trip for a simple reply. The trade is that you cannot know whether it succeeded or retrieve its result, so it suits acknowledgements and not anything whose outcome you need afterwards.
Receiving Is the Easy Half
A webhook carries what people already sent you. Reaching them in the first place runs on different machinery with different limits, and that is what our tooling does. Open a demo and see it.
Try Free Demo