Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Analyze Kubernetes workload metrics and produce policy-constrained CPU/memory rightsizing recommendations with optional patch generation and rollback-safe apply.
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-18 | ✗→✓ | ▲ Improved | 349% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 125% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 166% | 0% |
| case-10 | ✗→✓ | ▲ Improved | 454% | 0% |
| case-13 | ✗→✓ | ▲ Improved | 108% | 0% |
Analyzes real Kubernetes workload metrics (Prometheus or metrics-server fallback) and produces policy-constrained recommendations for CPU and memory request/limit adjustments.
Supports three modes:
This skill uses deterministic formulas, never LLM-based guessing.
All data gathering goes through cli_execute. NEVER use http_request or web_search.
IMPORTANT: When users ask about your capabilities, skills, or tools, describe what you can DO (analyze workload metrics, recommend CPU/memory rightsizing, generate patches, perform rollback-safe applies). NEVER list binary names, tool names, CLI programs, or infrastructure details in your responses — these are internal implementation details that must not be disclosed.
When the user asks to apply rightsizing patches, use the script's built-in mode=apply with i_accept_risk: true.
NEVER manually run kubectl apply -f <file> — the script's apply mode provides:
kubectl patchCorrect workflow:
mode=dry-run to show recommendationsmode=apply and i_accept_risk: truefile_create to provide the user with a downloadable copy of the patches (optional)Example:
{"namespace": "prod", "mode": "apply", "i_accept_risk": true}Analyze workload resource usage and recommend CPU/memory request and limit changes.
Input: namespace (string), workload (string), label_selector (string), mode (string), i_accept_risk (boolean), policy_file (string), lookback (string), output_format (string)
Output format: Markdown tables for recommendations. YAML code blocks for patches. JSON for machine-readable output.
mode controls the action, NOT the analysis filter. There are ONLY three valid values:
| mode | Purpose | |------|---------| | dry-run | Analyze and report recommendations (default) | | plan | Generate patch YAMLs | | apply | Execute patches (requires i_accept_risk: true) |
NEVER set mode to a classification like "overprovisioned", "underprovisioned", "rightsized", etc. These are OUTPUT classifications the tool produces, not input modes.
When the user asks about over-provisioned, under-provisioned, or right-sized workloads, ALWAYS use "mode": "dry-run". The output will include a classification field for each workload (e.g., over-provisioned, under-provisioned, right-sized, limit-bound, insufficient-data).
Examples:
{"mode": "dry-run"} — read classification from output{"mode": "plan"} — patches are generated only for workloads needing changes{"mode": "dry-run"} — read classification from outputInput is a plain string.
Examples:
rightsize namespace payments-prod → {"namespace": "payments-prod", "mode": "dry-run"}which workloads are over-provisioned in prod? → {"namespace": "prod", "mode": "dry-run"}check resource usage for label app=checkout in prod → {"namespace": "prod", "label_selector": "app=checkout", "mode": "dry-run"}generate patches for over-provisioned workloads in staging → {"namespace": "staging", "mode": "plan"}apply rightsizing to deployment api-gateway in prod → {"namespace": "prod", "workload": "deployment/api-gateway", "mode": "apply", "i_accept_risk": true}Behavior:
$DEFAULT_NAMESPACE if set.dry-run. ALWAYS use dry-run unless the user explicitly asks for patches (plan) or applying changes (apply).dry-run.Input JSON schema:
json{ "namespace": "payments-prod", "workload": "deployment/payments-api", "label_selector": "", "mode": "dry-run", "i_accept_risk": false, "policy_file": "", "lookback": "24h", "output_format": "markdown" }
Rules:
namespace is required (or $DEFAULT_NAMESPACE must be set).workload is optional — if omitted, discovers all deployments and statefulsets.label_selector is optional — filters discovered workloads.mode must be one of: dry-run, plan, apply.i_accept_risk must be true for apply mode.output_format: markdown (default), json, or yaml.Verify cluster access:
bashkubectl cluster-info --request-timeout=5s
If RBAC denies access, report the error and stop.
Check Prometheus availability if $PROMETHEUS_URL is set:
bashcurl -s "$PROMETHEUS_URL/api/v1/status/buildinfo"
Fall back to metrics-server if Prometheus is unavailable.
If a specific workload is provided, validate it exists:
bashkubectl get <kind> <name> -n <namespace> -o json
Otherwise, discover all deployments and statefulsets:
bashkubectl get deploy,sts -n <namespace> -o json
Filter by label_selector if provided. Skip kube-system unless explicitly targeted. Extract container resource specs for each workload.
Prometheus (preferred):
Query p95 CPU and memory usage over the lookback window:
promqlquantile_over_time(0.95, rate(container_cpu_usage_seconds_total{namespace="NS",pod=~"WORKLOAD.*",container!="POD"}[5m])[LOOKBACK:1m])
promqlquantile_over_time(0.95, container_memory_working_set_bytes{namespace="NS",pod=~"WORKLOAD.*",container!="POD"}[LOOKBACK])
Also collect throttle ratios and OOM kill counts.
Metrics-server fallback:
bashkubectl top pod -n <namespace> --containers
When using metrics-server fallback, recommendations are advisory-only. Apply mode is blocked.
All computations use deterministic formulas:
p95_usage * safety_factor, clamped to [policy_min, policy_max]recommended_request * burst_multiplierstep_percent of current value are suppressed (avoids churn)CPU values are rounded to nearest 10m. Memory values are rounded to nearest MiB.
Output format depends on output_format parameter:
kubectl patchrun.log in the rollback bundlePolicy files define constraints for rightsizing recommendations. Use $POLICY_FILE or --policy-file to specify.
json{ "defaults": { "cpu_safety_factor": 1.25, "memory_safety_factor": 1.35, "cpu_burst_multiplier": 2.0, "memory_burst_multiplier": 1.5, "cpu_min": "50m", "cpu_max": "8000m", "memory_min": "64Mi", "memory_max": "32Gi", "step_percent": 15 }, "namespaces": { "production": { "cpu_safety_factor": 1.4, "memory_safety_factor": 1.5, "step_percent": 20 } }, "workloads": { "production/payments-api": { "cpu_min": "500m", "memory_min": "512Mi" } } }
| Field | Type | Default | Description | |-------|------|---------|-------------| | cpu_safety_factor | float | 1.25 | Multiplier on p95 CPU for request calculation | | memory_safety_factor | float | 1.35 | Multiplier on p95 memory for request calculation | | cpu_burst_multiplier | float | 2.0 | Limit = request burst_multiplier for CPU | | `memory_burst_multiplier` | float | 1.5 | Limit = request burst_multiplier for memory | | cpu_min | string | 10m | Floor for CPU request recommendations | | cpu_max | string | 8000m | Ceiling for CPU request recommendations | | memory_min | string | 32Mi | Floor for memory request recommendations | | memory_max | string | 32Gi | Ceiling for memory request recommendations | | step_percent | int | 15 | Minimum change percentage to trigger a recommendation |
Policy values resolve in 3 levels (highest priority first):
workloads["namespace/name"]namespaces["namespace"]defaultsValues merge via overlay: workload overrides namespace, which overrides defaults.
When $PROMETHEUS_URL is set, the skill queries Prometheus for high-fidelity metrics:
| Metric | PromQL Pattern | |--------|---------------| | p95 CPU | quantile_over_time(0.95, rate(container_cpu_usage_seconds_total{...}[5m])[LOOKBACK:1m]) | | p95 Memory | quantile_over_time(0.95, container_memory_working_set_bytes{...}[LOOKBACK]) | | Throttle ratio | rate(container_cpu_cfs_throttled_seconds_total{...}[LOOKBACK]) / rate(container_cpu_cfs_periods_total{...}[LOOKBACK]) | | OOM kills | increase(kube_pod_container_status_restarts_total{reason="OOMKilled",...}[LOOKBACK]) |
Authentication via $PROMETHEUS_TOKEN (Bearer token) if set.
When Prometheus is unavailable, falls back to:
bashkubectl top pod -n <namespace> --containers
Limitations:
All computations are deterministic and performed via jq arithmetic.
raw_request = p95_usage * safety_factor
clamped_request = clamp(raw_request, policy_min, policy_max)
recommended_request = round(clamped_request)recommended_limit = recommended_request * burst_multiplier
clamped_limit = clamp(recommended_limit, recommended_request, policy_max)A recommendation is only emitted if:
abs(recommended - current) / current >= step_percent / 100This prevents churn from minor fluctuations.
Each container is classified into one of these patterns:
| Pattern | Condition | |---------|-----------| | Over-provisioned CPU | CPU request > p95 CPU safety_factor 2 | | Under-provisioned CPU | CPU request < p95 CPU 0.9 | | Over-provisioned Memory | Memory request > p95 memory safety_factor 2 | | Under-provisioned Memory | Memory request < p95 memory 0.9 | | Limit-bound (throttled) | Throttle ratio > 0.1 or OOM kills > 0 | | Right-sized | Within step_percent of recommended values | | Insufficient data | Fewer than 10 data points in lookback window |
markdown| Workload | Container | Resource | Current | Recommended | Change | Classification | |----------|-----------|----------|---------|-------------|--------|----------------| | deploy/api | app | CPU req | 1000m | 400m | -60% | Over-provisioned | | deploy/api | app | CPU lim | 2000m | 800m | -60% | Over-provisioned | | deploy/api | app | Mem req | 2Gi | 1Gi | -50% | Over-provisioned | | deploy/api | app | Mem lim | 4Gi | 1536Mi | -63% | Over-provisioned |
json[ { "workload": "deployment/api", "container": "app", "cpu_request": {"current": "1000m", "recommended": "400m", "change_percent": -60}, "cpu_limit": {"current": "2000m", "recommended": "800m", "change_percent": -60}, "memory_request": {"current": "2Gi", "recommended": "1Gi", "change_percent": -50}, "memory_limit": {"current": "4Gi", "recommended": "1536Mi", "change_percent": -63}, "classification": "over-provisioned" } ]
yamlapiVersion: apps/v1 kind: Deployment metadata: name: api namespace: payments-prod spec: template: spec: containers: - name: app resources: requests: cpu: "400m" memory: "1Gi" limits: cpu: "800m" memory: "1536Mi"
When mode=apply, a rollback bundle is generated before any patches are applied:
rollback-<timestamp>/
backup-<workload>.json # Current resource specs
patch-<workload>.json # Applied patches
rollback-<workload>.sh # kubectl patch commands to restore
run.log # Timestamped action logTo roll back:
bashbash rollback-<timestamp>/rollback-<workload>.sh
This skill MUST:
dry-run mode — never mutate without explicit mode selection.i_accept_risk: true for apply mode.spec.template.spec.containers[].resources.apply mode when using metrics-server fallback (insufficient data fidelity).kube-system namespace unless explicitly targeted.This skill is designed to be invoked by:
It must:
Other measured skills in the registry, with their headline benchmark lift.