Skip to content

[CONTP-1758] Improve DatadogGenericResource reconciliation at scale#3143

Merged
tbavelier merged 16 commits into
mainfrom
tbavelier/thousands-of-ddgrs
Jul 2, 2026
Merged

[CONTP-1758] Improve DatadogGenericResource reconciliation at scale#3143
tbavelier merged 16 commits into
mainfrom
tbavelier/thousands-of-ddgrs

Conversation

@tbavelier

@tbavelier tbavelier commented Jun 15, 2026

Copy link
Copy Markdown
Member

What does this PR do?

Improves DatadogGenericResource reconciliation behavior at high resource counts:

  • adds configurable DatadogGenericResource controller concurrency with --datadogGenericResourceMaxConcurrentReconciles / DD_GENERIC_RESOURCE_MAX_CONCURRENT_RECONCILES
  • adds configurable DDGR status polling cadence with --datadogGenericResourceRequeuePeriod / DD_GENERIC_RESOURCE_REQUEUE_PERIOD
  • keeps option precedence aligned with other operator startup options: compiled default < environment variable < CLI flag
  • marks DDGR live-state polling requeues as low priority so create/update/delete work can run ahead of status refresh backlog
  • documents the new DDGR tuning options

DD_GENERIC_RESOURCE_REQUEUE_PERIOD uses the shared duration env parser, so values must be valid Go duration strings such as 30s, 5m, or 1h. Bare integers are invalid and leave the default 60s in effect.

Motivation

At high CR counts, periodic status polling can dominate the controller queue and delay user-facing create/update/delete operations. This keeps DDGR status polling tunable and lower priority while leaving normal reconciliation and backend error retries at regular priority.

Should help in situations like #2816

Additional Notes

The low-priority path is limited to DDGR refreshState reconciles, which currently applies to resource types that fetch backend state such as monitors and SLOs. It intentionally does not lower the priority of create/update/delete retries.

Validated manually that workqueue_depth{controller="DatadogGenericResource", priority="-100"} exposes low-priority queue depth for status polling requeues. Created 1k DDGR with 10 concurrent reconciles, then changed to 1 concurrent reconcile to accumulate backlog in low-priority queue for status updates. Created an additional DDGR and verified it was treated in priority over the backlog and synced with the backend.

image

Shows the low-priority queue backlog while the regular priority is staying healthy.

Minimum Agent Versions

No minimum Agent or Cluster Agent version changes.

  • Agent: N/A
  • Cluster Agent: N/A

Describe your test plan

Automated tests:

go test ./cmd/...
go test ./internal/controller/datadoggenericresource
go test ./internal/controller

Manual scale and priority check:

  1. Deploy the operator with DDGR enabled and --datadogGenericResourceMaxConcurrentReconciles=10 or DD_GENERIC_RESOURCE_MAX_CONCURRENT_RECONCILES=10.
  2. Create 1k DDGRs at once (see helper in DDGR monitor load helper block below). The operator should process the queue in a few minutes and each DDGR should get an ID.
  3. Change datadogGenericResourceMaxConcurrentReconciles back to 1, or remove it since 1 is the default, and wait for the new operator pod to acquire the lease.
  4. Confirm backlog accumulates in the low-priority queue for status updates.
  5. Create a new DDGR, for example kubectl apply -f examples/datadoggenericresource/dashboard-sample.yaml.
  6. Confirm it syncs and gets an ID ahead of the status update backlog.
  7. Delete it with kubectl delete ddgr ddgr-dashboard-sample and confirm it is deleted.
  8. Change back to --datadogGenericResourceMaxConcurrentReconciles=10 or DD_GENERIC_RESOURCE_MAX_CONCURRENT_RECONCILES=10 and clean up the load-test resources.
DDGR monitor load helper
#!/usr/bin/env bash
set -euo pipefail

ACTION="${1:-create}" # create or delete
COUNT="${COUNT:-100}"
NAMESPACE="${NAMESPACE:-default}"
PREFIX="${PREFIX:-ddgr-load-test-monitor}"
MANIFEST="$(mktemp)"
trap 'rm -f "$MANIFEST"' EXIT

render() {
  for i in $(seq 1 "$COUNT"); do
    name="${PREFIX}-${i}"
    cat <<EOF
---
apiVersion: datadoghq.com/v1alpha1
kind: DatadogGenericResource
metadata:
  name: ${name}
spec:
  type: monitor
  jsonSpec: |-
    {
      "name": "${name}",
      "type": "metric alert",
      "query": "avg(last_5m):avg:system.load.1{*} > 100000",
      "message": "load test monitor",
      "tags": ["test:ddgr-load", "source:datadog-operator-pr-3143"]
    }
EOF
  done
}

render > "$MANIFEST"

case "$ACTION" in
  create)
    kubectl -n "$NAMESPACE" apply -f "$MANIFEST"
    ;;
  delete)
    kubectl -n "$NAMESPACE" delete -f "$MANIFEST" --ignore-not-found
    ;;
  *)
    echo "usage: COUNT=100 NAMESPACE=default $0 [create|delete]" >&2
    exit 1
    ;;
esac

