You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Mar 6, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Mar 6, 2026. It is now read-only.
Avoid running out of memory during slow iteration: set worker_queue maxsize to be 1, and/or make it configurable #561
Is your feature request related to a problem? Please describe.
When using to_dataframe_iterable for a large result set (with nested/repeated records) on a system with a fast upstream connection to BigQuery, but slow downstream processing, Python can use all the memory on the system, and get killed.
I think I have tracked it down to the worker_queue that is used to pass data from the worker threads back to the main thread: it does not have a maxsize.
This means that if items are not pulled from the queue fast enough, then all the memory on the system can be used
Describe the solution you'd like
I think a reasonable solution would be to set the maxsize to be 1:
worker_queue=queue.Queue(maxsize=1)
This would still effectively be a buffer size of "number of threads + 1" pages since each thread would fetch into a variable, and then wait if the queue is full.
However, it being configurable would also be reasonable I think.
Describe alternatives you've considered
I've monkey-patched for now, and it seems to work. But ideally, it wouldn't be necessary
# ...def_monkey_patch_queue_maxsize_1():
OriginalQueue=queue.QueueclassQueueWithMaxsize1(OriginalQueue):
def__init__(self):
super().__init__(maxsize=1)
def_restore():
queue.Queue=OriginalQueuequeue.Queue=QueueWithMaxsize1return_restore# ....query=bqClient.query(sql)
result_rows=query.result()
ensure_original_queue=_monkey_patch_queue_maxsize_1()
pages=result_rows.to_dataframe_iterable(bqStorageClient)
forpageinpages:
ensure_original_queue()
# ... something slow, even time.sleep can do it
That's probably a reasonable solution. The grpc-based clients have their own flow control, so it should be okay to use a smaller queue size for this step.
Activity
tswast commentedon Mar 19, 2021
That's probably a reasonable solution. The grpc-based clients have their own flow control, so it should be okay to use a smaller queue size for this step.