# Как устроены лимиты Polymarket в трёх его API

> Polymarket публикует глобальный потолок в 15 000 запросов за 10 секунд, и почти ни одна интеграция до него не доходит. Останавливает вас число на два порядка меньше — то, что стоит на конкретном эндпоинте, который вы вызываете.

- Источник: https://papaproxy.net/ru/blog/polymarket-api-rate-limits.php
- Опубликовано: 2026-08-08
- Автор: Alex Young
- Рубрика: Лимиты и производительность · Блог PapaProxy.net

---

## Ключевые выводы

- 15 000 за 10 секунд — глобальный потолок, а не бюджет: ограничивает вас число того эндпоинта, который вы вызываете: у `/positions` — 150, у `/markets` — 300, у `/events` — 500.
- Цифры на стороне чтения даны в десятисекундном окне (то есть 300 у `/markets` — это 30 rps в устойчивом режиме), но окна разные: у торговли есть ещё десятиминутный устойчивый потолок, у релеера окно минутное, а бакеты подписанта заданы в токенах в секунду.
- Бюджеты хостов раздельные — Gamma 4 000, CLOB 9 000, Data API 1 000 за 10 секунд, — и в нашем тесте троттлинг конкретного эндпоинта остался локальным: контроль получил ноль отказов в шести парах, пока нагруженный получал от 5% до 35%, — правда, нагрузка не приближалась к совместной и общехостовой квотам, лежащим выше.
- Документация говорит, что лишние запросы ставятся в очередь, а не отклоняются; в наших прогонах эндпоинты чтения отдавали немедленный 429 без фазы замедления, с `Retry-After: 0` и без заголовков `X-RateLimit-*` — поэтому считайте запросы сами и следите и за задержкой, и за 429.
- Превышение лимита не даёт ничего: при подаче на `/markets` от 35,6 до 43,6 rps полезная скорость держалась ровно на 27,8–28,7 rps — 93–96% документированного потолка, — а от 21% до 35% запросов уходило в отказы.
- У торговли есть второй, ортогональный ограничитель: токен-бакеты на подписанта с раздельными балансами ордеров и отмен, тиры по объёму от Standard (40/с, burst 60) до Elite (600/с, burst 900), батчи по принципу «всё или ничего» и cancel-all, списывающий по токену за каждый фактически отменённый ордер, — и вот его 429 несут осмысленный `Retry-After`.
- Мощность чтения растёт вместе с числом адресов — 95,3% эффективности на двадцати, без штрафа за /24 и со сбросом бюджета при смене адреса, — а пропускная способность по ордерам, привязанная к подписанту, так не растёт.

## Три API, три раздельных бюджета

Как показано в нашем руководстве по [трём API Polymarket](/ru/blog/polymarket-three-apis.php), у платформы три хоста, и у каждого своя квота под этим глобальным потолком. Официальная документация по лимитам перечисляет их по эндпоинтам, и рисунок везде одинаковый: щедрое число на хост целиком и заметно более жёсткие потолки на тех эндпоинтах, которые дороже обходятся платформе.

| Хост | Общий | Более жёсткие эндпоинты |
| --- | --- | --- |
| Gamma (`gamma-api`) | 4 000 / 10 с | `/events` 500, `/markets` 300, поиск 350 |
| CLOB (`clob`) | 9 000 / 10 с | `/book`, `/price`, `/midpoint` 1 500; батчевые `/books`, `/prices`, `/midpoints` 500; `/data/orders`, `/data/trades` 500; эндпоинты API-ключей 100 |
| Data (`data-api`) | 1 000 / 10 с | `/trades` 200, `/positions` 150, `/closed-positions` 150 |

Лимиты Gamma API самые щедрые, потому что метаданные кешируются и почти не меняются. Лимиты CLOB API крупнейшие в абсолютных числах — 9 000 за 10 секунд на хост, — поскольку рыночные данные читает постоянно почти любая интеграция. Лимиты Data API — самые жёсткие из трёх, и эта асимметрия и есть то, что стоит усвоить в первую очередь: дефицитный ресурс здесь именно эндпоинты, привязанные к кошелькам, поэтому трекер портфелей упирается в бюджет задолго до ценового фида.

Разделение работает в вашу пользу, если планировать с его учётом. Чтение метаданных рынка из Gamma не расходует квоту, которая нужна опросу позиций в Data API, поэтому обогащение holdings названиями рынков с точки зрения бюджета почти бесплатно. Стройте конвейеры так, чтобы каждый хост делал ту работу, которая ему обходится дешевле всего.

