# Which Pacer Utility Should I Choose?

TanStack Pacer provides five strategies for controlling when operations run. The right choice depends on what should happen to calls that arrive faster than your application can process them.

## Compare the utilities

| Utility | What happens to frequent calls? | Best fit |
| --- | --- | --- |
| [Debouncer](../framework/angular/guides/debouncing.md) | Earlier calls are discarded. The latest call runs after activity stops. | Search input, validation, autosave |
| [Throttler](../framework/angular/guides/throttling.md) | Calls are limited to a steady interval. A trailing call can retain the latest arguments. | Scroll, resize, progress, repeated UI updates |
| [Rate Limiter](../framework/angular/guides/rate-limiting.md) | Calls run until a quota is reached. Additional calls are rejected until capacity returns. | Client-side quotas and burst limits |
| [Queuer](../framework/angular/guides/queuing.md) | Calls wait in an ordered buffer and run individually. | Work that must not be lost |
| [Batcher](../framework/angular/guides/batching.md) | Items accumulate and run together as one batch. | Bulk requests, writes, and analytics events |

## Choose by required behavior

### Only the final value matters

Use a debouncer. Every call restarts a timer, and the most recent call runs once the calls go quiet.

### Work should continue at a steady pace

Use a throttler. It limits execution frequency without waiting for activity to stop completely.

### A fixed quota must be enforced

Use a rate limiter. It accepts calls until the configured limit is reached, then rejects additional calls within the window.

### Every operation must run

Use a queuer. It preserves pending operations and processes them according to FIFO, LIFO, or priority ordering. A finite `maxSize` can still cause new items to be rejected.

### Several items should run together

Use a batcher. It collects items until a size, time, or custom condition triggers one batch execution.

## Synchronous or asynchronous

Each utility has a synchronous and asynchronous version. Start with the synchronous version unless the utility must manage Promise-specific behavior.

Use the asynchronous version when you need to:

- Await the wrapped function's result.
- Track success, error, and settlement state.
- Configure error propagation.
- Retry failed executions.
- Abort in-flight operations.
- Run queued tasks concurrently with `AsyncQueuer`.

Passing an async function to a synchronous utility does not provide these features. The synchronous utility invokes the function but does not await or manage its Promise.

| Synchronous | Asynchronous |
| --- | --- |
| [Debouncing](../framework/angular/guides/debouncing.md) | [Async debouncing](../framework/angular/guides/async-debouncing.md) |
| [Throttling](../framework/angular/guides/throttling.md) | [Async throttling](../framework/angular/guides/async-throttling.md) |
| [Rate limiting](../framework/angular/guides/rate-limiting.md) | [Async rate limiting](../framework/angular/guides/async-rate-limiting.md) |
| [Queuing](../framework/angular/guides/queuing.md) | [Async queuing](../framework/angular/guides/async-queuing.md) |
| [Batching](../framework/angular/guides/batching.md) | [Async batching](../framework/angular/guides/async-batching.md) |

The async utilities use `AsyncRetryer` internally for retry and abort support. See the [Async Retrying Guide](../framework/angular/guides/async-retrying.md).

## Core package or framework adapter

Use `@tanstack/pacer` when you need the core classes and functions without component lifecycle integration. The [Vanilla quick start](../framework/vanilla/quick-start.md) covers it.

Use a framework adapter in an application that needs automatic cleanup and reactive state. Each adapter has a quick start:

- [React](../framework/react/quick-start.md)
- [Preact](../framework/preact/quick-start.md)
- [Solid](../framework/solid/quick-start.md)
- [Angular](../framework/angular/quick-start.md)
- [Vue](../framework/vue/quick-start.md)
- [Svelte](../framework/svelte/quick-start.md)
- [Lit](../framework/lit/quick-start.md)
- [Alpine](../framework/alpine/quick-start.md)
- [Ember](../framework/ember/quick-start.md)
- [Octane](../framework/octane/quick-start.md)

Framework adapters provide several API shapes around the same underlying utility:

- Instance APIs such as `useDebouncer` expose lifecycle methods and selected state.
- Callback APIs such as `useDebouncedCallback` return a function to call.
- State and value APIs connect the utility to framework state.

Choose the narrowest API that provides the control you need. Use the instance API when you need methods such as `cancel()` or `flush()`.

## Pacer Lite or Pacer

`@tanstack/pacer-lite` is intended for libraries that need smaller, non-reactive utilities. It omits TanStack Store integration, framework adapters, Devtools support, and some advanced options.

Use the regular core package or a framework adapter for application code. Consider Pacer Lite when bundle size is the primary constraint and reactive state is unnecessary.
