# Ticks and tick arrays

In a CLMM pool, the price curve is divided into discrete points called **ticks**. Each tick represents a 0.01% price increment. Liquidity providers don't place liquidity at arbitrary prices — they select tick boundaries as the upper and lower bounds of their position. When a swap crosses a tick boundary, the pool activates or deactivates the liquidity positions that start or end at that tick.

Not every tick is usable. **Tick spacing** controls which ticks are available for positions. A pool with tick spacing 10 only allows positions at every 10th tick. Smaller tick spacing gives LPs more granular control over their price range; larger tick spacing is coarser but cheaper to operate in. On Raydium, each fee tier maps to a specific tick spacing:

| Fee tier | Tick spacing | Typical use              |
| -------- | ------------ | ------------------------ |
| 1 bps    | 1            | Stable pairs (USDC-USDT) |
| 5 bps    | 10           | Major pairs (SOL-USDC)   |
| 30 bps   | 60           | Volatile pairs           |
| 100 bps  | 120          | High volatility          |

Tick data is stored on-chain in **tick arrays**. On Raydium, each tick array holds 60 slots and covers a price range of `60 × tick_spacing` ticks. A pool with tick spacing 10 has tick arrays spanning 600 ticks each. Tick arrays cost **0.072 SOL** to initialize and are permanent, shared infrastructure — once created, every LP in the pool benefits from them. You only pay for a tick array if your position is the first to use that price range.

#### Example

You open a position on a SOL-USDC pool (tick spacing 10). Your chosen price range spans roughly 1,500 ticks, which requires 3 tick arrays. Two of them already exist from other LPs. You pay to initialize 1 new array: **0.072 SOL**. If you had picked a range where all arrays already existed, the tick array cost would be zero.

For full position cost breakdowns, see [CLMM fees](/raydium/for-liquidity-providers/pool-fees.md). For how tick spacing relates to trading fees, see [How fees work](/raydium/concepts/how-fees-work.md).

***

### Developer reference

#### Tick arrays in swaps

The swap instruction accepts tick arrays as **remaining accounts**. There is no fixed count — you can pass as many as the transaction size allows. The program iterates through them in order, popping from the front of the queue as the swap crosses array boundaries.

The program uses the **tick array bitmap** (stored in `PoolState`) and optionally the **tick array bitmap extension** account to determine which tick arrays are initialized in the swap direction. If the swap needs an initialized tick array that was not included in the remaining accounts, it fails with `NotEnoughTickArrayAccount` (error 6027).

Key rules:

* All tick arrays passed must be **initialized** — the program will attempt to deserialize them and fail if they are not valid `TickArrayState` accounts
* If you are unsure which arrays are needed, the Raydium team recommends passing the **current tick array plus the next two in the swap direction**. To handle price fluctuations between transaction submission and execution, also include the tick array in the **opposite** direction as a buffer
* You can pass a tick array that the swap doesn't end up needing — unused arrays are harmlessly skipped
* Duplicating a tick array in the remaining accounts will not cause an error, but it wastes transaction space

#### Tick array bitmap

The pool tracks which tick arrays have been initialized using a 1024-bit bitmap stored in `PoolState.tick_array_bitmap` (represented as `[u64; 8]` covering 512 positions in each direction from center). The bitmap is centered at tick index 0, with bit 512 representing start index 0. For pools that need more range, the `TickArrayBitmapExtension` account adds 7168 additional bits.

To check if a tick array is initialized at a given `start_tick_index`:

```
multiplier = tick_spacing * 60
compressed = start_tick_index / multiplier + 512
bit_position = abs(compressed)
```

If the bit at that position is set to 1, the tick array exists on-chain. The bitmap is used during swaps to skip over uninitialized regions efficiently — the program finds the next set bit in the swap direction rather than iterating through every possible tick array.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.raydium.io/raydium/concepts/ticks-and-tick-arrays.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
