Repository: kubernetes-sigs/kueue
Pull request #188 (2022-04-07 20:49:20)

Rename guaranteed to min and ceiling to max
#### What type of PR is this?

/kind cleanup
/kind api-change

#### What this PR does / why we need it:

The `guaranteed` and `ceiling` fields where named such for lack of better names.

`guranteed` is highly misleading, because without preemption and scheduler enforcement, we can't necessarily guarantee the quota. `min` seems less problematic. Then `max` makes more sense than `ceiling`.

#### Which issue(s) this PR fixes:
<!--
*Automatically closes linked issue when PR is merged.
Usage: `Fixes #<issue number>`, or `Fixes (paste link of issue)`.
_If PR is about `failing-tests or flakes`, please post the related issues/tests in a comment and do not use `Fixes`_*
-->
Fixes #

#### Special notes for your reviewer:



k8s-ci-robot: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/kubernetes-sigs/kueue/pull/188#" title="Author self-approved">alculquicondor</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=kubernetes-sigs%2Fkueue).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/kubernetes-sigs/kueue/blob/main/OWNERS)~~ [alculquicondor]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
alculquicondor: /assign @ahg-g 
/hold

Patch:
diff --git a/api/v1alpha1/clusterqueue_types.go b/api/v1alpha1/clusterqueue_types.go
index 40f77e28f..84a2ed970 100644
--- a/api/v1alpha1/clusterqueue_types.go
+++ b/api/v1alpha1/clusterqueue_types.go
@@ -32,11 +32,11 @@ type ClusterQueueSpec struct {
 	// - name: cpu
 	//   flavors:
 	//   - quota:
-	//       guaranteed: 100
+	//       min: 100
 	// - name: memory
 	//   flavors:
 	//   - quota:
-	//       guaranteed: 100Gi
+	//       min: 100Gi
 	//
 	// +listType=map
 	// +listMapKey=name
@@ -53,31 +53,17 @@ type ClusterQueueSpec struct {
 	// 1. tenantB can run a workload consuming up to 20 k80 GPUs, meaning a resource
 	//    can be allocated from more than one clusterQueue in a cohort.
 	// 2. tenantB can not consume any p100 GPUs or spot because its QC has no quota
-	//    defined for them, and so the ceiling is practically 0.
+	//    defined for them, and so the max is implicitly 0.
 	// 3. If both tenantA and tenantB are running jobs such that current usage for
-	//    tenantA is lower than its guaranteed quota (e.g., 5 k80 GPUS) while
-	//    tenantB’s usage is higher than its guaranteed quota (e.g., 12 k80 GPUs),
+	//    tenantA is lower than its min quota (e.g., 5 k80 GPUS) while
+	//    tenantB’s usage is higher than its min quota (e.g., 12 k80 GPUs),
 	//    and both tenants have pending jobs requesting the remaining clusterQueue of
 	//    the cohort (the 3 k80 GPUs), then tenantA jobs will get this remaining
-	//    clusterQueue since tenantA is below its guaranteed limit.
+	//    clusterQueue since tenantA is below its min limit.
 	// 4. If a tenantA workload doesn’t tolerate spot, then the workload will only
 	//    be eligible to consume on-demand cores (the next in the list of cpu flavors).
-	//
-	//  <UNRESOLVED>
-	// 5. While evaluating a resource flavor’s list, what should take precedence:
-	//    honoring the preferred order in the list or keeping a usage under the
-	//    guaranteed clusterQueue? For example, if tenantA’s current k80 usage is 10 and
-	//    tenantB’s usage is 5, should a future tenantA workload that asks for any
-	//    GPU model be assigned borrowed k80 clusterQueue (since it is ordered first in
-	//    the list) or p100 since its usage is under tenantA’s guaranteed limit?
-	//    The tradeoff is honoring tenantA’s preferred order vs honoring fair
-	//    sharing of future tenantB’s jobs in a timely manner (or, when we have
-	//    preemption, reduce the chance of preempting tenantA’s workload)
-	//
-	//    We could make that a user choice via a knob on the QC or Cohort if we
-	//    decide to have a dedicated object API for it and start with preferring to
-	//    consume guaranteed clusterQueue first.
-	//  </UNRESOLVED>
+	// 5. Before considering on-demand, the workload will get assigned spot if
+	//    the quota can be borrowed from the cohort.
 	//
 	// metadata:
 	//  name: tenantA
@@ -87,26 +73,21 @@ type ClusterQueueSpec struct {
 	// - name: cpu
 	//   - name: spot
 	//     quota:
-	//       guaranteed: 1000
-	//     labels
-	//     - cloud.provider.com/spot:true
-	//     taints
-	//     - key: cloud.provider.com/spot
-	//       effect: NoSchedule
+	//       min: 1000
 	//   - name: on-demand
 	//     quota:
-	//       guaranteed: 100
+	//       min: 100
 	// - name: nvidia.com/gpus
 	//   - name: k80
 	//     quota:
-	//       guaranteed: 10
-	//       ceiling: 20
+	//       min: 10
+	//       max: 20
 	//     labels:
 	//     - cloud.provider.com/accelerator: nvidia-tesla-k80
 	//   - name: p100
 	//     quota:
-	//       guaranteed: 10
-	//       ceiling: 20
+	//       min: 10
+	//       max: 20
 	//     labels:
 	//     - cloud.provider.com/accelerator: nvidia-tesla-p100
 	//
@@ -118,12 +99,12 @@ type ClusterQueueSpec struct {
 	// - name: cpu
 	//   - name: on-demand
 	//     quota:
-	//       guaranteed: 100
+	//       min: 100
 	// - name: nvidia.com/gpus
 	//   - name: k80
 	//     quota:
-	//       guaranteed: 10
-	//       ceiling: 20
+	//       min: 10
+	//       max: 20
 	//     labels:
 	//     - cloud.provider.com/accelerator: nvidia-tesla-k80
 	//
@@ -189,48 +170,17 @@ type Resource struct {
 	// - name: nvidia.com/gpus
 	//   - name: k80
 	//     quota:
-	//       guaranteed: 10
-	//     labels:
-	//       cloud.provider.com/accelerator: nvidia-tesla-k80
+	//       min: 10
 	//   - name: p100
 	//     quota:
-	//       guaranteed: 10
-	//     labels:
-	//       cloud.provider.com/accelerator: nvidia-tesla-p100
+	//       min: 10
 	//
 	// The flavors are evaluated in order, selecting the first to satisfy a
 	// workload’s requirements. Also the quantities are additive, in the example
 	// above the GPU quota in total is 20 (10 k80 + 10 p100).
 	// A workload is limited to the selected type by converting the labels to a node
-	// selector that gets injected into the workload. ​​This list can’t be empty, at
-	// least one must exist.
-	//
-	// Note that a workload’s node affinity/selector constraints are evaluated
-	// against the labels, and so batch users can “filter” the flavors, but can’t
-	// force a different order. For example, the following workload affinity will
-	// only start the workload if P100 quota is available:
-	//
-	// matchExpressions:
-	// - key: cloud.provider.com/accelerator
-	//   value: nvidia-tesla-p100
-	//
-	// Each type can also set taints so that it is opt-out by default.
-	// A workload’s tolerations are evaluated against those taints, and only the
-	// flavors that the workload tolerates are considered. For example, an admin
-	// may choose to taint Spot CPU clusterQueue, and if a workload doesn't tolerate it
-	// will only be eligible to consume on-demand clusterQueue:
-	//
-	// - name: spot
-	//   quota:
-	//     guaranteed: 1000
-	//   labels
-	//   - cloud.provider.com/spot:true
-	//   taints
-	//   - key: cloud.provider.com/spot
-	//     effect: NoSchedule
-	// - name: on-demand
-	//   quota:
-	//     guaranteed: 100
+	// selector that gets injected into the workload. This list can’t be empty, at
+	// least one flavor must exist.
 	//
 	// +listType=map
 	// +listMapKey=resourceFlavor
@@ -250,17 +200,19 @@ type Flavor struct {
 type ResourceFlavorReference string
 
 type Quota struct {
-	// guaranteed amount of resource requests that are available to be used by
-	// running workloads assigned to this quota. This value should not exceed
-	// the Ceiling. The sum of guaranteed values in a cohort defines the maximum
-	// clusterQueue that can be allocated for the cohort.
-	Guaranteed resource.Quantity `json:"guaranteed,omitempty"`
+	// min amount of resource requests that are available to be used by workloads
+	// admitted by this ClusterQueue at a point in time.
+	// The sum of min quotas for a flavor in a cohort defines the maximum amount
+	// of resources that can be allocated by a ClusterQueue in the cohort.
+	Min resource.Quantity `json:"min,omitempty"`
 
-	// ceiling is the upper limit on the amount of resource requests that
-	// could be used by running workloads assigned to this quota at a point in time.
-	// Resources can be borrowed from unused guaranteed quota of other
-	// ClusterQueues in the same cohort. When null, it is unlimited.
-	Ceiling *resource.Quantity `json:"ceiling,omitempty"`
+	// max is the upper limit on the amount of resource requests that
+	// can be used by workloads admitted by this ClusterQueue at a point in time.
+	// Resources can be borrowed from unused min quota of other
+	// ClusterQueues in the same cohort.
+	// If not null, it must be greater than or equal to min.
+	// If null, there is no upper limit for borrowing.
+	Max *resource.Quantity `json:"max,omitempty"`
 }
 
 // ClusterQueueStatus defines the observed state of ClusterQueue
@@ -288,8 +240,7 @@ type Usage struct {
 	// borrowed from the cohort.
 	Total *resource.Quantity `json:"total,omitempty"`
 
-	// Borrowed is the used quantity past the guaranteed quota, borrowed from
-	// the cohort.
+	// Borrowed is the used quantity past the min quota, borrowed from the cohort.
 	Borrowed *resource.Quantity `json:"borrowing,omitempty"`
 }
 
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index 56ee144e6..0b7bd0372 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -313,9 +313,9 @@ func (in *QueueStatus) DeepCopy() *QueueStatus {
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *Quota) DeepCopyInto(out *Quota) {
 	*out = *in
-	out.Guaranteed = in.Guaranteed.DeepCopy()
-	if in.Ceiling != nil {
-		in, out := &in.Ceiling, &out.Ceiling
+	out.Min = in.Min.DeepCopy()
+	if in.Max != nil {
+		in, out := &in.Max, &out.Max
 		x := (*in).DeepCopy()
 		*out = &x
 	}
diff --git a/config/crd/bases/kueue.x-k8s.io_clusterqueues.yaml b/config/crd/bases/kueue.x-k8s.io_clusterqueues.yaml
index 63c0db40d..a59ea3b07 100644
--- a/config/crd/bases/kueue.x-k8s.io_clusterqueues.yaml
+++ b/config/crd/bases/kueue.x-k8s.io_clusterqueues.yaml
@@ -64,43 +64,29 @@ spec:
                   tenantB can run a workload consuming up to 20 k80 GPUs, meaning
                   a resource can be allocated from more than one clusterQueue in a
                   cohort. 2. tenantB can not consume any p100 GPUs or spot because
-                  its QC has no quota defined for them, and so the ceiling is practically
+                  its QC has no quota defined for them, and so the max is implicitly
                   0. 3. If both tenantA and tenantB are running jobs such that current
-                  usage for tenantA is lower than its guaranteed quota (e.g., 5 k80
-                  GPUS) while tenantB’s usage is higher than its guaranteed quota
-                  (e.g., 12 k80 GPUs), and both tenants have pending jobs requesting
-                  the remaining clusterQueue of the cohort (the 3 k80 GPUs), then
-                  tenantA jobs will get this remaining clusterQueue since tenantA
-                  is below its guaranteed limit. 4. If a tenantA workload doesn’t
-                  tolerate spot, then the workload will only be eligible to consume
-                  on-demand cores (the next in the list of cpu flavors). \n <UNRESOLVED>
-                  5. While evaluating a resource flavor’s list, what should take precedence:
-                  honoring the preferred order in the list or keeping a usage under
-                  the guaranteed clusterQueue? For example, if tenantA’s current k80
-                  usage is 10 and tenantB’s usage is 5, should a future tenantA workload
-                  that asks for any GPU model be assigned borrowed k80 clusterQueue
-                  (since it is ordered first in the list) or p100 since its usage
-                  is under tenantA’s guaranteed limit? The tradeoff is honoring tenantA’s
-                  preferred order vs honoring fair sharing of future tenantB’s jobs
-                  in a timely manner (or, when we have preemption, reduce the chance
-                  of preempting tenantA’s workload) \n We could make that a user choice
-                  via a knob on the QC or Cohort if we decide to have a dedicated
-                  object API for it and start with preferring to consume guaranteed
-                  clusterQueue first. </UNRESOLVED> \n metadata: name: tenantA spec:
-                  cohort: borrowing-cohort requestableResources: - name: cpu - name:
-                  spot quota: guaranteed: 1000 labels - cloud.provider.com/spot:true
-                  taints - key: cloud.provider.com/spot effect: NoSchedule - name:
-                  on-demand quota: guaranteed: 100 - name: nvidia.com/gpus - name:
-                  k80 quota: guaranteed: 10 ceiling: 20 labels: - cloud.provider.com/accelerator:
-                  nvidia-tesla-k80 - name: p100 quota: guaranteed: 10 ceiling: 20
-                  labels: - cloud.provider.com/accelerator: nvidia-tesla-p100 \n metadata:
-                  name: tenantB spec: cohort: borrowing-cohort requestableResources:
-                  - name: cpu - name: on-demand quota: guaranteed: 100 - name: nvidia.com/gpus
-                  - name: k80 quota: guaranteed: 10 ceiling: 20 labels: - cloud.provider.com/accelerator:
-                  nvidia-tesla-k80 \n If empty, this ClusterQueue cannot borrow from
-                  any other ClusterQueue and vice versa. \n The name style is similar
-                  to label keys. These are just names to link QCs together, and they
-                  are meaningless otherwise."
+                  usage for tenantA is lower than its min quota (e.g., 5 k80 GPUS)
+                  while tenantB’s usage is higher than its min quota (e.g., 12 k80
+                  GPUs), and both tenants have pending jobs requesting the remaining
+                  clusterQueue of the cohort (the 3 k80 GPUs), then tenantA jobs will
+                  get this remaining clusterQueue since tenantA is below its min limit.
+                  4. If a tenantA workload doesn’t tolerate spot, then the workload
+                  will only be eligible to consume on-demand cores (the next in the
+                  list of cpu flavors). 5. Before considering on-demand, the workload
+                  will get assigned spot if the quota can be borrowed from the cohort.
+                  \n metadata: name: tenantA spec: cohort: borrowing-cohort requestableResources:
+                  - name: cpu - name: spot quota: min: 1000 - name: on-demand quota:
+                  min: 100 - name: nvidia.com/gpus - name: k80 quota: min: 10 max:
+                  20 labels: - cloud.provider.com/accelerator: nvidia-tesla-k80 -
+                  name: p100 quota: min: 10 max: 20 labels: - cloud.provider.com/accelerator:
+                  nvidia-tesla-p100 \n metadata: name: tenantB spec: cohort: borrowing-cohort
+                  requestableResources: - name: cpu - name: on-demand quota: min:
+                  100 - name: nvidia.com/gpus - name: k80 quota: min: 10 max: 20 labels:
+                  - cloud.provider.com/accelerator: nvidia-tesla-k80 \n If empty,
+                  this ClusterQueue cannot borrow from any other ClusterQueue and
+                  vice versa. \n The name style is similar to label keys. These are
+                  just names to link QCs together, and they are meaningless otherwise."
                 type: string
               namespaceSelector:
                 description: namespaceSelector defines which namespaces are allowed
@@ -170,8 +156,8 @@ spec:
                   of workloads dispatched via this clusterQueue. This doesn’t guarantee
                   the actual availability of resources, although an integration with
                   a resource provisioner like Cluster Autoscaler is possible to achieve
-                  that. Example: \n - name: cpu flavors: - quota: guaranteed: 100
-                  - name: memory flavors: - quota: guaranteed: 100Gi"
+                  that. Example: \n - name: cpu flavors: - quota: min: 100 - name:
+                  memory flavors: - quota: min: 100Gi"
                 items:
                   properties:
                     flavors:
@@ -184,58 +170,43 @@ spec:
                         want to define different limits for different gpu models,
                         then each model is mapped to a flavor and must set different
                         values of a shared key. For example: \n spec: requestableResources:
-                        - name: nvidia.com/gpus - name: k80 quota: guaranteed: 10
-                        labels: cloud.provider.com/accelerator: nvidia-tesla-k80 -
-                        name: p100 quota: guaranteed: 10 labels: cloud.provider.com/accelerator:
-                        nvidia-tesla-p100 \n The flavors are evaluated in order, selecting
-                        the first to satisfy a workload’s requirements. Also the quantities
-                        are additive, in the example above the GPU quota in total
-                        is 20 (10 k80 + 10 p100). A workload is limited to the selected
-                        type by converting the labels to a node selector that gets
-                        injected into the workload. ​​This list can’t be empty, at
-                        least one must exist. \n Note that a workload’s node affinity/selector
-                        constraints are evaluated against the labels, and so batch
-                        users can “filter” the flavors, but can’t force a different
-                        order. For example, the following workload affinity will only
-                        start the workload if P100 quota is available: \n matchExpressions:
-                        - key: cloud.provider.com/accelerator value: nvidia-tesla-p100
-                        \n Each type can also set taints so that it is opt-out by
-                        default. A workload’s tolerations are evaluated against those
-                        taints, and only the flavors that the workload tolerates are
-                        considered. For example, an admin may choose to taint Spot
-                        CPU clusterQueue, and if a workload doesn't tolerate it will
-                        only be eligible to consume on-demand clusterQueue: \n - name:
-                        spot quota: guaranteed: 1000 labels - cloud.provider.com/spot:true
-                        taints - key: cloud.provider.com/spot effect: NoSchedule -
-                        name: on-demand quota: guaranteed: 100"
+                        - name: nvidia.com/gpus - name: k80 quota: min: 10 - name:
+                        p100 quota: min: 10 \n The flavors are evaluated in order,
+                        selecting the first to satisfy a workload’s requirements.
+                        Also the quantities are additive, in the example above the
+                        GPU quota in total is 20 (10 k80 + 10 p100). A workload is
+                        limited to the selected type by converting the labels to a
+                        node selector that gets injected into the workload. This list
+                        can’t be empty, at least one flavor must exist."
                       items:
                         properties:
                           quota:
                             description: quota is the limit of resource usage at a
                               point in time.
                             properties:
-                              ceiling:
+                              max:
                                 anyOf:
                                 - type: integer
                                 - type: string
-                                description: ceiling is the upper limit on the amount
-                                  of resource requests that could be used by running
-                                  workloads assigned to this quota at a point in time.
-                                  Resources can be borrowed from unused guaranteed
-                                  quota of other ClusterQueues in the same cohort.
-                                  When null, it is unlimited.
+                                description: max is the upper limit on the amount
+                                  of resource requests that can be used by workloads
+                                  admitted by this ClusterQueue at a point in time.
+                                  Resources can be borrowed from unused min quota
+                                  of other ClusterQueues in the same cohort. If not
+                                  null, it must be greater than or equal to min. If
+                                  null, there is no upper limit for borrowing.
                                 pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
                                 x-kubernetes-int-or-string: true
-                              guaranteed:
+                              min:
                                 anyOf:
                                 - type: integer
                                 - type: string
-                                description: guaranteed amount of resource requests
-                                  that are available to be used by running workloads
-                                  assigned to this quota. This value should not exceed
-                                  the Ceiling. The sum of guaranteed values in a cohort
-                                  defines the maximum clusterQueue that can be allocated
-                                  for the cohort.
+                                description: min amount of resource requests that
+                                  are available to be used by workloads admitted by
+                                  this ClusterQueue at a point in time. The sum of
+                                  min quotas for a flavor in a cohort defines the
+                                  maximum amount of resources that can be allocated
+                                  by a ClusterQueue in the cohort.
                                 pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
                                 x-kubernetes-int-or-string: true
                             type: object
@@ -285,8 +256,8 @@ spec:
                         anyOf:
                         - type: integer
                         - type: string
-                        description: Borrowed is the used quantity past the guaranteed
-                          quota, borrowed from the cohort.
+                        description: Borrowed is the used quantity past the min quota,
+                          borrowed from the cohort.
                         pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
                         x-kubernetes-int-or-string: true
                       total:
diff --git a/config/samples/single-clusterqueue-setup.yaml b/config/samples/single-clusterqueue-setup.yaml
index 0d0a1b902..7b11c8988 100644
--- a/config/samples/single-clusterqueue-setup.yaml
+++ b/config/samples/single-clusterqueue-setup.yaml
@@ -14,12 +14,12 @@ spec:
     flavors:
     - resourceFlavor: default
       quota:
-        guaranteed: 9
+        min: 9
   - name: "memory"
     flavors:
     - resourceFlavor: default
       quota:
-        guaranteed: 36Gi
+        min: 36Gi
 ---
 apiVersion: kueue.x-k8s.io/v1alpha1
 kind: Queue
diff --git a/docs/concepts/cluster_queue.md b/docs/concepts/cluster_queue.md
index e62d78383..5e94b676b 100644
--- a/docs/concepts/cluster_queue.md
+++ b/docs/concepts/cluster_queue.md
@@ -21,12 +21,12 @@ spec:
     flavors:
     - resourceFlavor: default
       quota:
-        guaranteed: 9
+        min: 9
   - name: "memory"
     flavors:
     - resourceFlavor: default
       quota:
-        guaranteed: 36Gi
+        min: 36Gi
 ```
 
 This ClusterQueue admits [workloads](workload.md) if and only if:
@@ -177,9 +177,10 @@ When borrowing, Kueue satisfies the following semantics:
 
 - When assigning flavors, Kueue goes through the list of flavors in
   `.spec.requestableResources[*].flavors`. For each flavor, Kueue attempts to
-  fit the workload using the guaranteed quota of the ClusterQueue or the unused
-  quota in the cohort. If the workload doesn't fit, Kueue proceeds evaluating
-  the next flavor in the list.
+  fit the workload using the min quota of the ClusterQueue or the unused
+  min quota of other ClusterQueues in the cohort, up to the max quota of the
+  ClusterQueue. If the workload doesn't fit, Kueue proceeds evaluating the next
+  flavor in the list.
 - Borrowing happens per-flavor. A ClusterQueue can only borrow quota of flavors
   it defines.
 
@@ -200,12 +201,12 @@ spec:
     flavors:
     - resourceFlavor: default
       quota:
-        guaranteed: 9
+        min: 9
   - name: "memory"
     flavors:
     - resourceFlavor: default
       quota:
-        guaranteed: 36Gi
+        min: 36Gi
 ```
 
 ```yaml
@@ -221,12 +222,12 @@ spec:
     flavors:
     - resourceFlavor: default
       quota:
-        guaranteed: 12
+        min: 12
   - name: "memory"
     flavors:
     - resourceFlavor: default
       quota:
-        guaranteed: 48Gi
+        min: 48Gi
 ```
 
 ClusterQueue `team-a-cq` can admit workloads depending on the following
@@ -236,22 +237,22 @@ scenarios:
   `team-a-cq` can admit workloads with resources adding up to `12+9=21` CPUs and
   `48+36=84Gi` of memory.
 - If ClusterQueue `team-b-cq` has pending workloads and the ClusterQueue
-  `team-a-cq` has all its `guaranteed` quota used, Kueue will admit workloads in
+  `team-a-cq` has all its `min` quota used, Kueue will admit workloads in
   ClusterQueue `team-b-cq` before admitting any new workloads in `team-a-cq`.
-  Therefore, Kueue ensures the `guaranteed` quota for `team-b-cq` is met.
+  Therefore, Kueue ensures the `min` quota for `team-b-cq` is met.
 
 **Note**: Kueue [does not support preemption](https://github.com/kubernetes-sigs/kueue/issues/83).
 No admitted workloads will be stopped to make space for new workloads.
 
-### Ceilings
+### Max quotas
 
 To limit the amount of resources that a ClusterQueue can borrow from others,
-you can set the `.spec.requestableResources[*].flavors[*].quota.ceiling`
+you can set the `.spec.requestableResources[*].flavors[*].quota.max`
 [quantity](https://kubernetes.io/docs/reference/kubernetes-api/common-definitions/quantity/) field.
-The `ceiling` must be greater than or equal to `guaranteed`.
+`max` must be greater than or equal to `min`.
 
-If, for a given flavor, the `ceiling` field is empty or null, a ClusterQueue can
-borrow the sum of the guaranteed quotas in all the ClusterQueues in the cohort.
+If, for a given flavor, the `max` field is empty or null, a ClusterQueue can
+borrow up to the sum of min quotas from all the ClusterQueues in the cohort.
 
 ## What's next?
 
diff --git a/docs/tasks/administer_cluster_quotas.md b/docs/tasks/administer_cluster_quotas.md
index 5741d791d..22ead4eab 100644
--- a/docs/tasks/administer_cluster_quotas.md
+++ b/docs/tasks/administer_cluster_quotas.md
@@ -45,12 +45,12 @@ spec:
     flavors:
     - resourceFlavor: default
       quota:
-        guaranteed: 9
+        min: 9
   - name: "memory"
     flavors:
     - resourceFlavor: default
       quota:
-        guaranteed: 36Gi
+        min: 36Gi
 ```
 
 To create the ClusterQueue, run the following command:
@@ -61,7 +61,7 @@ kubectl apply -f cluster-total.yaml
 
 This ClusterQueue governs the usage of [resource types](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#resource-types)
 `cpu` and `memory`. Each resource type has a single [resource flavor](/docs/concepts/cluster_queue.md#resourceflavor-object),
-named `default` with a guaranteed quota.
+named `default` with a min quota.
 
 The empty `namespaceSelector` allows any namespace to use these resources.
 
@@ -186,15 +186,15 @@ spec:
     flavors:
     - resourceFlavor: x86
       quota:
-        guaranteed: 9
+        min: 9
     - resourceFlavor: arm
       quota:
-        guaranteed: 12
+        min: 12
   - name: "memory"
     flavors:
     - resourceFlavor: default
       quota:
-        guaranteed: 84Gi
+        min: 84Gi
 ```
 
 The flavor names in the fields `.spec.requestableResources[*].flavors[*].resourceFlavor`
@@ -232,14 +232,14 @@ spec:
     flavors:
     - resourceFlavor: default
       quota:
-        guaranteed: 9
-        ceiling: 15
+        min: 9
+        max: 15
   - name: "memory"
     flavors:
     - resourceFlavor: default
       quota:
-        guaranteed: 36Gi
-        ceiling: 60Gi
+        min: 36Gi
+        max: 60Gi
 ```
 
 ```yaml
@@ -256,17 +256,17 @@ spec:
     flavors:
     - resourceFlavor: default
       quota:
-        guaranteed: 12
+        min: 12
   - name: "memory"
     flavors:
     - resourceFlavor: default
       quota:
-        guaranteed: 48Gi
+        min: 48Gi
 ```
 
-Note that the ClusterQueue `team-a-cq` also defines [ceilings](/docs/concepts/cluster_queue.md#ceilings).
+Note that the ClusterQueue `team-a-cq` also defines [max quotas](/docs/concepts/cluster_queue.md#max-quotas).
 This restricts the ability of the ClusterQueue to borrow the unused quota from
-the cohort up to the configured ceiling, even if the quota is completely unused.
+the cohort up to the configured `max`, even if the quota is completely unused.
 
 To create these ClusterQueues, save the preceding manifests and run the
 following command:
@@ -278,9 +278,9 @@ kubectl apply -f team-a-cq.yaml -f team-b-cq.yaml
 ## Multiple ClusterQueue with dedicated and fallback flavors
 
 A ClusterQueue can borrow resources from the [cohort](/docs/concepts/cluster_queue.md#cohort)
-even if the ClusterQueue has zero guaranteed quota for a flavor. This allows you
-to give dedicated quota for a flavor and fallback to quota for a different
-flavor, shared with other tenants.
+even if the ClusterQueue has zero min quota for a flavor. This allows you to
+give dedicated quota for a flavor and fallback to quota for a different flavor,
+shared with other tenants.
 
 Such setup can be accomplished with a ClusterQueue for each tenant and an extra
 ClusterQueue for the shared resources. For example, the manifests for two
@@ -300,16 +300,16 @@ spec:
     flavors:
     - resourceFlavor: arm
       quota:
-        guaranteed: 9
-        ceiling: 9
+        min: 9
+        max: 9
     - resourceFlavor: x86
       quota:
-        guaranteed: 0
+        min: 0
   - name: "memory"
     flavors:
     - resourceFlavor: default
       quota:
-        guaranteed: 36Gi
+        min: 36Gi
 ```
 
 ```yaml
@@ -326,15 +326,15 @@ spec:
     flavors:
     - resourceFlavor: arm
       quota:
-        guaranteed: 12
+        min: 12
     - resourceFlavor: x86
       quota:
-        guaranteed: 0
+        min: 0
   - name: "memory"
     flavors:
     - resourceFlavor: default
       quota:
-        guaranteed: 48Gi
+        min: 48Gi
 ```
 
 ```yaml
@@ -351,20 +351,20 @@ spec:
     flavors:
     - resourceFlavor: x86
       quota:
-        guaranteed: 6
+        min: 6
   - name: "memory"
     flavors:
     - resourceFlavor: default
       quota:
-        guaranteed: 24Gi
+        min: 24Gi
 ```
 
 Note the following setup:
 
-- `team-a-cq` and `team-b-cq` define a `ceiling` equal to their `guaranteed`
+- `team-a-cq` and `team-b-cq` define a `max` equal to their `min`
   quota for the `arm` flavor. Therefore, they can't borrow this flavor from each
   other.
-- `team-a-cq` and `team-b-cq` define `guaranteed: 0` for the `x86` flavor.
+- `team-a-cq` and `team-b-cq` define `min: 0` for the `x86` flavor.
   Therefore, they don't have any dedicated quota for the flavor and they can
   only borrow it from `shared-cq`.
 
diff --git a/pkg/cache/cache.go b/pkg/cache/cache.go
index 7c0b3e80e..5f89110d5 100644
--- a/pkg/cache/cache.go
+++ b/pkg/cache/cache.go
@@ -94,9 +94,9 @@ type ClusterQueue struct {
 
 // FlavorLimits holds a processed ClusterQueue flavor quota.
 type FlavorLimits struct {
-	Name       string
-	Guaranteed int64
-	Ceiling    *int64
+	Name string
+	Min  int64
+	Max  *int64
 }
 
 func (c *Cache) newClusterQueue(cq *kueue.ClusterQueue) (*ClusterQueue, error) {
@@ -413,7 +413,7 @@ func (c *Cache) Usage(cqObj *kueue.ClusterQueue) (kueue.UsedResources, int, erro
 			fUsage := kueue.Usage{
 				Total: pointer.Quantity(workload.ResourceQuantity(rName, used)),
 			}
-			borrowing := used - flavor.Guaranteed
+			borrowing := used - flavor.Min
 			if borrowing > 0 {
 				fUsage.Borrowed = pointer.Quantity(workload.ResourceQuantity(rName, borrowing))
 			}
@@ -470,11 +470,11 @@ func resourceLimitsByName(in []kueue.Resource) map[corev1.ResourceName][]FlavorL
 		for i := range flavors {
 			f := &r.Flavors[i]
 			fLimits := FlavorLimits{
-				Name:       string(f.ResourceFlavor),
-				Guaranteed: workload.ResourceValue(r.Name, f.Quota.Guaranteed),
+				Name: string(f.ResourceFlavor),
+				Min:  workload.ResourceValue(r.Name, f.Quota.Min),
 			}
-			if f.Quota.Ceiling != nil {
-				fLimits.Ceiling = pointer.Int64(workload.ResourceValue(r.Name, *f.Quota.Ceiling))
+			if f.Quota.Max != nil {
+				fLimits.Max = pointer.Int64(workload.ResourceValue(r.Name, *f.Quota.Max))
 			}
 			flavors[i] = fLimits
 
diff --git a/pkg/cache/snapshot.go b/pkg/cache/snapshot.go
index 1c3d6aa7b..7808ec70c 100644
--- a/pkg/cache/snapshot.go
+++ b/pkg/cache/snapshot.go
@@ -89,7 +89,7 @@ func (c *ClusterQueue) accumulateResources(cohort *Cohort) {
 			cohort.RequestableResources[name] = req
 		}
 		for _, flavor := range flavors {
-			req[flavor.Name] += flavor.Guaranteed
+			req[flavor.Name] += flavor.Min
 		}
 	}
 	if cohort.UsedResources == nil {
diff --git a/pkg/scheduler/scheduler.go b/pkg/scheduler/scheduler.go
index 8040b2d1a..f00157e8d 100644
--- a/pkg/scheduler/scheduler.go
+++ b/pkg/scheduler/scheduler.go
@@ -375,17 +375,17 @@ func flavorSelector(spec *corev1.PodSpec, allowedKeys sets.String) nodeaffinity.
 // If it fits, also returns any borrowing required.
 func fitsFlavorLimits(name corev1.ResourceName, val int64, cq *cache.ClusterQueue, flavor *cache.FlavorLimits) (bool, int64) {
 	used := cq.UsedResources[name][flavor.Name]
-	if flavor.Ceiling != nil && used+val > *flavor.Ceiling {
+	if flavor.Max != nil && used+val > *flavor.Max {
 		// Past borrowing limit.
 		return false, 0
 	}
 	cohortUsed := used
-	cohortTotal := flavor.Guaranteed
+	cohortTotal := flavor.Min
 	if cq.Cohort != nil {
 		cohortUsed = cq.Cohort.UsedResources[name][flavor.Name]
 		cohortTotal = cq.Cohort.RequestableResources[name][flavor.Name]
 	}
-	borrow := used + val - flavor.Guaranteed
+	borrow := used + val - flavor.Min
 	if borrow < 0 {
 		borrow = 0
 	}
@@ -408,18 +408,18 @@ func (e entryOrdering) Swap(i, j int) {
 }
 
 // Less is the ordering criteria:
-// 1. guaranteed before borrowing.
+// 1. request under min quota before borrowing.
 // 2. FIFO on creation timestamp.
 func (e entryOrdering) Less(i, j int) bool {
 	a := e[i]
 	b := e[j]
-	// 1. Prefer guaranteed (not borrowing)
-	aGuaranteed := len(a.borrows) == 0
-	bGuaranteed := len(b.borrows) == 0
-	if aGuaranteed != bGuaranteed {
-		return aGuaranteed
+	// 1. Request under min quota.
+	aMin := len(a.borrows) == 0
+	bMin := len(b.borrows) == 0
+	if aMin != bMin {
+		return aMin
 	}
-	// 2. FIFO
+	// 2. FIFO.
 	return a.Obj.CreationTimestamp.Before(&b.Obj.CreationTimestamp)
 }
 


Test patch:
diff --git a/pkg/cache/cache_test.go b/pkg/cache/cache_test.go
index 15fcae135..626d2c25f 100644
--- a/pkg/cache/cache_test.go
+++ b/pkg/cache/cache_test.go
@@ -48,8 +48,8 @@ func TestCacheClusterQueueOperations(t *testing.T) {
 						Flavors: []kueue.Flavor{{
 							ResourceFlavor: "default",
 							Quota: kueue.Quota{
-								Guaranteed: resource.MustParse("10"),
-								Ceiling:    pointer.Quantity(resource.MustParse("20")),
+								Min: resource.MustParse("10"),
+								Max: pointer.Quantity(resource.MustParse("20")),
 							},
 						}},
 					},
@@ -66,7 +66,7 @@ func TestCacheClusterQueueOperations(t *testing.T) {
 						Flavors: []kueue.Flavor{{
 							ResourceFlavor: "default",
 							Quota: kueue.Quota{
-								Guaranteed: resource.MustParse("15"),
+								Min: resource.MustParse("15"),
 							},
 						}},
 					},
@@ -112,7 +112,7 @@ func TestCacheClusterQueueOperations(t *testing.T) {
 				"a": {
 					Name: "a",
 					RequestableResources: map[corev1.ResourceName][]FlavorLimits{
-						corev1.ResourceCPU: {{Name: "default", Guaranteed: 10000, Ceiling: pointer.Int64(20000)}},
+						corev1.ResourceCPU: {{Name: "default", Min: 10000, Max: pointer.Int64(20000)}},
 					},
 					NamespaceSelector: labels.Nothing(),
 					LabelKeys:         map[corev1.ResourceName]sets.String{corev1.ResourceCPU: sets.NewString("cpuType")},
@@ -121,7 +121,7 @@ func TestCacheClusterQueueOperations(t *testing.T) {
 				"b": {
 					Name: "b",
 					RequestableResources: map[corev1.ResourceName][]FlavorLimits{
-						corev1.ResourceCPU: {{Name: "default", Guaranteed: 15000}},
+						corev1.ResourceCPU: {{Name: "default", Min: 15000}},
 					},
 					NamespaceSelector: labels.Nothing(),
 					UsedResources:     Resources{corev1.ResourceCPU: {"default": 0}},
@@ -162,7 +162,7 @@ func TestCacheClusterQueueOperations(t *testing.T) {
 				"a": {
 					Name: "a",
 					RequestableResources: map[corev1.ResourceName][]FlavorLimits{
-						corev1.ResourceCPU: {{Name: "default", Guaranteed: 10000, Ceiling: pointer.Int64(20000)}},
+						corev1.ResourceCPU: {{Name: "default", Min: 10000, Max: pointer.Int64(20000)}},
 					},
 					NamespaceSelector: labels.Nothing(),
 					LabelKeys:         map[corev1.ResourceName]sets.String{corev1.ResourceCPU: sets.NewString("cpuType")},
@@ -171,7 +171,7 @@ func TestCacheClusterQueueOperations(t *testing.T) {
 				"b": {
 					Name: "b",
 					RequestableResources: map[corev1.ResourceName][]FlavorLimits{
-						corev1.ResourceCPU: {{Name: "default", Guaranteed: 15000}},
+						corev1.ResourceCPU: {{Name: "default", Min: 15000}},
 					},
 					NamespaceSelector: labels.Nothing(),
 					UsedResources:     Resources{corev1.ResourceCPU: {"default": 0}},
@@ -210,8 +210,8 @@ func TestCacheClusterQueueOperations(t *testing.T) {
 										{
 											ResourceFlavor: "default",
 											Quota: kueue.Quota{
-												Guaranteed: resource.MustParse("5"),
-												Ceiling:    pointer.Quantity(resource.MustParse("10")),
+												Min: resource.MustParse("5"),
+												Max: pointer.Quantity(resource.MustParse("10")),
 											},
 										},
 									},
@@ -242,7 +242,7 @@ func TestCacheClusterQueueOperations(t *testing.T) {
 				"a": {
 					Name: "a",
 					RequestableResources: map[corev1.ResourceName][]FlavorLimits{
-						corev1.ResourceCPU: {{Name: "default", Guaranteed: 5000, Ceiling: pointer.Int64(10000)}},
+						corev1.ResourceCPU: {{Name: "default", Min: 5000, Max: pointer.Int64(10000)}},
 					},
 					NamespaceSelector: labels.Nothing(),
 					LabelKeys:         map[corev1.ResourceName]sets.String{corev1.ResourceCPU: sets.NewString("cpuType", "region")},
@@ -288,7 +288,7 @@ func TestCacheClusterQueueOperations(t *testing.T) {
 				"b": {
 					Name: "b",
 					RequestableResources: map[corev1.ResourceName][]FlavorLimits{
-						corev1.ResourceCPU: {{Name: "default", Guaranteed: 15000}},
+						corev1.ResourceCPU: {{Name: "default", Min: 15000}},
 					},
 					NamespaceSelector: labels.Nothing(),
 					UsedResources:     Resources{corev1.ResourceCPU: {"default": 0}},
@@ -803,8 +803,8 @@ func TestClusterQueueUsage(t *testing.T) {
 						{
 							ResourceFlavor: "default",
 							Quota: kueue.Quota{
-								Guaranteed: resource.MustParse("10"),
-								Ceiling:    pointer.Quantity(resource.MustParse("20")),
+								Min: resource.MustParse("10"),
+								Max: pointer.Quantity(resource.MustParse("20")),
 							},
 						},
 					},
@@ -815,15 +815,15 @@ func TestClusterQueueUsage(t *testing.T) {
 						{
 							ResourceFlavor: "model_a",
 							Quota: kueue.Quota{
-								Guaranteed: resource.MustParse("5"),
-								Ceiling:    pointer.Quantity(resource.MustParse("10")),
+								Min: resource.MustParse("5"),
+								Max: pointer.Quantity(resource.MustParse("10")),
 							},
 						},
 						{
 							ResourceFlavor: "model_b",
 							Quota: kueue.Quota{
-								Guaranteed: resource.MustParse("5"),
-								// No ceiling.
+								Min: resource.MustParse("5"),
+								// No max.
 							},
 						},
 					},
diff --git a/pkg/cache/snapshot_test.go b/pkg/cache/snapshot_test.go
index 55fceb6f0..7de795e2c 100644
--- a/pkg/cache/snapshot_test.go
+++ b/pkg/cache/snapshot_test.go
@@ -55,13 +55,13 @@ func TestSnapshot(t *testing.T) {
 							{
 								ResourceFlavor: "demand",
 								Quota: kueue.Quota{
-									Guaranteed: resource.MustParse("100"),
+									Min: resource.MustParse("100"),
 								},
 							},
 							{
 								ResourceFlavor: "spot",
 								Quota: kueue.Quota{
-									Guaranteed: resource.MustParse("200"),
+									Min: resource.MustParse("200"),
 								},
 							},
 						},
@@ -82,7 +82,7 @@ func TestSnapshot(t *testing.T) {
 							{
 								ResourceFlavor: "spot",
 								Quota: kueue.Quota{
-									Guaranteed: resource.MustParse("100"),
+									Min: resource.MustParse("100"),
 								},
 							},
 						},
@@ -93,7 +93,7 @@ func TestSnapshot(t *testing.T) {
 							{
 								ResourceFlavor: "default",
 								Quota: kueue.Quota{
-									Guaranteed: resource.MustParse("50"),
+									Min: resource.MustParse("50"),
 								},
 							},
 						},
@@ -113,7 +113,7 @@ func TestSnapshot(t *testing.T) {
 							{
 								ResourceFlavor: "default",
 								Quota: kueue.Quota{
-									Guaranteed: resource.MustParse("100"),
+									Min: resource.MustParse("100"),
 								},
 							},
 						},
@@ -258,12 +258,12 @@ func TestSnapshot(t *testing.T) {
 				RequestableResources: map[corev1.ResourceName][]FlavorLimits{
 					corev1.ResourceCPU: {
 						{
-							Name:       "demand",
-							Guaranteed: 100_000,
+							Name: "demand",
+							Min:  100_000,
 						},
 						{
-							Name:       "spot",
-							Guaranteed: 200_000,
+							Name: "spot",
+							Min:  200_000,
 						},
 					},
 				},
@@ -285,14 +285,14 @@ func TestSnapshot(t *testing.T) {
 				RequestableResources: map[corev1.ResourceName][]FlavorLimits{
 					corev1.ResourceCPU: {
 						{
-							Name:       "spot",
-							Guaranteed: 100_000,
+							Name: "spot",
+							Min:  100_000,
 						},
 					},
 					"example.com/gpu": {
 						{
-							Name:       "default",
-							Guaranteed: 50,
+							Name: "default",
+							Min:  50,
 						},
 					},
 				},
@@ -316,8 +316,8 @@ func TestSnapshot(t *testing.T) {
 				RequestableResources: map[corev1.ResourceName][]FlavorLimits{
 					corev1.ResourceCPU: {
 						{
-							Name:       "default",
-							Guaranteed: 100_000,
+							Name: "default",
+							Min:  100_000,
 						},
 					},
 				},
diff --git a/pkg/scheduler/scheduler_test.go b/pkg/scheduler/scheduler_test.go
index 741c965dc..a445bd5fe 100644
--- a/pkg/scheduler/scheduler_test.go
+++ b/pkg/scheduler/scheduler_test.go
@@ -77,8 +77,8 @@ func TestSchedule(t *testing.T) {
 							{
 								ResourceFlavor: "default",
 								Quota: kueue.Quota{
-									Guaranteed: resource.MustParse("50"),
-									Ceiling:    pointer.Quantity(resource.MustParse("50")),
+									Min: resource.MustParse("50"),
+									Max: pointer.Quantity(resource.MustParse("50")),
 								},
 							},
 						},
@@ -107,15 +107,15 @@ func TestSchedule(t *testing.T) {
 							{
 								ResourceFlavor: "on-demand",
 								Quota: kueue.Quota{
-									Guaranteed: resource.MustParse("50"),
-									Ceiling:    pointer.Quantity(resource.MustParse("100")),
+									Min: resource.MustParse("50"),
+									Max: pointer.Quantity(resource.MustParse("100")),
 								},
 							},
 							{
 								ResourceFlavor: "spot",
 								Quota: kueue.Quota{
-									Guaranteed: resource.MustParse("100"),
-									Ceiling:    pointer.Quantity(resource.MustParse("100")),
+									Min: resource.MustParse("100"),
+									Max: pointer.Quantity(resource.MustParse("100")),
 								},
 							},
 						},
@@ -144,15 +144,15 @@ func TestSchedule(t *testing.T) {
 							{
 								ResourceFlavor: "on-demand",
 								Quota: kueue.Quota{
-									Guaranteed: resource.MustParse("50"),
-									Ceiling:    pointer.Quantity(resource.MustParse("60")),
+									Min: resource.MustParse("50"),
+									Max: pointer.Quantity(resource.MustParse("60")),
 								},
 							},
 							{
 								ResourceFlavor: "spot",
 								Quota: kueue.Quota{
-									Guaranteed: resource.MustParse("0"),
-									Ceiling:    pointer.Quantity(resource.MustParse("100")),
+									Min: resource.MustParse("0"),
+									Max: pointer.Quantity(resource.MustParse("100")),
 								},
 							},
 						},
@@ -163,8 +163,8 @@ func TestSchedule(t *testing.T) {
 							{
 								ResourceFlavor: "model-a",
 								Quota: kueue.Quota{
-									Guaranteed: resource.MustParse("20"),
-									Ceiling:    pointer.Quantity(resource.MustParse("20")),
+									Min: resource.MustParse("20"),
+									Max: pointer.Quantity(resource.MustParse("20")),
 								},
 							},
 						},
@@ -843,8 +843,8 @@ func TestEntryAssignFlavors(t *testing.T) {
 			},
 			clusterQueue: cache.ClusterQueue{
 				RequestableResources: map[corev1.ResourceName][]cache.FlavorLimits{
-					corev1.ResourceCPU:    {{Name: "default", Guaranteed: 1000}},
-					corev1.ResourceMemory: {{Name: "default", Guaranteed: 2 * utiltesting.Mi}},
+					corev1.ResourceCPU:    {{Name: "default", Min: 1000}},
+					corev1.ResourceMemory: {{Name: "default", Min: 2 * utiltesting.Mi}},
 				},
 			},
 			wantFits: true,
@@ -880,7 +880,7 @@ func TestEntryAssignFlavors(t *testing.T) {
 			clusterQueue: cache.ClusterQueue{
 				RequestableResources: map[corev1.ResourceName][]cache.FlavorLimits{
 					corev1.ResourceCPU: {
-						{Name: "tainted", Guaranteed: 4000},
+						{Name: "tainted", Min: 4000},
 					},
 				},
 			},
@@ -903,7 +903,7 @@ func TestEntryAssignFlavors(t *testing.T) {
 			},
 			clusterQueue: cache.ClusterQueue{
 				RequestableResources: map[corev1.ResourceName][]cache.FlavorLimits{
-					corev1.ResourceCPU: {{Name: "default", Guaranteed: 4000}},
+					corev1.ResourceCPU: {{Name: "default", Min: 4000}},
 				},
 				UsedResources: cache.Resources{
 					corev1.ResourceCPU: {
@@ -926,12 +926,12 @@ func TestEntryAssignFlavors(t *testing.T) {
 			clusterQueue: cache.ClusterQueue{
 				RequestableResources: map[corev1.ResourceName][]cache.FlavorLimits{
 					corev1.ResourceCPU: {
-						{Name: "one", Guaranteed: 2000},
-						{Name: "two", Guaranteed: 4000},
+						{Name: "one", Min: 2000},
+						{Name: "two", Min: 4000},
 					},
 					corev1.ResourceMemory: {
-						{Name: "one", Guaranteed: utiltesting.Gi},
-						{Name: "two", Guaranteed: 5 * utiltesting.Mi},
+						{Name: "one", Min: utiltesting.Gi},
+						{Name: "two", Min: 5 * utiltesting.Mi},
 					},
 				},
 			},
@@ -957,12 +957,12 @@ func TestEntryAssignFlavors(t *testing.T) {
 			clusterQueue: cache.ClusterQueue{
 				RequestableResources: map[corev1.ResourceName][]cache.FlavorLimits{
 					corev1.ResourceCPU: {
-						{Name: "one", Guaranteed: 2000},
-						{Name: "two", Guaranteed: 4000},
+						{Name: "one", Min: 2000},
+						{Name: "two", Min: 4000},
 					},
 					corev1.ResourceMemory: {
-						{Name: "one", Guaranteed: utiltesting.Gi},
-						{Name: "two", Guaranteed: 5 * utiltesting.Mi},
+						{Name: "one", Min: utiltesting.Gi},
+						{Name: "two", Min: 5 * utiltesting.Mi},
 					},
 				},
 			},
@@ -980,8 +980,8 @@ func TestEntryAssignFlavors(t *testing.T) {
 			clusterQueue: cache.ClusterQueue{
 				RequestableResources: map[corev1.ResourceName][]cache.FlavorLimits{
 					corev1.ResourceCPU: {
-						{Name: "tainted", Guaranteed: 4000},
-						{Name: "two", Guaranteed: 4000},
+						{Name: "tainted", Min: 4000},
+						{Name: "two", Min: 4000},
 					},
 				},
 			},
@@ -1005,8 +1005,8 @@ func TestEntryAssignFlavors(t *testing.T) {
 			clusterQueue: cache.ClusterQueue{
 				RequestableResources: map[corev1.ResourceName][]cache.FlavorLimits{
 					corev1.ResourceCPU: {
-						{Name: "non-existent", Guaranteed: 4000},
-						{Name: "two", Guaranteed: 4000},
+						{Name: "non-existent", Min: 4000},
+						{Name: "two", Min: 4000},
 					},
 				},
 			},
@@ -1054,8 +1054,8 @@ func TestEntryAssignFlavors(t *testing.T) {
 			clusterQueue: cache.ClusterQueue{
 				RequestableResources: map[corev1.ResourceName][]cache.FlavorLimits{
 					corev1.ResourceCPU: {
-						{Name: "one", Guaranteed: 4000},
-						{Name: "two", Guaranteed: 4000},
+						{Name: "one", Min: 4000},
+						{Name: "two", Min: 4000},
 					},
 				},
 				LabelKeys: map[corev1.ResourceName]sets.String{corev1.ResourceCPU: sets.NewString("cpuType")},
@@ -1105,12 +1105,12 @@ func TestEntryAssignFlavors(t *testing.T) {
 			clusterQueue: cache.ClusterQueue{
 				RequestableResources: map[corev1.ResourceName][]cache.FlavorLimits{
 					corev1.ResourceCPU: {
-						{Name: "one", Guaranteed: 4000},
-						{Name: "two", Guaranteed: 4000},
+						{Name: "one", Min: 4000},
+						{Name: "two", Min: 4000},
 					},
 					corev1.ResourceMemory: {
-						{Name: "one", Guaranteed: utiltesting.Gi},
-						{Name: "two", Guaranteed: utiltesting.Gi},
+						{Name: "one", Min: utiltesting.Gi},
+						{Name: "two", Min: utiltesting.Gi},
 					},
 				},
 			},
@@ -1169,8 +1169,8 @@ func TestEntryAssignFlavors(t *testing.T) {
 			clusterQueue: cache.ClusterQueue{
 				RequestableResources: map[corev1.ResourceName][]cache.FlavorLimits{
 					corev1.ResourceCPU: {
-						{Name: "one", Guaranteed: 4000},
-						{Name: "two", Guaranteed: 4000},
+						{Name: "one", Min: 4000},
+						{Name: "two", Min: 4000},
 					},
 				},
 			},
@@ -1215,8 +1215,8 @@ func TestEntryAssignFlavors(t *testing.T) {
 			clusterQueue: cache.ClusterQueue{
 				RequestableResources: map[corev1.ResourceName][]cache.FlavorLimits{
 					corev1.ResourceCPU: {
-						{Name: "one", Guaranteed: 4000},
-						{Name: "two", Guaranteed: 4000},
+						{Name: "one", Min: 4000},
+						{Name: "two", Min: 4000},
 					},
 				},
 				LabelKeys: map[corev1.ResourceName]sets.String{corev1.ResourceCPU: sets.NewString("cpuType")},
@@ -1243,8 +1243,8 @@ func TestEntryAssignFlavors(t *testing.T) {
 			clusterQueue: cache.ClusterQueue{
 				RequestableResources: map[corev1.ResourceName][]cache.FlavorLimits{
 					corev1.ResourceCPU: {
-						{Name: "one", Guaranteed: 4000},
-						{Name: "two", Guaranteed: 10_000},
+						{Name: "one", Min: 4000},
+						{Name: "two", Min: 10_000},
 					},
 				},
 			},
@@ -1281,16 +1281,16 @@ func TestEntryAssignFlavors(t *testing.T) {
 				RequestableResources: map[corev1.ResourceName][]cache.FlavorLimits{
 					corev1.ResourceCPU: {
 						{
-							Name:       "default",
-							Guaranteed: 2000,
-							Ceiling:    pointer.Int64(100_000),
+							Name: "default",
+							Min:  2000,
+							Max:  pointer.Int64(100_000),
 						},
 					},
 					corev1.ResourceMemory: {
 						{
-							Name:       "default",
-							Guaranteed: 2 * utiltesting.Gi,
-							// No ceiling.
+							Name: "default",
+							Min:  2 * utiltesting.Gi,
+							// No max.
 						},
 					},
 				},
@@ -1339,9 +1339,9 @@ func TestEntryAssignFlavors(t *testing.T) {
 				RequestableResources: map[corev1.ResourceName][]cache.FlavorLimits{
 					corev1.ResourceCPU: {
 						{
-							Name:       "one",
-							Guaranteed: 1000,
-							// No ceiling.
+							Name: "one",
+							Min:  1000,
+							// No max.
 						},
 					},
 				},
@@ -1355,7 +1355,7 @@ func TestEntryAssignFlavors(t *testing.T) {
 				},
 			},
 		},
-		"past ceiling": {
+		"past max": {
 			wlPods: []kueue.PodSet{
 				{
 					Count: 1,
@@ -1369,9 +1369,9 @@ func TestEntryAssignFlavors(t *testing.T) {
 				RequestableResources: map[corev1.ResourceName][]cache.FlavorLimits{
 					corev1.ResourceCPU: {
 						{
-							Name:       "one",
-							Guaranteed: 1000,
-							Ceiling:    pointer.Int64(10_000),
+							Name: "one",
+							Min:  1000,
+							Max:  pointer.Int64(10_000),
 						},
 					},
 				},
diff --git a/pkg/util/testing/wrappers.go b/pkg/util/testing/wrappers.go
index 05e3f0e39..39b567e4c 100644
--- a/pkg/util/testing/wrappers.go
+++ b/pkg/util/testing/wrappers.go
@@ -310,11 +310,11 @@ func (r *ResourceWrapper) Flavor(f *kueue.Flavor) *ResourceWrapper {
 type FlavorWrapper struct{ kueue.Flavor }
 
 // MakeFlavor creates a wrapper for a resource flavor.
-func MakeFlavor(rf, guaranteed string) *FlavorWrapper {
+func MakeFlavor(rf, min string) *FlavorWrapper {
 	return &FlavorWrapper{kueue.Flavor{
 		ResourceFlavor: kueue.ResourceFlavorReference(rf),
 		Quota: kueue.Quota{
-			Guaranteed: resource.MustParse(guaranteed),
+			Min: resource.MustParse(min),
 		},
 	}}
 }
@@ -324,9 +324,9 @@ func (f *FlavorWrapper) Obj() *kueue.Flavor {
 	return &f.Flavor
 }
 
-// Ceiling updates the flavor ceiling.
-func (f *FlavorWrapper) Ceiling(c string) *FlavorWrapper {
-	f.Quota.Ceiling = pointer.Quantity(resource.MustParse(c))
+// Max updates the flavor max.
+func (f *FlavorWrapper) Max(c string) *FlavorWrapper {
+	f.Quota.Max = pointer.Quantity(resource.MustParse(c))
 	return f
 }
 
diff --git a/test/integration/controller/core/clusterqueue_controller_test.go b/test/integration/controller/core/clusterqueue_controller_test.go
index d0710facf..18f76ec55 100644
--- a/test/integration/controller/core/clusterqueue_controller_test.go
+++ b/test/integration/controller/core/clusterqueue_controller_test.go
@@ -74,11 +74,11 @@ var _ = ginkgo.Describe("ClusterQueue controller", func() {
 	ginkgo.BeforeEach(func() {
 		clusterQueue = testing.MakeClusterQueue("cluster-queue").
 			Resource(testing.MakeResource(corev1.ResourceCPU).
-				Flavor(testing.MakeFlavor(flavorOnDemand, "5").Ceiling("10").Obj()).
-				Flavor(testing.MakeFlavor(flavorSpot, "5").Ceiling("10").Obj()).Obj()).
+				Flavor(testing.MakeFlavor(flavorOnDemand, "5").Max("10").Obj()).
+				Flavor(testing.MakeFlavor(flavorSpot, "5").Max("10").Obj()).Obj()).
 			Resource(testing.MakeResource(resourceGPU).
-				Flavor(testing.MakeFlavor(flavorModelA, "5").Ceiling("10").Obj()).
-				Flavor(testing.MakeFlavor(flavorModelB, "5").Ceiling("10").Obj()).Obj()).Obj()
+				Flavor(testing.MakeFlavor(flavorModelA, "5").Max("10").Obj()).
+				Flavor(testing.MakeFlavor(flavorModelB, "5").Max("10").Obj()).Obj()).Obj()
 		gomega.Expect(k8sClient.Create(ctx, clusterQueue)).To(gomega.Succeed())
 		queue = testing.MakeQueue("queue", ns.Name).ClusterQueue(clusterQueue.Name).Obj()
 		gomega.Expect(k8sClient.Create(ctx, queue)).To(gomega.Succeed())
diff --git a/test/integration/controller/core/queue_controller_test.go b/test/integration/controller/core/queue_controller_test.go
index 830dc5395..5b21a228d 100644
--- a/test/integration/controller/core/queue_controller_test.go
+++ b/test/integration/controller/core/queue_controller_test.go
@@ -49,8 +49,8 @@ var _ = ginkgo.Describe("Queue controller", func() {
 	ginkgo.BeforeEach(func() {
 		clusterQueue = testing.MakeClusterQueue("clusterQueue_queue-controller").
 			Resource(testing.MakeResource(resourceGPU).
-				Flavor(testing.MakeFlavor(flavorModelA, "5").Ceiling("10").Obj()).
-				Flavor(testing.MakeFlavor(flavorModelB, "5").Ceiling("10").Obj()).Obj()).Obj()
+				Flavor(testing.MakeFlavor(flavorModelA, "5").Max("10").Obj()).
+				Flavor(testing.MakeFlavor(flavorModelB, "5").Max("10").Obj()).Obj()).Obj()
 		queue = testing.MakeQueue("queue", ns.Name).ClusterQueue(clusterQueue.Name).Obj()
 		gomega.Expect(k8sClient.Create(ctx, queue)).To(gomega.Succeed())
 	})
diff --git a/test/integration/framework/framework.go b/test/integration/framework/framework.go
index 54ee52686..8372caab2 100644
--- a/test/integration/framework/framework.go
+++ b/test/integration/framework/framework.go
@@ -164,7 +164,7 @@ func ExpectWorkloadsToBePending(ctx context.Context, k8sClient client.Client, wl
 			}
 		}
 		return pending
-	}).Should(gomega.Equal(len(wls)), "Not enough workloads are pending")
+	}, Timeout, Interval).Should(gomega.Equal(len(wls)), "Not enough workloads are pending")
 }
 
 func UpdateWorkloadStatus(ctx context.Context, k8sClient client.Client, wl *kueue.Workload, update func(*kueue.Workload)) {
diff --git a/test/integration/scheduler/scheduler_test.go b/test/integration/scheduler/scheduler_test.go
index bf555af2b..3029026a5 100644
--- a/test/integration/scheduler/scheduler_test.go
+++ b/test/integration/scheduler/scheduler_test.go
@@ -86,7 +86,7 @@ var _ = ginkgo.Describe("Scheduler", func() {
 		prodClusterQ = testing.MakeClusterQueue("prod-cq").
 			Cohort("prod").
 			Resource(testing.MakeResource(corev1.ResourceCPU).
-				Flavor(testing.MakeFlavor(spotTaintedFlavor.Name, "5").Ceiling("5").Obj()).
+				Flavor(testing.MakeFlavor(spotTaintedFlavor.Name, "5").Max("5").Obj()).
 				Flavor(testing.MakeFlavor(onDemandFlavor.Name, "5").Obj()).
 				Obj()).
 			Obj()
@@ -103,7 +103,7 @@ var _ = ginkgo.Describe("Scheduler", func() {
 		prodBEClusterQ = testing.MakeClusterQueue("prod-be-cq").
 			Cohort("be").QueueingStrategy(kueue.BestEffortFIFO).
 			Resource(testing.MakeResource(corev1.ResourceCPU).
-				Flavor(testing.MakeFlavor(onDemandFlavor.Name, "5").Ceiling("10").Obj()).
+				Flavor(testing.MakeFlavor(onDemandFlavor.Name, "5").Max("10").Obj()).
 				Obj()).
 			Obj()
 		gomega.Expect(k8sClient.Create(ctx, prodBEClusterQ)).Should(gomega.Succeed())
@@ -111,7 +111,7 @@ var _ = ginkgo.Describe("Scheduler", func() {
 		devBEClusterQ = testing.MakeClusterQueue("dev-be-cq").
 			Cohort("be").QueueingStrategy(kueue.BestEffortFIFO).
 			Resource(testing.MakeResource(corev1.ResourceCPU).
-				Flavor(testing.MakeFlavor(onDemandFlavor.Name, "5").Ceiling("10").Obj()).
+				Flavor(testing.MakeFlavor(onDemandFlavor.Name, "5").Max("10").Obj()).
 				Obj()).
 			Obj()
 		gomega.Expect(k8sClient.Create(ctx, devBEClusterQ)).Should(gomega.Succeed())
@@ -237,7 +237,7 @@ var _ = ginkgo.Describe("Scheduler", func() {
 		fallbackClusterQueue := testing.MakeClusterQueue("fallback-cq").
 			Cohort(prodClusterQ.Spec.Cohort).
 			Resource(testing.MakeResource(corev1.ResourceCPU).
-				Flavor(testing.MakeFlavor(spotTaintedFlavor.Name, "5").Obj()). // prod-cq can't borrow this flavor due to its ceiling.
+				Flavor(testing.MakeFlavor(spotTaintedFlavor.Name, "5").Obj()). // prod-cq can't borrow this flavor due to its max quota.
 				Flavor(testing.MakeFlavor(onDemandFlavor.Name, "5").Obj()).
 				Obj()).
 			Obj()
@@ -501,7 +501,7 @@ var _ = ginkgo.Describe("Scheduler", func() {
 		devCq := &kueue.ClusterQueue{}
 		gomega.Expect(k8sClient.Get(ctx, types.NamespacedName{Name: devBEClusterQ.Name}, devCq)).Should(gomega.Succeed())
 
-		updatedResource := testing.MakeResource(corev1.ResourceCPU).Flavor(testing.MakeFlavor(onDemandFlavor.Name, "13").Ceiling("13").Obj()).Obj()
+		updatedResource := testing.MakeResource(corev1.ResourceCPU).Flavor(testing.MakeFlavor(onDemandFlavor.Name, "13").Max("13").Obj()).Obj()
 		devCq.Spec.RequestableResources = []kueue.Resource{*updatedResource}
 		gomega.Expect(k8sClient.Update(ctx, devCq)).Should(gomega.Succeed())