Hardware FixRecommendedDevice not working? Your driver may be the problemCheck updates for common hardware issues.Fix DriversOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsSlow PC?RecommendedPC slow today? Run a repair scan before it gets worseResolve common Windows issues and optimize system performance.Scan Now×
Skip to content
World desk7 min

Secure and Queue Telegram Webhooks in Laravel with Redis Idempotency

A practical Laravel pattern for authenticating Telegram webhook requests, deduplicating update IDs with shared Redis, and queueing work with recovery and retry safeguards.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For a Laravel Telegram bot, verify Telegram’s webhook secret before accepting a request, atomically claim its update_id in Redis, then queue the work. This stops simultaneous duplicate deliveries from both being enqueued in the ordinary path, but it does not guarantee exactly-once processing: queue dispatch can fail after the claim, and a worker can repeat side effects after a retry. Design recovery and business operations for those failure cases.

Choose webhooks or polling—not both

A webhook is Telegram’s push mode: Telegram sends each update to your public endpoint. With getUpdates, your application polls Telegram instead. The Bot API makes the two modes mutually exclusive for a bot, so stop polling before enabling its webhook, or remove the webhook before returning to polling. Telegram’s Bot API also says updates are retained on Telegram’s servers for no longer than 24 hours.

As an Amazon Associate I earn from qualifying purchases.

Receive mode How updates arrive What your application must operate
Webhook Telegram pushes updates to your endpoint. A publicly reachable HTTPS endpoint and its request handling.
getUpdates Your application polls Telegram for updates. A polling process that requests updates.

Webhook delivery is not a promise that each update reaches your application only once. Treat repeated delivery as normal, and use the update’s update_id to recognize repeats. Telegram also notes that update identifiers are generally useful for restoring sequence when updates arrive out of order; after a week without new updates, the next identifier may be chosen randomly rather than sequentially. Do not use the identifier as a permanent clock or assume it always increases by one. See the Update object documentation.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Configure a reachable endpoint and secret

Telegram requires a publicly reachable endpoint using TLS and supports webhook ports 443, 80, 88, and 8443, according to its webhook guide. Configure the final URL directly: Telegram’s FAQ says redirects are unsupported. Confirm the live requirements when deploying, since network rules and API details can change.

When calling setWebhook, provide that HTTPS URL and a high-entropy secret_token. Telegram sends the configured value in the X-Telegram-Bot-Api-Secret-Token request header. Keep both this secret and the bot token in protected application configuration rather than source control, logs, or client-visible errors. Telegram cautions that a bot token is a unique identifier and should be stored securely and shared only with people who need direct access; see its developer introduction.

A hard-to-guess URL path can add a useful origin-checking obstacle, as the FAQ suggests, but it is not a replacement for checking the secret-token header. URLs may also appear in access logs and monitoring systems, so handle a secret path accordingly.

Validate before accepting or dispatching

Use a dedicated POST route and reject a missing or incorrect secret before parsing the update or scheduling work. Compare secrets with a timing-safe comparison. The following controller outline assumes services.telegram.webhook_secret is populated from a secret-managed environment setting, and that services.telegram.idempotency_ttl_seconds is set to a retention period chosen for your workload:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
use IlluminateHttpRequest;
use IlluminateSupportFacadesCache;

public function __invoke(Request $request)
{
    $expected = (string) config('services.telegram.webhook_secret');
    $provided = $request->header('X-Telegram-Bot-Api-Secret-Token');

    if ($expected === '' || ! is_string($provided) || ! hash_equals($expected, $provided)) {
        abort(403);
    }

    $update = $request->json()->all();
    $updateId = $update['update_id'] ?? null;

    if (! is_array($update) || ! is_int($updateId)) {
        abort(400);
    }

    $key = 'telegram:update:' . $updateId;
    $ttl = (int) config('services.telegram.idempotency_ttl_seconds');

    $claimed = Cache::store('redis')->add(
        $key,
        'claimed',
        now()->addSeconds($ttl)
    );

    if (! $claimed) {
        return response()->noContent();
    }

    ProcessTelegramUpdate::dispatch($update);

    return response()->noContent();
}

This is a focused example, not a complete validation policy. Apply a request-body size limit at the web server or application boundary, validate the update fields your bot actually supports, and avoid logging the secret or sensitive payload data. A shared Redis-backed cache is essential: all web processes must use the same store, and any workers that rely on its locks must see that same central cache.

