MATIH Platform is in active MVP development. Documentation reflects current implementation status.
9. Query Engine & SQL
Workload Management

Workload Management

The WorkloadController and WorkloadManager provide comprehensive workload management including query queuing, resource pool management, tenant quota enforcement, and throttling.


Base Path

/v1/workload

Workload Status

curl http://query-engine:8080/v1/workload/status \
  -H "Authorization: Bearer $JWT_TOKEN"
{
  "enabled": true,
  "timestamp": "2026-02-12T10:30:00Z",
  "totalSubmitted": 45000,
  "totalAdmitted": 44500,
  "totalRejected": 500,
  "totalCompleted": 43800,
  "totalFailed": 700,
  "queueDepth": 12,
  "executingQueries": 28,
  "averageWaitTimeMs": 450,
  "memoryUtilization": 0.65,
  "cpuUtilization": 0.48,
  "concurrencyUtilization": 0.56
}

Query Admission Flow

The WorkloadManager.submit() method implements a multi-step admission control:

Submit Query
    |
    v
Check Tenant Quota ---> REJECTED (quota exceeded)
    |
    v
Check Throttling -----> THROTTLED (rate limited, retry after backoff)
    |
    v
Calculate Priority
    |
    v
Resources Available? ---> YES: Execute immediately (EXECUTING)
    |
    NO
    |
    v
Queue Full? ---> YES: REJECTED (queue full)
    |
    NO
    |
    v
Enqueue (QUEUED, position N)

Queue Management

# Get queue statistics
curl http://query-engine:8080/v1/workload/queue \
  -H "Authorization: Bearer $JWT_TOKEN"
 
# Get queued queries for current tenant
curl http://query-engine:8080/v1/workload/queue/queries \
  -H "Authorization: Bearer $JWT_TOKEN"
 
# Update query priority
curl -X POST "http://query-engine:8080/v1/workload/queue/priority/query-123?priority=8" \
  -H "Authorization: Bearer $JWT_TOKEN"
 
# Remove query from queue
curl -X DELETE http://query-engine:8080/v1/workload/queue/query/query-123 \
  -H "Authorization: Bearer $JWT_TOKEN"

Resource Pool

# Get resource pool status
curl http://query-engine:8080/v1/workload/resources \
  -H "Authorization: Bearer $JWT_TOKEN"
 
# Get active resource reservations (admin only)
curl http://query-engine:8080/v1/workload/resources/reservations \
  -H "Authorization: Bearer $JWT_TOKEN"
 
# Get tenant resource usage
curl http://query-engine:8080/v1/workload/resources/tenant \
  -H "Authorization: Bearer $JWT_TOKEN"

Tenant Quotas

# Get current tenant quota status
curl http://query-engine:8080/v1/workload/quota \
  -H "Authorization: Bearer $JWT_TOKEN"
 
# Set custom quota for a tenant (admin only)
curl -X POST http://query-engine:8080/v1/workload/quota/override/{tenantId} \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $JWT_TOKEN" \
  -d '{
    "dailyQueryLimit": 10000,
    "dailyDataScanLimitGb": 500,
    "maxConcurrentQueries": 50
  }'
 
# Get quota alerts (admin only)
curl http://query-engine:8080/v1/workload/quota/alerts \
  -H "Authorization: Bearer $JWT_TOKEN"

Priority Calculation

Query priority is calculated based on multiple factors:

FactorEffect
Default priorityBase value from configuration
Interactive query typeBoost (higher priority)
Large estimated cost (>1M)Penalty (lower priority)
User-specified overrideDirect override
private int calculatePriority(QuerySubmission submission) {
    int priority = config.getPriority().getDefaultPriority();
    if (submission.getQueryType() == QueryQueue.QueryType.INTERACTIVE) {
        priority += config.getPriority().getInteractiveBoost();
    }
    if (submission.getEstimatedCost() > 1000000) {
        priority -= config.getPriority().getLargeQueryPenalty();
    }
    if (submission.getRequestedPriority() != null) {
        priority = submission.getRequestedPriority();
    }
    return Math.max(1, Math.min(config.getQueue().getPriorityLevels(), priority));
}

Throttling

Rate limiting uses a per-tenant sliding window with exponential backoff:

private ThrottleResult checkThrottling(UUID tenantId) {
    ThrottleState state = tenantThrottleState.computeIfAbsent(tenantId, k -> new ThrottleState());
    if (state.shouldReset()) state.reset();
    int maxPerMinute = config.getThrottling().getMaxQueriesPerMinute();
    if (state.getQueriesInWindow() >= maxPerMinute) {
        state.incrementBackoff();
        return ThrottleResult.throttled(state.getBackoffMs());
    }
    state.incrementQueries();
    return ThrottleResult.notThrottled();
}

Backoff increases exponentially: 100ms, 200ms, 400ms, 800ms... up to ~100 seconds.