pgduck_server: cap s3_uploader_thread_limit by host memory#433
Draft
sfc-gh-mslot wants to merge 1 commit into
Draft
pgduck_server: cap s3_uploader_thread_limit by host memory#433sfc-gh-mslot wants to merge 1 commit into
sfc-gh-mslot wants to merge 1 commit into
Conversation
50f89b7 to
b116337
Compare
b116337 to
bcb7389
Compare
bcb7389 to
0dd7cce
Compare
sfc-gh-mslot
commented
Jul 9, 2026
| } | ||
|
|
||
| { | ||
| uint64 s3UploaderThreadLimit = DefaultS3UploaderThreadLimit(); |
Collaborator
Author
There was a problem hiding this comment.
useful to pass in memoryLimit here?
DuckDB's httpfs uploader defaults to 50 concurrent multipart-upload part buffers per file, each ~80MB and allocated against memory_limit. On a small host (memory_limit 2GB) a single large snapshot write to S3 can pin up to ~4GB and crash pgduck_server with an out-of-memory error, taking down concurrent queries for other mirrors. Read the effective memory_limit back from DuckDB and set s3_uploader_thread_limit to ~2 per GiB of it, clamped to [2, 50]. Sizing against the budget the buffers are charged to (not physical RAM, which can differ) keeps the cap correct when memory_limit is set below RAM. Runs after memory_limit is configured and before the init file, so it reflects the real budget and operators can still override it. Signed-off-by: Marco Slot <marco.slot@snowflake.com>
0dd7cce to
a4f1bda
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
DuckDB's httpfs S3 uploader keeps up to
s3_uploader_thread_limitmultipart-upload part buffers in flight per open file (default 50), each ~80MB and allocated against DuckDB'smemory_limit(MemoryTag::EXTENSION). The default part size is ~80MB because it derives froms3_uploader_max_filesize / s3_uploader_max_parts_per_file(800GB / 10000). On a small host (memory_limit2GB) a single large snapshot writing to S3 can pin up to ~4GB in part buffers alone, hit the limit, and crashpgduck_serverwith an out-of-memory error. systemd restarts it and the snapshot retries into the same failure, so one oversized table can crash-loop the server for hours, aborting concurrent queries for every other mirror each time.Solution
Set
s3_uploader_thread_limitat startup instead of leaving it at the upstream default of 50. The part buffers are charged againstmemory_limit, so the cap is sized against that budget rather than physical RAM (the two can differ, e.g. a 2GB limit on a 4GB host). We read the effectivememory_limitback from DuckDB and use ~2 threads per GiB, clamped to[2, 50](never above the upstream default). Uploads are network-bound and run on detached threads independent of DuckDB'sthreadssetting, so CPU count is not the constraint.memory_limits3_uploader_thread_limitThe
SET GLOBALruns aftermemory_limitis configured and before the init file is applied, so it reflects the effective limit and an operator can still override it:Test plan
pgduck_serverbuild clean under the tree's-Wall/-Werror=…flags.s3_uploader_thread_limit is set to: NandSELECT current_setting('s3_uploader_thread_limit')returns it:--memory_limit=2GB→ 4,512MB→ 2 (floor), a large limit → 50 (cap).