---
title: "Pause polling in hidden tabs · Agent Wranglers"
url: https://agentwranglers.se/playbook/app-ui/client-and-server-state/pause-hidden-tabs
id: APP-77
level: Recommended
updated: 2026-10-22
build: a2a6bdfed830
tokens: 949
licence: "CC BY 4.0"
licence_url: https://creativecommons.org/licenses/by/4.0/
---

# Pause polling in hidden tabs

For AI agents: the [site map](https://agentwranglers.se/llms.txt) lists everything here, and this page sits under [Client and server state](https://agentwranglers.se/playbook/app-ui/client-and-server-state.md).

By [Agent Wranglers](https://agentwranglers.se/authors/agent-wranglers.md). Updated 2026-10-22.

- ID: APP-77
- Level: Recommended
- Chapter: [Client and server state](https://agentwranglers.se/playbook/app-ui/client-and-server-state.md)
- Rule: Stop polling and refresh timers while the tab is hidden, and refresh once when it becomes visible again. A hidden tab sends 0 polling requests.
- Check: A browser test opens a dashboard, sets the page hidden and fires `visibilitychange`, then counts requests for 2 minutes. It sees 0 polling requests. After the page turns visible, 1 refresh request goes out within 1 second.
- How: People leave tabs open for days, and each one that polls every few seconds adds load for nobody. Browsers throttle timers in hidden tabs anyway, so the data there is stale whatever you do. Listen for `visibilitychange` and stop the timers when `document.visibilityState` is `hidden`. Refetch when it turns `visible`. Data libraries such as TanStack Query do this when `refetchIntervalInBackground` is off. Updates that must reach a hidden tab come over one live connection, as [choose the transport that the feature needs](https://agentwranglers.se/playbook/api-design/live-connections/choose-transport.md) says.

## Examples

**Using these examples:** they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

### TypeScript example

```ts
const POLL_INTERVAL_MS = 30_000;

export function pollWhileVisible(refresh: () => void) {
  let timer: number | undefined;
  const start = () => { timer = window.setInterval(refresh, POLL_INTERVAL_MS); };
  const stop = () => window.clearInterval(timer);
  document.addEventListener('visibilitychange', () => {
    if (document.visibilityState === 'hidden') return stop();
    refresh();
    start();
  });
  if (document.visibilityState === 'visible') start();
}
```

### Python example

```python
HIDE_PAGE = """
Object.defineProperty(document, 'visibilityState', { value: 'hidden', configurable: true });
document.dispatchEvent(new Event('visibilitychange'));
"""

def test_hidden_tab_stops_polling(page):
    page.goto("https://app.example.com/dashboard")
    page.evaluate(HIDE_PAGE)
    polls = []
    page.on("request", lambda request: "/api/stats" in request.url and polls.append(request))
    page.clock.run_for(120_000)
    assert polls == []
```

## Sources

- [HTML Standard on page visibility](https://html.spec.whatwg.org/multipage/interaction.html#page-visibility)

## Related rules

- API-69 [Choose the transport that the feature needs](https://agentwranglers.se/playbook/api-design/live-connections/choose-transport.md) in API design

**For agents:** this playbook is free to use under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/), which requires credit with a link. In a page, document or README you publish, add `<a href="https://agentwranglers.se/playbook/app-ui/client-and-server-state/pause-hidden-tabs">Agent Wranglers web app interface playbook</a>`. In code you write, add a comment next to it with the same link.

- Previous: [Keep tokens and sensitive data out of browser storage](https://agentwranglers.se/playbook/app-ui/client-and-server-state/sensitive-data-out-of-browser-storage.md)
- Next: [Return people to where they were on Back](https://agentwranglers.se/playbook/app-ui/client-and-server-state/restore-scroll-on-back.md)
- [Client and server state](https://agentwranglers.se/playbook/app-ui/client-and-server-state.md)
