Skip to content

Telegram plugin: duplicate pollers cause background CPU churn even when idle #1344

@cola-runner

Description

@cola-runner

Summary

The Telegram plugin can create noticeable background CPU churn even when it looks "idle", and the main cause appears to be duplicate pollers competing for the same bot token rather than a single healthy poller spinning in a tight loop.

What I observed

On one machine, I found two long-lived Bun processes for the Telegram plugin at the same time:

  • cache copy:
    ~/.claude/plugins/cache/claude-plugins-official/telegram/0.0.4
  • marketplace copy:
    ~/.claude/plugins/marketplaces/claude-plugins-official/external_plugins/telegram

Both were launched from .mcp.json entries that run:

{
  "command": "bun",
  "args": ["run", "--cwd", "${CLAUDE_PLUGIN_ROOT}", "--shell=bun", "--silent", "start"]
}

and start resolves to:

"start": "bun install --no-summary && bun server.ts"

I was also able to confirm that the plugin starts polling immediately after MCP connection setup, with no singleton / lock around Telegram getUpdates.

Why this causes the CPU symptom

Telegram only allows one getUpdates consumer per bot token.

When duplicate plugin instances are alive at the same time, they can:

  • compete for inbound updates
  • trigger 409 Conflict
  • keep retrying / waking up in the background
  • accumulate across sessions if an old process is not cleaned up properly

That makes the plugin feel like it is "burning CPU even when unused", because more than one Bun runtime is hanging around and contending for the same bot.

Important detail from local sampling

I sampled an idle Bun Telegram process on macOS and it was mostly blocked in kernel waits (kevent64 / __ulock_wait2). That suggests the steady-state idle path of a single healthy poller is not the only problem.

The more likely root cause of the user-visible CPU issue is:

  1. duplicate pollers are allowed to start
  2. stale/orphaned pollers are easy to accumulate
  3. polling starts eagerly instead of only for the active poller
  4. the approval flow also adds a fixed background interval

So the CPU complaint is real, but the main issue seems to be duplicate-instance contention and background churn, not necessarily one isolated JS tight loop.

Suggested fix

A practical fix would be:

  • add a polling lock per TELEGRAM_STATE_DIR
  • allow only one process to own Telegram polling
  • downgrade duplicate instances to tools-only mode instead of starting another poller
  • reclaim stale locks from dead PIDs
  • replace the fixed approval-directory polling interval with fs.watch plus interval fallback
  • separately fix plugin discovery so marketplace and cache copies are not both loaded for the same plugin

Related issues

Environment

  • macOS
  • Bun 1.3.11
  • telegram plugin v0.0.4
  • observed on 2026-04-10

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions