Skip to main content

Quota Management

Datum Cloud uses a sophisticated quota system to enforce resource limits at the organization and project levels. This guide explains how quotas work and how to manage them.

Quota System Overview

The quota system consists of four main components:

ResourceRegistration

Defines what can be limited (e.g., projects, workloads)

GrantCreationPolicy

Defines how much quota to allocate automatically

ClaimCreationPolicy

Defines when quota is claimed (e.g., on resource creation)

ResourceGrant / ResourceClaim

Actual quota allocations and consumption

How Quotas Work

Example: Project Quota

1

Registration

A ResourceRegistration defines that projects can be quota-limited.From config/services/resourcemanager.miloapis.com/quota/registrations/project-registration.yaml:1:
apiVersion: quota.miloapis.com/v1alpha1
kind: ResourceRegistration
metadata:
  name: projects-per-organization
spec:
  consumerType:
    apiGroup: resourcemanager.miloapis.com
    kind: Organization
  type: Entity
  resourceType: resourcemanager.miloapis.com/projects
  baseUnit: project
  displayUnit: projects
  claimingResources:
    - apiGroup: resourcemanager.miloapis.com
      kind: Project
2

Grant Policy

A GrantCreationPolicy automatically allocates quota when an organization is created.For Personal organizations (quota/grant-policies/personal-org-grant-policy.yaml:1):
spec:
  trigger:
    resource:
      apiVersion: resourcemanager.miloapis.com/v1alpha1
      kind: Organization
    constraints:
      - expression: 'trigger.spec.type == "Personal"'
  target:
    resourceGrantTemplate:
      spec:
        allowances:
          - resourceType: resourcemanager.miloapis.com/projects
            buckets:
              - amount: 2  # Personal orgs get 2 projects
For Standard organizations (quota/grant-policies/standard-org-grant-policy.yaml:1):
spec:
  allowances:
    - resourceType: resourcemanager.miloapis.com/projects
      buckets:
        - amount: 10  # Standard orgs get 10 projects
3

Claim Policy

A ClaimCreationPolicy creates a quota claim when a project is created.From quota/claim-policies/claim-creation-policy.yaml:1:
spec:
  trigger:
    resource:
      apiVersion: resourcemanager.miloapis.com/v1alpha1
      kind: Project
  target:
    resourceClaimTemplate:
      spec:
        requests:
          - resourceType: resourcemanager.miloapis.com/projects
            amount: 1  # Each project claims 1 quota unit
4

Enforcement

When you create a project:
  1. ClaimCreationPolicy triggers and creates a ResourceClaim
  2. Quota system checks if organization has available quota
  3. If quota available: Project created, claim satisfied
  4. If quota exceeded: Creation fails with error

Viewing Quotas

Organization Quotas

# View quota grants for an organization
kubectl get resourcegrants -n organization-my-company
Example output:
NAME                     CONSUMER     RESOURCE-TYPE                            ALLOCATED   AVAILABLE
default-project-quota    my-company   resourcemanager.miloapis.com/projects    7           3

Detailed Quota Information

# Describe grant
kubectl describe resourcegrant default-project-quota -n organization-my-company
Example output:
Name:         default-project-quota
Namespace:    organization-my-company
Spec:
  Consumer Ref:
    API Group:  resourcemanager.miloapis.com
    Kind:       Organization
    Name:       my-company
  Allowances:
    Resource Type:  resourcemanager.miloapis.com/projects
    Buckets:
      Amount:  10
Status:
  Allocated:  7   # 7 projects created
  Available:  3   # 3 more can be created
  Phase:      Active

View Quota Claims

# List all claims in organization
kubectl get resourceclaims -n organization-my-company
Example output:
NAME                          CONSUMER     REQUESTED   STATUS
project-production-env        my-company   1           Satisfied
project-staging-env           my-company   1           Satisfied
project-development           my-company   1           Satisfied

Check Specific Claim

kubectl describe resourceclaim project-production-env -n organization-my-company

Default Quotas

Datum Cloud has the following default quotas:

Organization Quotas

Projects: 2
resourceType: resourcemanager.miloapis.com/projects
amount: 2
Defined in config/services/resourcemanager.miloapis.com/quota/grant-policies/personal-org-grant-policy.yaml:32

Customizing Quotas

Modify Organization Project Quota

1

Edit the GrantCreationPolicy

# For Personal organizations
kubectl edit grantcreationpolicy personal-organization-project-quota-policy

# For Standard organizations
kubectl edit grantcreationpolicy standard-organization-project-quota-policy
2

Change the amount

spec:
  target:
    resourceGrantTemplate:
      spec:
        allowances:
          - resourceType: resourcemanager.miloapis.com/projects
            buckets:
              - amount: 20  # Changed from 10 to 20
3

Apply to existing organizations

The policy only affects new organizations. For existing orgs, manually update grants:
kubectl edit resourcegrant default-project-quota -n organization-my-company
Change amount:
spec:
  allowances:
    - resourceType: resourcemanager.miloapis.com/projects
      buckets:
        - amount: 20

Manually Grant Additional Quota

Grant extra quota to a specific organization:
apiVersion: quota.miloapis.com/v1alpha1
kind: ResourceGrant
metadata:
  name: extra-project-quota
  namespace: organization-my-company
spec:
  consumerRef:
    apiGroup: resourcemanager.miloapis.com
    kind: Organization
    name: my-company
  allowances:
    - resourceType: resourcemanager.miloapis.com/projects
      buckets:
        - amount: 5  # 5 additional projects
kubectl apply -f extra-quota.yaml
Multiple grants for the same resource type are additive. The organization now has 10 (default) + 5 (extra) = 15 total project quota.

Creating New Quota Types

To add quota limits for other resources (e.g., workloads, networks):

1. Create ResourceRegistration

apiVersion: quota.miloapis.com/v1alpha1
kind: ResourceRegistration
metadata:
  name: workloads-per-project
  labels:
    app.kubernetes.io/name: datum
    app.kubernetes.io/component: quota-system
spec:
  # Who consumes this quota
  consumerType:
    apiGroup: resourcemanager.miloapis.com
    kind: Project
  
  # Counting quota (not size-based)
  type: Entity
  
  # What resource is being limited
  resourceType: compute.datumapis.com/workloads
  
  description: "Maximum number of workloads per project"
  
  # Units
  baseUnit: workload
  displayUnit: workloads
  unitConversionFactor: 1
  
  # What resources claim this quota
  claimingResources:
    - apiGroup: compute.datumapis.com
      kind: Workload

2. Create GrantCreationPolicy

apiVersion: quota.miloapis.com/v1alpha1
kind: GrantCreationPolicy
metadata:
  name: project-workload-quota-policy
  labels:
    app.kubernetes.io/name: datum
    app.kubernetes.io/component: quota-system
spec:
  # Trigger when a project is created
  trigger:
    resource:
      apiVersion: resourcemanager.miloapis.com/v1alpha1
      kind: Project
  
  # Create a grant
  target:
    resourceGrantTemplate:
      metadata:
        name: "workload-quota"
        namespace: "project-{{ trigger.metadata.name }}"
        labels:
          quota.miloapis.com/auto-created: "true"
      spec:
        consumerRef:
          apiGroup: resourcemanager.miloapis.com
          kind: Project
          name: "{{ trigger.metadata.name }}"
        allowances:
          - resourceType: compute.datumapis.com/workloads
            buckets:
              - amount: 50  # 50 workloads per project

3. Create ClaimCreationPolicy

apiVersion: quota.miloapis.com/v1alpha1
kind: ClaimCreationPolicy
metadata:
  name: workload-quota-enforcement
  labels:
    app.kubernetes.io/name: datum
    app.kubernetes.io/component: quota-system
spec:
  # Trigger when a workload is created
  trigger:
    resource:
      apiVersion: compute.datumapis.com/v1alpha1
      kind: Workload
  
  # Create a claim
  target:
    resourceClaimTemplate:
      metadata:
        name: "workload-{{ trigger.metadata.name }}"
        namespace: "project-{{ trigger.metadata.namespace }}"
        labels:
          quota.miloapis.com/auto-created: "true"
      spec:
        consumerRef:
          apiGroup: resourcemanager.miloapis.com
          kind: Project
          name: "{{ trigger.metadata.namespace }}"
        requests:
          - resourceType: compute.datumapis.com/workloads
            amount: 1  # Each workload claims 1 unit

4. Apply Quota Resources

kubectl apply -f workload-quota-registration.yaml
kubectl apply -f workload-quota-grant-policy.yaml
kubectl apply -f workload-quota-claim-policy.yaml

Handling Quota Errors

Quota Exceeded Error

When you exceed quota:
Error from server: admission webhook denied the request: 
Quota exceeded for resourcemanager.miloapis.com/projects in organization my-company. 
Requested: 1, Available: 0
Solutions:
# List existing projects
kubectl get projects -l organization=my-company

# Delete unused project
kubectl delete project old-project

# Try again
kubectl apply -f new-project.yaml

Monitoring Quota Usage

Check Current Usage

# Script to show quota usage
for org in $(kubectl get organizations -o name); do
  echo "=== $org ==="
  orgname=$(echo $org | cut -d'/' -f2)
  kubectl get resourcegrants -n organization-$orgname -o custom-columns=\
    NAME:.metadata.name,\
    TYPE:.spec.allowances[0].resourceType,\
    ALLOCATED:.status.allocated,\
    AVAILABLE:.status.available
done

Set Up Alerts

Use Prometheus to alert on high quota usage:
# Prometheus alert rule
groups:
  - name: datum_quotas
    rules:
      - alert: QuotaNearlyExhausted
        expr: |
          (
            quota_allocated / (quota_allocated + quota_available)
          ) > 0.9
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "Quota nearly exhausted for {{ $labels.organization }}"
          description: "{{ $labels.organization }} has used {{ $value | humanizePercentage }} of quota."

Best Practices

Monitor quota usage

Regularly check quota usage to avoid hitting limits.

Clean up unused resources

Delete old projects, workloads to free quota.

Plan capacity

Estimate quota needs before starting new projects.

Use labels

Label resources to identify quota consumers.

Set up alerts

Alert when quota usage reaches 80-90%.

Document limits

Document quota limits for your team.

Troubleshooting

Quota not enforced

# Check if ClaimCreationPolicy exists
kubectl get claimcreationpolicies

# Check if ResourceRegistration exists
kubectl get resourceregistrations

# Check controller logs
kubectl logs -n datum-system -l control-plane=controller-manager | grep quota

Grant not created automatically

# Check GrantCreationPolicy
kubectl describe grantcreationpolicy personal-organization-project-quota-policy

# Manually create grant
kubectl apply -f grant.yaml

Claim not created on resource creation

# Check if ClaimCreationPolicy is active
kubectl get claimcreationpolicies

# Check events
kubectl get events -n organization-my-company --sort-by='.lastTimestamp'

# Manually create claim
kubectl apply -f claim.yaml

Next Steps

Monitoring

Set up Prometheus monitoring for quotas

Managing Resources

Resource management workflows

Organizations

Learn more about organizations

Projects

Learn more about projects

Build docs developers (and LLMs) love