## Почему общее число вводит в заблуждение

15 000 — это потолок по всему сразу, а не квота, которую можно потратить на что-то одно. Поля, фильтры и пагинацию самого узкого эндпоинта мы разобрали в руководстве по [Data API `/positions` Polymarket](/ru/blog/polymarket-data-api-positions.php). На практике вас ограничивает то число уровня эндпоинта, в которое вы упрётесь первым, и разрыв драматический: 150 запросов за 10 секунд у `/positions` — это 1% от глобального потолка.

Полезно и перевести единицы, потому что лимиты в секунду, которые все подразумевают, редко совпадают с опубликованными. Цифры на стороне чтения даны в **десятисекундном окне**, поэтому `/markets` с его 300 за 10 секунд — это 30 запросов в секунду в устойчивом режиме, а не 300. Но окна на площадке неоднородны: у торговых эндпоинтов есть ещё и устойчивый потолок, отмеряемый десятью минутами, у submit-эндпоинта релеера окно минутное, а бакеты подписанта заданы в токенах в секунду. Читайте окно вместе с числом — каждый раз.

Лимиты эндпоинта рынков хорошо показывают, почему различие важно: на 30 запросах в секунду большой каталог обходится быстро, но наивный цикл, выпустивший 300 запросов в первую же секунду, столкнётся с окном, хотя число «за 10 секунд» выглядело комфортным.

Практические следствия вытекают из арифметики:

- **Считайте собственный потолок под задачу.** Трекеру на 500 кошельков по одному вызову `/positions` нужно 500 ÷ 150 ≈ 3,3 десятисекундных окна — то есть 33 секунды на полный обход с одного адреса, что бы ни говорил глобальный потолок.
- **Группируйте там, где есть батч.** У `/books` и `/prices` квота по числу запросов ниже, чем у одиночных версий (500 против 1 500 за 10 секунд), но каждый запрос покрывает много токенов, поэтому для многотокенной работы они сокращают именно количество запросов. Насколько — зависит от того, сколько токенов вы упаковываете в вызов.
- **Листайте Gamma курсорами.** `/markets/keyset` и `/events/keyset` возвращают `next_cursor` и заменяют offset-эндпоинты, которые идут к отказу от поддержки. Учтите, что потолки у них разные: `limit` не выше 100 у `/markets/keyset` и не выше 500 у `/events/keyset`.

## Как троттлинг выглядит с вашей стороны

Здесь опубликованная модель Polymarket отличается от большинства площадок. Лимиты применяет Cloudflare на **скользящих окнах**, и документация утверждает, что запросы сверх лимита троттлятся — задерживаются и ставятся в очередь, — а не отклоняются сразу.

Чего документация не обещает, так это формы этой деградации: она не говорит, что первым симптомом всегда будет задержка, и не гарантирует, что ответы продолжат приходить с кодом 200, пока вы за пределами бюджета. Наши собственные замеры на эндпоинтах чтения дали обратное поведение — жёсткий `429` на изломе без предварительного замедления, — и раздел ниже рассказывает, что мы увидели. Поэтому наблюдайте за обоими сигналами: снимайте p95 длительности запроса по каждому эндпоинту, считайте 429 отдельно и ведите собственный счётчик запросов за десятисекундное окно по каждому хосту, чтобы знать своё положение раньше, чем о нём сообщит площадка.

Что до ретраев — здесь важна точность в том, где вообще есть подсказка. Ограничитель торговли на подписанта документирует заголовок `Retry-After` в своих ответах `429`, и там значение осмысленно: это минимальная задержка, после которой ваш запрос станет по карману. Общая страница IP-лимитов ничего подобного для эндпоинтов чтения не обещает, поэтому не стройте откат в расчёте на то, что заголовок придёт и будет полезным.

Лимиты при аутентификации подчиняются той же модели по IP, но с двумя добавками, которые стоит закладывать. У эндпоинтов управления API-ключами в CLOB своя жёсткая квота — 100 запросов за 10 секунд: этого с избытком хватает, чтобы вывести ключ при старте, и мало, если вы переполучаете учётные данные при каждом перезапуске воркера. А у аутентифицированной торговли есть совершенно отдельный ограничитель — о нём дальше.

## Burst и устойчивые лимиты в торговле

Ордера и отмены управляются токен-бакетами на подписанта, которые действуют **вместе** с IP-лимитами Cloudflare, а не вместо них. Работают оба. Адрес подписанта здесь — это адрес, связанный с вашими учётными данными CLOB API, и у каждого подписанта два независимых бакета: один для ордеров, другой для отмен, причём расход в одном не трогает другой.

Лимиты торговых эндпоинтов заданы скоростью пополнения плюс ёмкостью всплеска. Токены накапливаются непрерывно со скоростью текущего тира; burst — это максимум, который бакет может удерживать, поэтому полный бакет можно потратить разом, а дальше он пополняется ровным темпом. Документация даёт арифметику прямо: `burst_seconds = burst / rate_per_sec` показывает, на сколько хватит полного всплеска при непрерывном давлении.

Стоимость в токенах считается за единицу работы, а не за запрос, — и именно эта деталь ловит тех, кто работает батчами:

| Бакет | Запрос | Стоимость в токенах |
| --- | --- | --- |
| Order | `POST /order` | 1 |
| Order | `POST /orders` | число ордеров в батче |
| Cancel | `DELETE /order` | 1 |
| Cancel | `DELETE /orders` | число переданных ID ордеров |
| Cancel | `DELETE /cancel-all` | 1 плюс число фактически отменённых ордеров |
| Cancel | `DELETE /cancel-market-orders` | 1 плюс число подошедших отменённых ордеров |

На уровне лимитера батчи работают по принципу «всё или ничего»: батч принимается, только если в бакете хватает токенов на каждую позицию, иначе отклоняется весь запрос и не обрабатывается ничего. Батч, чья стоимость превышает burst текущего тира, не может быть принят в принципе — его придётся разбивать, а повторные попытки отправить его без изменений будут падать всегда.

Механика cancel-all заслуживает отдельного внимания, потому что способна загнать вас в долг. Поскольку число ордеров к отмене заранее неизвестно, запрос сначала тратит один токен, а затем, по факту, списывает ещё по одному за каждый успешно отменённый ордер. На тирах, где это разрешено, второе списание уводит баланс ниже нуля, и дальнейшие отмены остаются заблокированными, пока баланс не восстановится.

Ёмкость зависит от тиров по объёму, которые назначаются по накопленному 30-дневному обороту мейкерского кошелька — даже когда мейкер отличается от подписанта — и обновляются каждые три часа:

| Тир | Оборот за 30 дней | Ордера: скорость/burst | Отмены: скорость/burst | Отрицательный баланс отмен |
| --- | --- | --- | --- | --- |
| Standard | — | 40 / 60 | 80 / 120 | Да |
| Copper | $30 000+ | 60 / 90 | 120 / 180 | Да |
| Bronze | $50 000+ | 80 / 120 | 160 / 240 | Да |
| Silver | $100 000+ | 200 / 300 | 400 / 600 | Да |
| Gold | $500 000+ | 400 / 600 | 800 / 1 200 | Да |
| Platinum | $2,5 млн+ | 450 / 675 | 900 / 1 350 | Нет |
| Diamond | $5 млн+ | 525 / 787 | 1 050 / 1 575 | Нет |
| Elite | $10 млн+ | 600 / 900 | 1 200 / 1 800 | Нет |

Polymarket отмечает, что пороги, окно объёма и сами скорости могут меняться по мере настройки системы, — поэтому читайте их из карточки, а не зашивайте в код. Та же страница описывает выкатку в режиме предупреждения, начатую 24 июля 2026 года: в этот период запросы, которые позже будут отклоняться, несут заголовок `Poly-RateLimit-Warning: true`, но всё ещё обрабатываются. Проверьте текущий статус боевого применения, прежде чем рассчитывать на любое из двух поведений.

В отличие от IP-лимитов, этот ограничитель сообщает своё состояние заголовками: `Poly-RateLimit-Remaining` — баланс бакета, `Poly-RateLimit-Reset` — когда закончится текущее ожидание, `Poly-RateLimit-Tier` — применённый тир, а `Retry-After` приходит на 429. Две тонкости: `Reset` — это не момент, когда бакет заполнится, а момент, когда должно хватить токенов на тот запрос, который вы пытались отправить; а `Remaining` может уйти в минус после cancel-all на тирах, допускающих долг. Перед отправкой крупного батча сравнивайте его стоимость с остатком.

## Наш тест: что лимиты делают на самом деле

В августе 2026 года мы измерили сторону чтения всех трёх хостов. Кампания тестирования заняла в общей сложности 24 часа, но отдельные ступени нагрузки длились по 60 секунд, поэтому это не тест суточной ровной нагрузки. Всё описанное ниже — публичный GET-трафик: без аутентификации, без ордеров и без вмешательства в живые стаканы, с двух раздельно учитываемых пулов выделенных адресов — датацентрового и ISP, — которые нигде не сводились в общую цифру. Нагрузка подавалась в процентах от документированного темпа, а лестница останавливалась на первом отказе.

**Поведение при превышении противоречит документированной модели.** Это главный результат. На всех эндпоинтах и обоих пулах излом приходил немедленным `429` без всякой фазы очереди: базовая задержка держалась ровной вплоть до ступени излома, а затем запросы просто отклонялись. Плавного замедления, которое описывает документация, мы не наблюдали ни разу. Две детали делают ситуацию хуже для того, кто пишет клиент:

- `Retry-After` присутствует, но его значение равно `0` — как указание на паузу он не сообщает ничего;
- заголовки `X-RateLimit-*` отсутствуют полностью. Прочитать остаток бюджета негде: единственный сигнал — удар в стену.

Оба факта указывают в одну сторону: ведите собственный счётчик по каждому хосту и эндпоинту, а 429 воспринимайте как подтверждение, что вы уже вышли за предел, а не как подсказку по расписанию.

**Где находится излом.**

| Эндпоинт | Документировано | Излом | Вывод |
| --- | --- | --- | --- |
| `gamma /markets` | 300 / 10 с = 30 rps | первый 429 на ступени номинальных 100% | отказы начинаются на документированном темпе |
| `data /positions` | 150 / 10 с = 15 rps | между 100% и 125% | документированный переживает, ломается ниже 125% |

Читать это следует как диапазоны, а не как точные пороги: лестница с дискретным шагом локализует излом между двумя ступенями, а не с точностью до запроса. Оба пула дали идентичные границы — разницы между датацентровыми и ISP-адресами в том, где стоит лимит, мы не нашли.

**Троттлинг эндпоинта остался локальным — в проверенном нами диапазоне.** Мы нагружали один эндпоинт до 150% его документированного темпа, одновременно медленно опрашивая второй, — шесть пар. Цель получала от 5% до 35% отказов; контроль — ноль 429 во всех шести парах, включая пару, где оба эндпоинта живут на одном хосте (`/markets` под нагрузкой, `/events` в контроле).

Важно понимать, что именно отсюда следует, а что нет. У Gamma есть общая квота на `/markets` и `/events` вместе и ещё более высокий общий лимит хоста; нагрузка `/markets` до 150% его собственного потолка остаётся заметно ниже обоих. Поэтому честная формулировка уже, чем «бюджеты изолированы»: троттлинг, специфичный для `/markets`, не перелился на контрольный эндпоинт при той нагрузке, которую мы подавали. Ведут ли себя независимо совместная и общехостовая квоты — отдельный вопрос, до которого наша схема не дотянулась: для него нужна нагрузка, подходящая к этим более высоким уровням.

**Давить сильнее бессмысленно.** Если считать успешные ответы, а не отправленные запросы, на `gamma /markets` получается так:

| Пул | Отдавали | Проходило успешно | От документированных 30 rps |
| --- | --- | --- | --- |
| Датацентр | 35,6 rps | 28,1 | 94% |
| Датацентр | 43,6 rps | 28,7 | 96% |
| ISP | 42,9 rps | 27,8 | 93% |
| ISP | 37,9 rps | 27,9 | 93% |

Четыре независимых прогона, предложенная нагрузка от 35,6 до 43,6 запроса в секунду — а полезная пропускная способность ни разу не вышла из полосы 27,8–28,7, то есть 93–96% документированного потолка. Это более крепкое свидетельство о положении лимита, чем единичное наблюдение излома: перед нами плато пропускной способности, устоявшее при разбросе подаваемой нагрузки более чем на 20%. Всё, что подаётся сверх плато, конвертируется в отказы — от 21% до 35% запросов в этих четырёх прогонах — и не приносит ни одного дополнительного ответа.

**Адреса складываются линейно.** При нагрузке в половину измеренного излома на каждый адрес по `/positions`:

| Адресов | Датацентр, rps | Эффективность | ISP, rps | Эффективность |
| --- | --- | --- | --- | --- |
| 1 | 9,09 | 100% | 9,10 | 100% |
| 2 | 18,10 | 99,6% | 18,11 | 99,5% |
| 5 | 45,11 | 99,3% | 45,12 | 99,2% |
| 10 | 88,70 | 97,6% | 89,18 | 98,0% |
| 20 | 173,28 | 95,3% | — | — |

Отсюда два связанных наблюдения: лимит не считается по подсети — четыре адреса из одной /24 дали тот же результат, что четыре из разных, без отказов в обеих группах, — и бюджет сбрасывается при смене адреса, так что после доведённого до отказа адреса следующий отдаёт полный бюджет. Уникальность выходов проверялась первой, потому что без неё вся эта арифметика не работает: 999 уникальных точек выхода из 999 на датацентровом пуле и 100 из 100 на ISP.

**Накладные расходы прокси различаются по пулам.** Прямые базы снимались вперемешку с прогонами через прокси, а не однократно перед ними, поэтому сравнение корректно:

| Хост | Добавляет датацентр | Добавляет ISP |
| --- | --- | --- |
| gamma | +747 мс | +327 мс |
| data | +643 мс | +312 мс |
| clob | +612 мс | +464 мс |

ISP-адреса добавляли меньше на каждом хосте, но не в постоянной пропорции: примерно вдвое меньше на gamma (327 против 747 мс) и data (312 против 643 мс), однако на clob — лишь примерно на четверть (464 против 612 мс). Для задач на пропускную способность разница несущественна: оба пула упёрлись в одинаковые границы лимитов, поэтому ограничивает потолок эндпоинта в любом случае. Для чувствительных к задержке задач на этом маршруте быстрее оказался ISP.

**Один результат мы объяснить не смогли.** При одинаковом предложенном темпе 22,3 rps на `/positions` датацентровый пул дал 5% отказов и 21,3 успешных rps, а ISP — 29% отказов и 15,8: шестикратная разница в доле отказов при равной нагрузке. Прогоны разделяли шесть минут, поэтому лимит мог дрейфовать во времени, а могло и что-то различать сами наборы адресов. Публикуем как открытый вопрос, а не сглаживаем.

**Чего мы не измеряли.** Ни один эндпоинт CLOB под нагрузкой не проверялся — только доступность и задержка, — поэтому измеренного числа по `/book` или `/price` у нас нет, и документированные цифры остаются неподтверждёнными с нашей стороны. Торговые эндпоинты исключены принципиально: они требуют пополненного кошелька и подписанных ордеров, а даже немедленно отменённый ордер вмешивается в живой стакан, поэтому всё в торговом разделе выше взято из документации. Максимальная ступень длилась 60 секунд, так что многочасовая ровная нагрузка не проверена, и маршрут был один географический.

## Как проектировать внутри лимитов

Большинство интеграций, упирающихся в лимиты, тратят бюджет на вопросы, ответы на которые уже знают. Прежде чем добавлять мощность, три привычки обычно высвобождают больше запаса, чем инфраструктура:

**Кешируйте то, что не меняется.** Вопрос рынка, слаг, condition ID и ID токенов не меняются никогда. Один раз забрать и сохранить — значит убрать с горячего пути целый класс вызовов Gamma.

**[Подписывайтесь вместо опроса](/ru/blog/polymarket-websocket-api.php).** Живым ценам и обновлениям стакана место на вебсокет-каналах; REST-опрос данных, которые и так пушатся, — самый частый источник самостоятельно устроенного троттлинга.

**Опрашивайте по уровням, а не равномерно.** Кошелькам с крупной живой экспозицией нужен короткий интервал, спящим — длинный. Равномерный таймер тратит большую часть бюджета на подтверждение того, что ничего не произошло.

После этого остаётся то, что действительно ограничено документированными поадресными квотами, — и наши замеры уточняют, что это значит. Продавливание одного адреса за потолок эндпоинта не дало вообще никакого прироста, поэтому единственный способ читать быстрее — больше адресов, и складываются они почти линейно: 95,3% эффективности на двадцати адресах, без штрафа за непрерывный блок /24 и с полным бюджетом сразу после перехода на следующий адрес. Это касается только чтения. Пропускную способность по ордерам так не масштабировать: торговые бакеты привязаны к подписанту, поэтому добавление адресов не увеличивает скорость выставления и отмены ордеров — и пытаться обойти это таким способом не стоит.

Если ваше ограничение — объём чтения, наши [персональные прокси](/ru/individual.php) представляют собой выделенные IPv4-адреса, статичные на весь срок плана, к каждому из которых применяется своя документированная квота. О выборе между пулами наши прогоны позволяют сделать один вывод и не позволяют другой: оба пула упёрлись в одинаковые границы лимитов, то есть по пропускной способности ни один не быстрее, — а вот по накладной задержке на этом маршруте ISP оказался легче, и это имеет значение, только если ваша нагрузка чувствительна ко времени ответа. Масштабирование проверяйте на своей нагрузке, а не считайте линейным за пределами проверенного нами диапазона, и перед распределением нагрузки по адресам сверьтесь с актуальными условиями использования Polymarket.