Cache::add provides the atomic “only if absent” claim: for concurrent requests with the same namespaced update ID, only one should claim the key. If the key already exists, the handler returns success without dispatching the duplicate. The TTL is not a universal constant. Set it to cover your realistic Telegram replay window and the time needed for your own queue recovery, balancing duplicate protection against storage retention.

Account for the claim-to-dispatch failure window

The example claims Redis before dispatch, as required to stop two concurrent requests from both enqueueing the same update. That ordering has a failure window: if the process crashes or queue dispatch fails after the claim is written, a later delivery sees the key and may be acknowledged without work ever entering the queue. Returning an error in that case may prompt another delivery, but the existing claim still blocks it until expiry.

If losing an update in that window is unacceptable, do not treat a bare Redis key plus a queue call as a durable handoff. Use a recoverable state machine or an outbox-style design that records accepted work durably and lets a publisher retry dispatch; coordinate that design with the Redis idempotency claim. Track states such as claimed, queued, and completed only if you also define how stale states are detected and recovered. This is an engineering safeguard, not a guarantee supplied by Telegram or Laravel.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Queue small, validated work

After validation and a successful claim, dispatch a small job containing the validated update or a durable reference to it. Return a successful HTTP response once the update is safely accepted for processing; do not perform slow business operations in the webhook request. Queueing keeps request handling short and gives the application a place to retry processing, but the queue handoff itself must fit the recovery design above.

Make important business effects independently idempotent where possible. For example, when an update triggers a database change, record the update identity alongside that change under a unique constraint or in the same transaction. For an external API call, use that service’s idempotency mechanism if it provides one, or maintain your own durable operation state. A Redis admission key only controls whether another request is admitted while that key exists; it cannot undo or deduplicate an effect already repeated by a worker.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Use Laravel uniqueness and overlap locks for their specific jobs

Laravel 12’s queue documentation describes two distinct coordination mechanisms. ShouldBeUnique uses a lock based on the job’s uniqueId to prevent duplicate dispatch while the lock is held. WithoutOverlapping uses an atomic cache lock to limit concurrent processing. They solve different scheduling problems, and neither makes external side effects exactly once.

  • Use ShouldBeUnique when suppressing duplicate queue dispatch for a job key is useful. Laravel documents uniqueFor to bound the lock duration and uniqueVia to choose a cache repository. The uniqueness lock is held through completion or exhaustion of retries; ShouldBeUniqueUntilProcessing releases it just before processing. Unique-job constraints do not apply to jobs inside batches.
  • Use WithoutOverlapping when two jobs must not process the same resource concurrently, including jobs with different update IDs that affect one account or other shared entity. Configure lock expiry so an abnormal worker termination does not leave work excluded indefinitely.

For a unique job keyed by the Telegram update, implement uniqueId() using that update ID and select a uniqueness duration that fits the retry and recovery policy. The application-level Redis claim still matters: it filters duplicate HTTP deliveries before dispatch, whereas Laravel uniqueness coordinates queue admission. A shared central cache is required for correct coordination across servers or containers; see Laravel 12 queue documentation.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Coordinate retries, timeouts, and recovery

Set the worker timeout, Redis queue connection’s retry_after, job attempt limit, backoff, and any overlap or uniqueness lock expiry as one policy. A worker timeout and queue reservation interval that do not align can leave a job eligible for retry while a prior worker may still be running. Lock durations that are too short can permit concurrent work; durations that are too long can delay recovery after a crash.

Laravel attempts can be consumed by more than uncaught exceptions: manual releases, middleware releases, timeouts, and normal completion affect attempt accounting. Choose retries and backoff for the operation’s expected failure modes, and make retrying safe at the business-effect layer. Monitor failed jobs and provide an operational way to inspect, retry, or otherwise resolve them. Laravel’s 12.x documentation covers Redis queue configuration, retries, timeouts, and failed-job recovery; use the documentation version matching the Laravel release actually installed.

Quick Recap

Bestseller No. 1

Trace the complete request path

  1. Telegram sends an update by HTTPS POST to the configured public webhook URL.
  2. Laravel checks the X-Telegram-Bot-Api-Secret-Token header and rejects a missing or incorrect value before accepting the body.
  3. The endpoint validates payload size and shape, extracts the integer update_id, and atomically claims a namespaced key in shared Redis with a workload-appropriate expiry.
  4. If the key already exists, the endpoint acknowledges the repeat without enqueuing it again. If the claim succeeds, it hands validated work to the queue using a recovery design appropriate to the cost of losing the claim-to-dispatch handoff.
  5. A worker processes the job with retry and lock settings that match the queue connection, while business effects remain safe if processing is attempted again.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.