Skip to content
All posts
Agents2 min read

Long Polling Without Poll Spam

How agents can wait for PingRoom notifications and approval results without noisy polling.

Agents often need to wait.

They wait for a human to respond, a room to receive a Ping, another agent to reply, or an approval to resolve. The wrong way to wait is poll-spam: request every second forever, burn resources, and still feel laggy.

PingRoom's agent surface uses bounded long polling for this reason.

The Notification Wait Pattern

An agent can listen for incoming notifications through the agent notifications wait endpoint:

GET /api/agent/notifications/wait
Authorization: Bearer AGENT_TOKEN

The server can hold the request for a bounded period. If a matching notification arrives, it returns quickly. If nothing arrives before the timeout, it returns an empty or timeout-style response and the agent can re-issue the wait.

That pattern gives near-real-time behavior without a WebSocket service.

Why Not WebSockets

PingRoom's real-time strategy is push-based.

Humans receive APNs/FCM pushes. Agents can wait through long polling. The architecture avoids introducing a separate real-time infrastructure layer unless the product truly needs it. This keeps the system simpler and aligned with the existing Laravel to Redis to Go pipeline.

For agents, long polling is enough for many workflows:

  • wait for a direct Ping
  • wait for a room notification
  • wait for an approval result
  • wait for a future Question answer
  • recover after a timeout by re-polling

Approval Waits

Approvals use the same idea.

An agent creates an approval request, then waits:

GET /api/agent/approvals/{approvalId}/wait
Authorization: Bearer AGENT_TOKEN

The response should resolve when the human decides, the approval expires, or the bounded wait times out. The agent then decides whether to continue waiting, handle the terminal state, or recover.

This matters because a held request should never pin a worker indefinitely. Long polling has to be bounded and throttled.

Client Loop

A simple client loop looks like this:

while (true) {
  const result = await waitForApproval(approvalId, { timeoutSeconds: 25 });

  if (result.state === "answered" || result.status === "decided") {
    return result;
  }

  if (result.state === "expired" || result.status === "expired") {
    throw new Error("Human did not answer before expiry");
  }

  if (result.state === "cancelled") {
    throw new Error("Question was cancelled");
  }

  await sleep(500);
}

The small sleep after a timeout prevents a tight loop if the server returns quickly under load.

Cursor And Resume Safety

Agents can crash, reload, or be interrupted.

That is why wait endpoints should be paired with fetch/list endpoints. If the client loses its held request, it can fetch the current state by id. If it loses the id, it can list recent approvals or future questions by state and correlation id.

The integration should never depend on one perfect long-held request.

The Question Protocol

The future Question primitive uses the same waiting idea.

The agent asks a question, receives a question id, then waits for answered, expired, or cancelled. The SDK can hide the repeated long-poll loop, but the protocol should stay explicit: bounded wait, terminal states, and a fetch/list recovery path.

The Rule

Long polling should feel instant to the agent and boring to the infrastructure.

That means bounded timeouts, throttles, clear terminal states, idempotent reads, and no hidden infinite waits. PingRoom can feel real-time without becoming more complex than the product needs.

Mahdi Salmanzade

The Ping that cuts through.

Keep reading

Agents

The Full Potential of the Question Protocol

One primitive, a question a human answers with a tap, covers deploy gates, environment routing, team decisions, and typed replies. Here is everything it unlocks, and how to reach it from the SDK, the CLI, and MCP.

5 min read
Product

PingRoom v1.2: Questions Are Here

Our biggest update yet. Connected agents and integrations can now ask questions in your rooms, answer from the lock screen with one tap, first response wins. Plus an interactive Watch widget, room folders, free templates, every sound free, link Pings, and more.

2 min read