perf: submit I/O requests eagerly in FullZipScheduler#6513
Merged
Xuanwo merged 1 commit intolance-format:mainfrom Apr 14, 2026
Merged
perf: submit I/O requests eagerly in FullZipScheduler#6513Xuanwo merged 1 commit intolance-format:mainfrom
Xuanwo merged 1 commit intolance-format:mainfrom
Conversation
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
Member
|
Belated second approval. Thanks for catching this! This is the third time this issue (wrapping something with async move closure only to have the execution semantics get changed) has bitten me in two months 😆 |
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.
Summary
Refactor
FullZipScheduler::create_page_load_taskto accept a pre-submitted I/O future instead of deferring I/O submission until the async task executes. This allows the I/O requests to be submitted immediately during scheduling, enabling the object store layer to batch and parallelize them. close #6504I/O Model Change
Before: Lazy I/O submission (serialized)
Previously,
create_page_load_taskreceived aFullZipReadSource::Remote(io)along with byte ranges and priority. The actualio.submit_request()call happened inside the async block, meaning the I/O request was not submitted until the future was first polled.When decoding multiple pages (e.g. across many fragments), this created a sequential I/O pattern:
Each page's I/O request could only be submitted after the previous task started executing. The I/O scheduler had no visibility into upcoming requests, preventing it from batching or parallelizing them effectively.
After: Eager I/O submission (pipelined)
Now,
io.submit_request()is called before constructing thePageLoadTask, and the resulting future is passed intocreate_page_load_task. All I/O requests for all pages are submitted upfront during the scheduling phase:The object store layer can now see all pending requests at once and optimize I/O through batching, connection multiplexing, and parallel fetches. The async tasks only await the already-in-flight I/O futures.
Changes
rust/lance-encoding/src/encodings/logical/primitive.rs:create_page_load_tasksignature to acceptBoxFuture<'static, Result<Vec<Bytes>>>instead ofFullZipReadSource+ byte ranges + priorityio.submit_request()calls to happen eagerly at both call sites (schedule_ranges_with_rep_indexand the non-rep-index path), before constructing the page load taskPerformance
Tested with a multi-fragment dataset containing fixed-width columns (768-dim float32 vectors, 40 fragments, 50 rows/fragment):
The improvement comes entirely from I/O pipelining — the decoding logic itself is unchanged. The effect is most pronounced with many fragments or pages, where the serialized I/O submission was the dominant bottleneck.