Example:

COUNT=1000 NAMESPACE=default ./ddgr-load.sh create
COUNT=1000 NAMESPACE=default ./ddgr-load.sh delete

Requeue period check:

  1. Deploy the operator with DDGR enabled and DD_GENERIC_RESOURCE_REQUEUE_PERIOD=5m, or use --datadogGenericResourceRequeuePeriod=5m.
  2. Create a few DDGR monitors and verify state sync happens after roughly 5 minutes.
  3. Set DD_GENERIC_RESOURCE_REQUEUE_PERIOD to an invalid duration such as foo or 120.
  4. Verify the parser logs an ignoring invalid env var DD_GENERIC_RESOURCE_REQUEUE_PERIOD=... message and resources fall back to the default 60s sync cadence.
  5. Set both DD_GENERIC_RESOURCE_REQUEUE_PERIOD=5m and --datadogGenericResourceRequeuePeriod=2m, then verify the CLI flag wins.

Checklist

  • PR has at least one valid label: bug, enhancement, refactoring, documentation, tooling, and/or dependencies
  • PR has a milestone or the qa/skip-qa label
  • All commits are signed (see: signing commits)

@tbavelier tbavelier added the enhancement New feature or request label Jun 15, 2026
@tbavelier tbavelier added this to the v1.29.0 milestone Jun 15, 2026
@datadog-datadog-prod-us1-2

datadog-datadog-prod-us1-2 Bot commented Jun 15, 2026

Copy link
Copy Markdown

Code Coverage  Pipelines

Fix all issues with BitsAI

🛑 Gate Violations

🎯 1 Code Coverage issue detected

A Patch coverage percentage gate may be blocking this PR.

Patch coverage: 48.39% (threshold: 80.00%)

⚠️ Warnings

🚦 1 Pipeline job failed

DataDog/datadog-operator | e2e: [1.32]   View in Datadog   GitLab

ℹ️ Info

🎯 Code Coverage (details)
Patch Coverage: 48.39%
Overall Coverage: 45.10% (+0.03%)

Useful? React with 👍 / 👎

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 62e1b02 | Docs | Datadog PR Page | Give us feedback!

@codecov-commenter

codecov-commenter commented Jun 15, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 64.70588% with 18 lines in your changes missing coverage. Please review.
✅ Project coverage is 44.73%. Comparing base (72bc0a0) to head (f2af21b).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
...al/controller/datadoggenericresource_controller.go 0.00% 6 Missing ⚠️
cmd/main.go 0.00% 4 Missing ⚠️
...al/controller/datadoggenericresource/controller.go 89.18% 3 Missing and 1 partial ⚠️
internal/controller/setup.go 0.00% 4 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #3143      +/-   ##
==========================================
+ Coverage   43.79%   44.73%   +0.93%     
==========================================
  Files         375      377       +2     
  Lines       30575    31508     +933     
==========================================
+ Hits        13390    14094     +704     
- Misses      16276    16489     +213     
- Partials      909      925      +16     
Flag Coverage Δ
unittests 44.73% <64.70%> (+0.93%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
cmd/main.go 6.60% <0.00%> (-0.08%) ⬇️
...al/controller/datadoggenericresource/controller.go 86.18% <89.18%> (+7.37%) ⬆️
internal/controller/setup.go 71.71% <0.00%> (-1.94%) ⬇️
...al/controller/datadoggenericresource_controller.go 0.00% <0.00%> (ø)

... and 13 files with indirect coverage changes


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 72bc0a0...f2af21b. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@tbavelier
tbavelier force-pushed the tbavelier/thousands-of-ddgrs branch from d08e2b9 to b6051a5 Compare June 15, 2026 15:10
@tbavelier
tbavelier force-pushed the tbavelier/thousands-of-ddgrs branch from b6051a5 to 29c92c9 Compare June 16, 2026 09:05
@tbavelier tbavelier changed the title Improve DatadogGenericResource reconciliation at scale [CONTP-1758] Improve DatadogGenericResource reconciliation at scale Jun 16, 2026
@tbavelier
tbavelier force-pushed the tbavelier/thousands-of-ddgrs branch from d4a9c5c to 136adf5 Compare June 16, 2026 09:58
@tbavelier
tbavelier marked this pull request as ready for review June 16, 2026 10:03
@tbavelier
tbavelier requested a review from a team June 16, 2026 10:03
@tbavelier
tbavelier requested a review from a team as a code owner June 16, 2026 10:03

@drichards-87 drichards-87 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some suggestions from Docs and approved the PR.

Comment thread docs/datadog_generic_resource.md Outdated
Comment thread docs/datadog_generic_resource.md Outdated
Comment thread docs/datadog_generic_resource.md Outdated
Comment thread docs/datadog_generic_resource.md Outdated
Comment thread docs/datadog_generic_resource.md Outdated
Comment thread docs/datadog_generic_resource.md Outdated
@tbavelier
tbavelier merged commit a64eed4 into main Jul 2, 2026
36 of 38 checks passed
@tbavelier
tbavelier deleted the tbavelier/thousands-of-ddgrs branch July 2, 2026 09:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants