2025, Nov 30 21:02

Почему запросы с [date] в Overpass через OSMnx падают по памяти и как это исправить

Почему запросы с [date] в Overpass API через OSMnx падают по памяти и дают run out of memory. Показываем причину и фикс: увеличить ox.settings.overpass_memory.

Если вы добавляете исторический срез к запросу Overpass API через OSMnx, на первый взгляд безобидная настройка способна довести сервер до предельного расхода памяти. Если вы фильтруете по тегам вроде highway=residential и запрос стабильно падает только при наличии параметра [date], дело в том, как Overpass обрабатывает запросы с датой, а не в ошибке OSMnx.

Воспроизводимый пример

Ниже приведён фрагмент, который запрашивает жилые дороги внутри полигона в формате WKT на конкретный момент времени. В примере увеличен таймаут и включён подробный лог. При добавлении [date] в overpass_settings запрос может привести к серверному сообщению «run out of memory»; без него тот же вызов завершается штатно.

import osmnx as ox
import shapely
import datetime
snap_ts = datetime.datetime.fromisoformat("2023-12-31T10:15:23.355030")
wkt_area = "POLYGON ((12.492709372340677 41.916655635027965, 12.495766040251999 41.99143760629819, 12.76378053852936 41.984419025131984, 12.754692779733519 41.78305304410847, 12.487561402159495 41.79004473805951, 12.48453188956227 41.715248372182295, 12.21767031884794 41.72151888179064, 12.224974122071886 41.92295004575664, 12.492709372340677 41.916655635027965))"
ox.settings.requests_timeout = 200
ox.settings.use_cache = False
ox.settings.log_console = True
ox.settings.overpass_settings = f"[out:json][timeout:{ox.settings.requests_timeout}][date:\"{snap_ts}\"]"
poly_geom = shapely.wkt.loads(wkt_area)
kvs = {"highway": "residential"}
rows = ox.features_from_polygon(poly_geom, kvs)
print(len(rows))

Если убрать строку с установкой overpass_settings, запрос проходит — это напрямую указывает на фильтр [date] как на причину.

Почему с [date] это падает

Бэкэнд Overpass меняет стратегию выполнения, когда присутствует фильтр даты. Вместо просмотра только текущих версий объектов он восстанавливает их историю, чтобы соответствовать запрошенному моменту времени. На стандартном сервере это заметно увеличивает потребление памяти.

Добавление [date] в запрос приводит к иной стратегии выполнения: данные нужно реконструировать из прежних и текущих версий объектов, чтобы соответствовать запрошенной дате. Без [date] учитываются только текущие версии, что резко сокращает объём данных.

Отдельно отмечено, что другие реализации с оптимизациями справляются с тем же классом запросов при меньшем объёме памяти.

Кстати, я проверил этот запрос на другой реализации с некоторыми улучшениями производительности. Оба запроса с датой выполнялись за секунду‑другую при maxsize 512M.

Иными словами, истощение памяти происходит на стороне Overpass API именно из‑за [date].

Решение: выделить серверу больше памяти

В OSMnx лимит памяти для Overpass задаётся через ox.settings.overpass_memory. Увеличив его, вы позволите серверу выполнить исторические запросы, которые иначе падают. После повышения лимита тот же запрос проходит, хотя может выполняться заметно дольше.

import osmnx as ox
import shapely
import datetime
snap_ts = datetime.datetime.fromisoformat("2023-12-31T10:15:23.355030")
wkt_area = "POLYGON ((12.492709372340677 41.916655635027965, 12.495766040251999 41.99143760629819, 12.76378053852936 41.984419025131984, 12.754692779733519 41.78305304410847, 12.487561402159495 41.79004473805951, 12.48453188956227 41.715248372182295, 12.21767031884794 41.72151888179064, 12.224974122071886 41.92295004575664, 12.492709372340677 41.916655635027965))"
ox.settings.use_cache = False
ox.settings.log_console = True
ox.settings.requests_timeout = 200
ox.settings.overpass_memory = "3G"
ox.settings.overpass_settings = f"[out:json][timeout:{ox.settings.requests_timeout}][date:\"{snap_ts}\"]"
poly_geom = shapely.wkt.loads(wkt_area)
kvs = {"highway": "residential"}
rows = ox.features_from_polygon(poly_geom, kvs)
print(len(rows))

Это напрямую устраняет серверное замечание «Query run out of memory using about 2048 MB of RAM». После увеличения лимита памяти тот же исторический запрос завершается, но может занять довольно много времени.

Зачем это важно

Исторические запросы часто нужны для воспроизводимости, аудитов и временной аналитики. Понимание того, что [date] переключает Overpass в иной, более прожорливый по памяти режим, помогает правильно трактовать сбои. Регулировка лимита памяти — это практичный рычаг, доступный в OSMnx. Другие настройки — например, увеличение только requests_timeout или уменьшение max_query_area_size — в этой ситуации, как правило, не помогут, потому что узкое место — память, а не длительность запроса или разбиение.

Что запомнить

Если вам нужен снимок состояния на момент времени, оставляйте параметр [date], но повышайте ox.settings.overpass_memory до тех пор, пока сервер не начнёт справляться с вашим запросом, и будьте готовы к более долгому выполнению. Если же историческое состояние не требуется, уберите [date], чтобы уложиться в стандартный объём памяти. Держите включённым ox.settings.log_console во время экспериментов, чтобы сразу видеть серверные сообщения Overpass и убедиться, что упираетесь именно в лимит памяти, а не во что‑то другое. С этими настройками привычный рабочий процесс в OSMnx сохраняется, и вы можете стабильно получать объекты как на текущий момент, так и на конкретную дату.