If you’ve ever opened a Uniswap V3 or V4 position and seen a chart full of little vertical bars, price ranges, and a mysterious number called a “tick,” you’ve probably felt a small wave of panic. Don’t worry, ticks are one of those ideas that sound intimidating but turn out to be pretty simple once you see the problem they were built to solve.
In Uniswap V2, liquidity is a constant. Every pool holds a fixed reserve curve (x * y = k), and that liquidity is spread evenly across every possible price, from zero to infinity. That sounds generous, but it’s wasteful. If ETH is trading around $3,000, there’s basically no chance it trades at $0.01 or at $10 million anytime soon, yet V2 forces your capital to sit idle across that entire range, earning fees only from the tiny sliver of trades that happen near the current price.
Uniswap V3 changed the fundamental model: instead of liquidity being a single constant number across the entire price curve, liquidity providers can choose which segment of the price curve they want their capital to sit in. You might deposit only between $2,800 and $3,200, someone else might deposit between $2,000 and $5,000, and someone else might go extremely narrow, $2,990–$3,010.
The consequence is that liquidity is no longer a single constant L; it becomes a function of price, L(P), that steps up and down depending on how many LPs have active positions covering that particular price. This is what “concentrated liquidity” really means: not just “more liquidity near the current price,” but liquidity as a variable, piecewise quantity across the curve instead of a flat one.
That creates a new engineering problem: how do you track a liquidity function that changes shape every time someone opens or closes a position, without making every swap prohibitively expensive to compute? You can’t just re-integrate some continuous curve on every trade; that would be a gas nightmare. You need a way to represent “liquidity changes here” as a small number of cheap, discrete events. That’s exactly what ticks are for.
Before ticks even enter the picture, it’s worth being precise about what “price” means inside a pool, because it’s easy to get backwards.
A pool holds two tokens, call them X and Y, with reserves x and y. The price of X, denominated in Y, is defined as the ratio:
P = y / x
This tells you how much Y you get per unit of X. If P = 10, that means 1 unit of X is worth 10 units of Y.
But every price has a flip side, the price of Y, denominated in X, and that’s just the reciprocal:
P_y = x / y = 1 / P
So if P = 10, then P_y = 1 / 10 = 0.1. That is, 1 unit of Y is worth 0.1 units of X. Same pool, same reserves, just looked at from the other token’s point of view.
This matters for ticks because Uniswap has to pick one consistent direction to define “the” price of a pool (by convention, token1 per token0), and every tick, every range boundary, and every “in range / out of range” check is implicitly expressed in that direction. If you ever flip a chart or a UI from showing X/Y to Y/X, you’re just looking at P versus 1/P, and since 1.0001^(-tick) = 1 / 1.0001^tick, that flip corresponds exactly to negating the tick.
Think of the entire possible price spectrum for a trading pair as a number line. Uniswap chops that number line into discrete steps like marks on a ruler. Each mark is called a tick.
Formally, each tick corresponds to a specific price using this formula:
price = 1.0001^tick
Why 1.0001? Because each tick represents a 0.01% (1 basis point) price movement from the previous one. That’s a small enough step to give fine-grained pricing, while still being a fixed, predictable increment that smart contracts can compute cheaply.
So:
As the number of ticks increases, the price increases. As it goes down, the price goes down. It’s essentially a logarithmic index for price — instead of storing raw prices (which involve messy decimals and rounding issues), Uniswap stores integers, and integers are cheap and precise for a blockchain to work with.
Here’s the part that actually answers “why ticks”: Uniswap V3 doesn’t store liquidity as a smooth curve. It stores liquidity as piecewise constant flat within a segment between two ticks, and only changes at a tick.
Every tick that has at least one position starting or ending on it is called an “initialized tick,” and it stores a single important number: liquidityNet, how much total liquidity gets added (or removed) the moment the price crosses that tick.
When a swap happens and price moves through the pool:
That’s the entire trick. Instead of continuously modeling every LP’s individual range on every single trade, the contract only has to do work at the handful of tick boundaries a swap actually crosses. Most of a swap’s execution is just “keep using this same flat number” cheap arithmetic with occasional O(1) jumps at crossings. This is what makes concentrated liquidity computationally practical on a blockchain where every operation costs gas.
Here’s a wrinkle beginners often miss: pools don’t let you set a position at every single tick. Each pool has a tick spacing parameter, and LP positions can only start or end on ticks that are multiples of that spacing.
This is a gas-vs-precision tradeoff: fewer usable ticks means fewer possible positions to check during a swap, which keeps transactions cheaper.
Every idea above the current price, the current tick, and tick spacing has to actually live somewhere in the contract’s storage. That place is a single storage variable called slot0.
Storage on Ethereum is expensive: every distinct storage slot you read or write costs gas. So instead of storing the pool’s current price, current tick, and a handful of other frequently-read values as separate variables (which would mean separate expensive storage reads every time), Uniswap V3 packs them all into one 256-bit slot. Reading “the state of the pool right now” becomes one cheap storage read instead of five or six.
slot0 bundles together things like:
You don’t need to memorize every field, but the concept is worth internalizing: slot0 is effectively the pool’s “dashboard”, the current price (as a square root), the current tick, and a few bookkeeping values, all packed together so that checking “where is the market right now” is as gas-cheap as a single read. It’s the same design philosophy as ticks themselves: concentrated liquidity only works economically on-chain because Uniswap is relentless about turning expensive continuous math into cheap discrete lookups.
When you provide liquidity on Uniswap V3, you’re literally choosing a segment of the curve: a lower tick and an upper tick. Under the hood, opening that position adds your liquidity amount to liquidityNet at your lower tick, and subtracts it at your upper tick. That’s how the contract knows to “turn your capital on” when price enters your segment and “turn it off” when price leaves it.
Every other LP is doing the same thing on their own chosen segments, which is exactly why total liquidity varies across the price curve instead of being one flat number like in V2.
This is why LPs talk about “narrow ranges” vs “wide ranges.” A narrow range around the current price earns more fees per dollar of capital (because it’s more concentrated) — but it’s riskier, since price is more likely to drift outside a tight range, leaving you exposed to just one asset and out of the fee-earning game until you rebalance.
Even if you never plan to write a smart contract, understanding ticks helps you:
Read LP dashboards intelligently. When a Uniswap interface shows your position as “in range” or “out of range,” it’s really telling you where the current tick sits relative to your chosen tick boundaries.
Understand impermanent loss dynamics better. Concentrated positions amplify impermanent loss compared to V2-style full-range positions, because your capital is doing more “work” in a smaller price window.
Make smarter range choices. Wider ranges = more passive, lower fee density, more forgiving. Narrower ranges = active management, higher fee density, higher risk of going out of range.
Follow protocol design conversations. Ticks are foundational to how newer AMMs (including Uniswap V4 hooks) build custom logic around liquidity concentration, dynamic fees, and range orders.
Once you see ticks as just “steps on a price ruler” rather than some exotic DeFi math, the rest of Uniswap V3/V4’s mechanics, range orders, active liquidity, and fee concentration start to click into place much faster.
Disclaimer: This article is for educational purposes only and does not constitute financial or investment advice. DeFi protocols carry smart contract, market, and liquidity risks always do your own research before providing liquidity.