Sort offers by price within availability groups in _get_job_plan#3840
Open
megheaiulian wants to merge 1 commit intodstackai:masterfrom
Open
Sort offers by price within availability groups in _get_job_plan#3840megheaiulian wants to merge 1 commit intodstackai:masterfrom
megheaiulian wants to merge 1 commit intodstackai:masterfrom
Conversation
…ackai#3839) The sort in _get_job_plan only sorted by availability, preserving the input order from heapq.merge. Since backend offers are not guaranteed to be price-sorted (gpuhunt explicitly documents its results as 'not strictly sorted by the price'), cheap offers from one backend could be buried behind expensive offers from another. Add price as a secondary sort key so that available offers are sorted cheapest-first, matching the behavior of the dstack offer path which explicitly sorts by price in get_backend_offers_in_run_candidate_fleets.
f491338 to
ff46674
Compare
jvstme
reviewed
Apr 30, 2026
| if profile.creation_policy == CreationPolicy.REUSE_OR_CREATE: | ||
| job_offers.extend(offer for _, offer in backend_offers) | ||
| job_offers.sort(key=lambda offer: not offer.availability.is_available()) | ||
| job_offers.sort(key=lambda offer: (not offer.availability.is_available(), offer.price)) |
Collaborator
There was a problem hiding this comment.
If I'm not mistaken, sorting here:
- Only affects the run plan shown in
dstack apply, but doesn't affect the actual provisioning order. - Can shuffle the available
instance_offers(representing idle instances) andbackend_offers(representing new instances to be provisioned), which is not expected — idle instances should always come first regardless of the price, as dstack prefers reusing them over provisioning new ones.
Anyways, I'm not sure if we want to sort by price in the first place, please see my issue comment
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
Fixes #3839
_get_job_plan()sorted offers only by availability (not offer.availability.is_available()), preserving the input order fromheapq.merge. Since backend offers are not guaranteed to be price-sorted (gpuhunt explicitly documents its results as "not strictly sorted by the price"), cheap offers from one backend (e.g., Vast.ai at $0.37) could be buried behind expensive offers from another backend (e.g., RunPod at $0.98).This was the root cause of #3839:
dstack applyshowed RunPod offers ($0.98+) before cheaper Vast.ai offers ($0.37+), whiledstack offercorrectly sorted by price because it usesget_backend_offers_in_run_candidate_fleets()which explicitly sorts by price.Changes
plan.py:835: Addoffer.priceas secondary sort key so that within each availability group, offers are sorted cheapest-first:test_plan.py: AddTestGetJobPlanwith 5 tests:test_sorts_available_offers_by_price— available offers sorted by price even when input is out of ordertest_sorts_not_available_offers_by_price— NOT_AVAILABLE offers also sorted by pricetest_sorts_mixed_availability_by_availability_then_price— available group sorted by price, then NOT_AVAILABLE group sorted by price (inputs in reverse price order to verify sort, not just stable order)test_sorts_unsorted_multi_backend_offers_by_price— reproduces the bug: RunPod offers ($0.98, $1.49) before Vast.ai ($0.37, $1.22) in input, verifying price sort produces correct ordertest_instance_offers_and_backend_offers_sorted_by_availability_then_price— expensive IDLE pool instance ($0.98) sorts after cheap AVAILABLE backend offer ($0.37)How to test
Before: RunPod offers ($0.98+) appear before cheaper Vast.ai offers ($0.37+)
After: All offers sorted by price ascending within availability groups