{"id":"a2b5411e-ff9e-4018-88bb-f0c1d33deee7","shortId":"sf8cYr","kind":"skill","title":"dt-obs-predictive-analytics","tagline":"Predictive analytics for Dynatrace — time series forecasting with the timeseries-forecast tool, capacity saturation planning, trend and anomaly detection across hosts, services, and infrastructure.","description":"# Predictive Analytics Skill\n\nForecast resource saturation, detect trends, analyze anomalies, and characterize signal behavior using DQL and Dynatrace analyzer tools.\n\n## Analysis Disciplines\n\n| # | Discipline | Use when … |\n|---|------------|-----------|\n| 1 | **Forecast and Prediction** | Predicting future metric values for capacity planning, cost estimation, or proactive alerting |\n| 2 | **Detecting Changes** | A metric *shifted* — find when the character of the signal changed, regardless of whether it crossed a limit |\n| 3 | **Detecting Violations** | A metric is *currently out of bounds* — find entities that exceed or fall below an acceptable range |\n| 4 | **Timeseries Characteristics** | Characterizing a signal's seasonality, noise level, and trend before further analysis |\n\n---\n\n## Choosing the Right Detection Tool\n\n**The single most important decision**: are you asking \"did this metric *change*?\" or \"is this metric *currently wrong*?\"\n\n| Question | Tool | Why |\n|----------|------|-----|\n| \"Did this metric change in the last N hours?\" | `timeseries-novelty-detection` | Detects *when* the signal's character changed (spike, step, trend onset, variability shift) without requiring a known acceptable limit |\n| \"Which services spiked or dropped recently?\" | `timeseries-novelty-detection` with `SPIKE` / `CHANGE_IN_VALUES` | Finds the specific entities and timestamps where change occurred; returns empty for stable signals |\n| \"When did CPU start trending up?\" | `timeseries-novelty-detection` with `TREND_IN_VALUES` | Pinpoints the onset of a directional shift |\n| \"Which hosts are currently above 90% CPU?\" | `static-threshold-analyzer` | Known fixed limit — fire alerts when exceeded | Can also be done with standard DQL queries, but the tool provides built-in violation counting, sliding window and alerting logic |\n| \"Which services are currently above their usual load?\" | `adaptive-anomaly-detector` | Learns the normal distribution from the data and flags sustained threshold violations |\n| \"Which services are high right now vs. their weekly pattern?\" | `seasonal-baseline-anomaly-detector` | Accounts for time-of-day/day-of-week patterns before deciding what is anomalous |\n\n### Decision rule in plain language\n\n- **Use `timeseries-novelty-detection`** when the question contains \"changed\", \"shifted\", \"spiked\", \"dropped\", \"started\", \"when did\", or \"did anything unusual happen\". The tool answers *whether* a change occurred and *when*. It requires no predefined threshold.\n- **Use an anomaly detector** (`adaptive`, `seasonal`, or `static`) when the question is about *ongoing* or *current* state relative to an expected range: \"which are highest\", \"who is violating\", \"what is above X\". These tools count violation samples inside a sliding window — they confirm *how long* something has been bad, not whether the signal changed.\n\n> **Pitfall**: Running `adaptive-anomaly-detector` on a broad fleet to answer \"which service changed load?\" typically flags every service that has *any* variation, producing low-signal results. Use `timeseries-novelty-detection` first to identify entities where the load character genuinely shifted, then use the anomaly detectors to measure the severity of those specific signals.\n\n## When to Use This Skill\n\n- **Capacity**: \"Which hosts will hit 90% CPU in the next 30 days?\"\n- **Forecast**: \"Forecast service request volume for the next 7 days\"\n- **Trend**: \"Is memory usage growing across our Kubernetes nodes?\"\n- **Anomaly**: \"Which services have unusual error rates right now?\"\n- **Baseline**: \"How does today's traffic compare to last week?\"\n- **Signal profile**: \"Is this metric seasonal or trending before I set up alerting?\"\n\n---\n\n## Important Constraints\n\n**Dynatrace Forecast Analyzer supports univariate forecasting only** — predicting one metric based on its own historical values. Multivariate forecasting (using multiple metrics as inputs) requires external tools (Python, R, Azure AutoML).\n\n**Tooling Rule**: Run analyses using Dynatrace tools: `timeseries-forecast`, `adaptive-anomaly-detector`, `seasonal-baseline-anomaly-detector`, `static-threshold-analyzer`, and `timeseries-novelty-detection`. Use `execute-dql` for DQL queries.\n\n**Result Analysis Rule**: Always analyse and summarise results directly from the raw tool output. Derive all numbers, trends, and conclusions inline.\n\n---\n\n## Result Presentation Format\n\nAlways present forecast results as a structured table:\n\n| Column | Content |\n|--------|---------|\n| Rank | 🥇 🥈 🥉 ordered by urgency or magnitude |\n| Signal / Entity | Metric name and entity or dimension |\n| Last Actual | Most recent non-null value from the historical series |\n| Forecast | Point forecast at the end of the horizon |\n| Range | Lower – Upper confidence band at the same horizon point |\n| Trend | % change from Last Actual to Forecast: 🔴 >+20% / 🟠 +5–20% / 🟢 ±5% stable / 🔵 −5–20% declining / ⚫ <−20% sharp drop |\n| Action | ✅ No action / ⚠️ Monitor / 🔴 Act now |\n\nAlways follow the table with a **Key Findings** section (3–5 bullet points, ranked by priority).\n\n---\n\n## Core DQL Techniques\n\nDQL has no native `forecast` function. For forward-looking forecasts, use `timeseries-forecast` (see `references/forecasting-analyzer.md`).\n\n### Key DQL Rules\n\n1. `timeseries` returns arrays — one value per time slot per entity\n2. `arrayLast(arr)` = most recent value; `arrayFirst(arr)` = oldest\n3. Growth = `(arrayLast - arrayFirst) / number_of_intervals`\n4. Always `filter isNotNull(field)` before sorting to avoid null ordering issues\n5. Use `toLong()` when dividing `Long` fields to avoid type errors\n6. Use `dt.smartscape.*` not deprecated `dt.entity.*` in DQL display fields; use `dt.smartscape.*` in `by:{}` grouping clauses for entity-level queries\n\n---\n\n## Standard Query Patterns\n\n### Moving Average Trend\n\n```dql\ntimeseries cpu = avg(dt.host.cpu.usage), from: now()-24h, interval: 1h, by: {dt.smartscape.host}\n| fieldsAdd moving_avg = arrayMovingAvg(cpu, 4)\n| fieldsAdd current = arrayLast(cpu)\n| fieldsAdd trend = arrayLast(cpu) - arrayFirst(cpu)\n| filter isNotNull(current)\n| sort trend desc\n| limit 20\n| fields dt.smartscape.host, current, trend, moving_avg\n```\n\n### Saturation Risk Classification\n\n```dql\ntimeseries cpu = avg(dt.host.cpu.usage), from: now()-7d, interval: 1h, by: {dt.smartscape.host}\n| fieldsAdd p95 = arrayPercentile(cpu, 95)\n| fieldsAdd saturation_risk = if(p95 > 85, \"HIGH\", else: if(p95 > 70, \"MEDIUM\", else: \"LOW\"))\n| filter isNotNull(p95)\n| sort p95 desc\n| fields dt.smartscape.host, p95, saturation_risk\n```\n\n### Days to Saturation Forecast\n\n```dql\ntimeseries cpu = avg(dt.host.cpu.usage), from: now()-30d, interval: 1d, by: {dt.smartscape.host}\n| fieldsAdd current = arrayLast(cpu)\n| fieldsAdd daily_growth = (arrayLast(cpu) - arrayFirst(cpu)) / 30\n| filter isNotNull(current)\n| fieldsAdd days_to_saturation = if(daily_growth > 0, toLong((90 - current) / daily_growth), else: 9999)\n| sort days_to_saturation asc\n| limit 20\n| fields dt.smartscape.host, current, daily_growth, days_to_saturation\n```\n\n### Anomaly Scoring\n\n```dql\ntimeseries cpu = avg(dt.host.cpu.usage), from: now()-24h, interval: 1h, by: {dt.smartscape.host}\n| fieldsAdd baseline_avg = arrayAvg(cpu)\n| fieldsAdd current = arrayLast(cpu)\n| fieldsAdd anomaly_score = if(isNotNull(current) and isNotNull(baseline_avg), abs(current - baseline_avg), else: 0)\n| sort anomaly_score desc\n| limit 20\n| fields dt.smartscape.host, current, baseline_avg, anomaly_score\n```\n\n### Metric Discovery\n\nBefore forecasting, discover available metrics by keyword:\n\n```dql\nmetrics from: now() - 1h\n| filter contains(metric.key, \"cpu\")\n| summarize count(), by: {metric.key}\n| sort `count()` desc\n```\n\n---\n\n## Reference Guides\n\n- **`references/forecasting-analyzer.md`** — `timeseries-forecast` tool:\n  data requirements, parameter reference, interval selection, horizon limits, common pitfalls\n- **`references/capacity-forecasting.md`** — CPU/memory/disk/K8s saturation\n  forecasts; multi-resource risk scoring; days-to-saturation DQL patterns\n- **`references/anomaly-scoring.md`** — `adaptive-anomaly-detector`, `seasonal-baseline-anomaly-detector`,\n  `static-threshold-analyzer`; DQL deviation scoring\n- **`references/novelty-detection.md`** — `timeseries-novelty-detection` tool: spike, drop, step change,\n  trend onset, and variability change detection; all novelty types; parameter reference; worked examples\n- **`references/trend-detection.md`** — `timeseries-novelty-detection` for trend onset and change points;\n  week-over-week joins; growth rate and acceleration detection\n\n## Related Skills\n\n- **dt-dql-essentials** — DQL syntax, `timeseries` command rules, array function reference\n- **dt-obs-hosts** — Host and process metrics catalog\n- **dt-obs-services** — Service RED metrics for service-level trend analysis\n- **dt-obs-problems** — Davis AI problem history for anomaly correlation","tags":["obs","predictive","analytics","dynatrace","for","agent-skills","ai-agents","claude-code","devops","dql","mcp","observability"],"capabilities":["skill","source-dynatrace","skill-dt-obs-predictive-analytics","topic-agent-skills","topic-ai-agents","topic-claude-code","topic-devops","topic-dql","topic-dynatrace","topic-mcp","topic-observability"],"categories":["dynatrace-for-ai"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/Dynatrace/dynatrace-for-ai/dt-obs-predictive-analytics","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add Dynatrace/dynatrace-for-ai","source_repo":"https://github.com/Dynatrace/dynatrace-for-ai","install_from":"skills.sh"}},"qualityScore":"0.489","qualityRationale":"deterministic score 0.49 from registry signals: · indexed on github topic:agent-skills · 78 github stars · SKILL.md body (8,897 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-18T18:56:48.554Z","embedding":null,"createdAt":"2026-05-11T18:57:14.527Z","updatedAt":"2026-05-18T18:56:48.554Z","lastSeenAt":"2026-05-18T18:56:48.554Z","tsv":"'+20':700 '+5':701 '-24':840,993 '-30':933 '-7':886 '/day-of-week':321 '0':961,1023 '1':56,756 '1d':936 '1h':843,889,996,1050 '2':72,767 '20':702,706,708,869,975,1029 '3':93,726,776 '30':494,950 '4':113,783,851 '5':703,705,727,795 '6':806 '7':504 '70':907 '85':902 '90':241,489,963 '95':896 '9999':968 'ab':1018 'acceler':1153 'accept':111,184 'account':315 'across':26,511 'act':715 'action':711,713 'actual':663,697 'adapt':285,372,425,590,1096 'adaptive-anomaly-detector':284,424,589,1095 'ai':1196 'alert':71,251,274,546 'also':255 'alway':617,638,717,784 'analys':582,618 'analysi':51,127,615,1190 'analyt':5,7,32 'analyz':39,49,246,551,601,1107 'anomal':327 'anomali':24,40,286,313,370,426,469,515,591,596,984,1009,1025,1035,1097,1102,1200 'answer':356,433 'anyth':351 'arr':769,774 'array':759,1166 'arrayavg':1002 'arrayfirst':773,779,860,948 'arraylast':768,778,854,858,941,946,1006 'arraymovingavg':849 'arraypercentil':894 'asc':973 'ask':140 'automl':578 'avail':1042 'averag':831 'avg':836,848,875,882,929,989,1001,1017,1021,1034 'avoid':791,803 'azur':577 'bad':416 'band':687 'base':559 'baselin':312,524,595,1000,1016,1020,1033,1101 'behavior':44 'bound':102 'broad':430 'built':267 'built-in':266 'bullet':728 'capac':19,65,484 'catalog':1177 'chang':74,85,144,157,173,198,208,342,359,421,436,694,1120,1125,1143 'charact':81,172,463 'character':42,116 'characterist':115 'choos':128 'classif':878 'claus':821 'column':646 'command':1164 'common':1077 'compar':530 'conclus':633 'confid':686 'confirm':410 'constraint':548 'contain':341,1052 'content':647 'core':733 'correl':1201 'cost':67 'count':270,402,1056,1060 'cpu':217,242,490,835,850,855,859,861,881,895,928,942,947,949,988,1003,1007,1054 'cpu/memory/disk/k8s':1080 'cross':90 'current':99,149,239,279,383,853,864,872,940,953,964,978,1005,1013,1019,1032 'd':887,934 'daili':944,959,965,979 'data':294,1069 'davi':1195 'day':320,495,505,922,955,970,981,1089 'days-to-satur':1088 'decid':324 'decis':137,328 'declin':707 'deprec':810 'deriv':628 'desc':867,916,1027,1061 'detect':25,37,73,94,131,166,167,195,224,337,455,606,1115,1126,1138,1154 'detector':287,314,371,427,470,592,597,1098,1103 'deviat':1109 'dimens':661 'direct':234,622 'disciplin':52,53 'discov':1041 'discoveri':1038 'display':814 'distribut':291 'divid':799 'done':257 'dql':46,260,610,612,734,736,754,813,833,879,926,986,1046,1092,1108,1159,1161 'drop':190,345,710,1118 'dt':2,1158,1170,1179,1192 'dt-dql-essenti':1157 'dt-obs-host':1169 'dt-obs-predictive-analyt':1 'dt-obs-problem':1191 'dt-obs-servic':1178 'dt.entity':811 'dt.host.cpu.usage':837,883,930,990 'dt.smartscape':808,817 'dt.smartscape.host':845,871,891,918,938,977,998,1031 'dynatrac':9,48,549,584 'els':904,909,967,1022 'empti':211 'end':679 'entiti':104,204,459,655,659,766,824 'entity-level':823 'error':520,805 'essenti':1160 'estim':68 'everi':440 'exampl':1133 'exceed':106,253 'execut':609 'execute-dql':608 'expect':388 'extern':573 'fall':108 'field':787,801,815,870,917,976,1030 'fieldsadd':846,852,856,892,897,939,943,954,999,1004,1008 'filter':785,862,911,951,1051 'find':78,103,201,724 'fire':250 'first':456 'fix':248 'flag':296,439 'fleet':431 'follow':718 'forecast':12,17,34,57,496,497,550,554,566,588,640,674,676,699,740,746,750,925,1040,1067,1082 'format':637 'forward':744 'forward-look':743 'function':741,1167 'futur':61 'genuin':464 'group':820 'grow':510 'growth':777,945,960,966,980,1150 'guid':1063 'h':841,994 'happen':353 'high':303,903 'highest':392 'histor':563,672 'histori':1198 'hit':488 'horizon':682,691,1075 'host':27,237,486,1172,1173 'hour':162 'identifi':458 'import':136,547 'infrastructur':30 'inlin':634 'input':571 'insid':405 'interv':782,842,888,935,995,1073 'isnotnul':786,863,912,952,1012,1015 'issu':794 'join':1149 'key':723,753 'keyword':1045 'known':183,247 'kubernet':513 'languag':332 'last':160,532,662,696 'learn':288 'level':122,825,1188 'limit':92,185,249,868,974,1028,1076 'load':283,437,462 'logic':275 'long':412,800 'look':745 'low':448,910 'low-sign':447 'lower':684 'magnitud':653 'measur':472 'medium':908 'memori':508 'metric':62,76,97,143,148,156,538,558,569,656,1037,1043,1047,1176,1184 'metric.key':1053,1058 'monitor':714 'move':830,847,874 'multi':1084 'multi-resourc':1083 'multipl':568 'multivari':565 'n':161 'name':657 'nativ':739 'next':493,503 'node':514 'nois':121 'non':667 'non-nul':666 'normal':290 'novelti':165,194,223,336,454,605,1114,1128,1137 'null':668,792 'number':630,780 'ob':3,1171,1180,1193 'occur':209,360 'oldest':775 'one':557,760 'ongo':381 'onset':177,231,1122,1141 'order':649,793 'output':627 'p95':893,901,906,913,915,919 'paramet':1071,1130 'pattern':309,322,829,1093 'per':762,765 'pinpoint':229 'pitfal':422,1078 'plain':331 'plan':21,66 'point':675,692,729,1144 'predefin':366 'predict':4,6,31,59,60,556 'present':636,639 'prioriti':732 'proactiv':70 'problem':1194,1197 'process':1175 'produc':446 'profil':535 'provid':265 'python':575 'queri':261,613,826,828 'question':151,340,378 'r':576 'rang':112,389,683 'rank':648,730 'rate':521,1151 'raw':625 'recent':191,665,771 'red':1183 'refer':1062,1072,1131,1168 'references/anomaly-scoring.md':1094 'references/capacity-forecasting.md':1079 'references/forecasting-analyzer.md':752,1064 'references/novelty-detection.md':1111 'references/trend-detection.md':1134 'regardless':86 'relat':385,1155 'request':499 'requir':181,364,572,1070 'resourc':35,1085 'result':450,614,621,635,641 'return':210,758 'right':130,304,522 'risk':877,899,921,1086 'rule':329,580,616,755,1165 'run':423,581 'sampl':404 'satur':20,36,876,898,920,924,957,972,983,1081,1091 'score':985,1010,1026,1036,1087,1110 'season':120,311,373,539,594,1100 'seasonal-baseline-anomaly-detector':310,593,1099 'section':725 'see':751 'select':1074 'seri':11,673 'servic':28,187,277,301,435,441,498,517,1181,1182,1187 'service-level':1186 'set':544 'sever':474 'sharp':709 'shift':77,179,235,343,465 'signal':43,84,118,170,214,420,449,478,534,654 'singl':134 'skill':33,483,1156 'skill-dt-obs-predictive-analytics' 'slide':271,407 'slot':764 'someth':413 'sort':789,865,914,969,1024,1059 'source-dynatrace' 'specif':203,477 'spike':174,188,197,344,1117 'stabl':213,704 'standard':259,827 'start':218,346 'state':384 'static':244,375,599,1105 'static-threshold-analyz':243,598,1104 'step':175,1119 'structur':644 'summar':1055 'summaris':620 'support':552 'sustain':297 'syntax':1162 'tabl':645,720 'techniqu':735 'threshold':245,298,367,600,1106 'time':10,318,763 'time-of-day':317 'timeseri':16,114,164,193,222,335,453,587,604,749,757,834,880,927,987,1066,1113,1136,1163 'timeseries-forecast':15,586,748,1065 'timeseries-novelty-detect':163,192,221,334,452,603,1112,1135 'timestamp':206 'today':527 'tolong':797,962 'tool':18,50,132,152,264,355,401,574,579,585,626,1068,1116 'topic-agent-skills' 'topic-ai-agents' 'topic-claude-code' 'topic-devops' 'topic-dql' 'topic-dynatrace' 'topic-mcp' 'topic-observability' 'traffic':529 'trend':22,38,124,176,219,226,506,541,631,693,832,857,866,873,1121,1140,1189 'type':804,1129 'typic':438 'univari':553 'unusu':352,519 'upper':685 'urgenc':651 'usag':509 'use':45,54,333,368,451,467,481,567,583,607,747,796,807,816 'usual':282 'valu':63,200,228,564,669,761,772 'variabl':178,1124 'variat':445 'violat':95,269,299,395,403 'volum':500 'vs':306 'week':308,533,1146,1148 'week-over-week':1145 'whether':88,357,418 'window':272,408 'without':180 'work':1132 'wrong':150 'x':399","prices":[{"id":"efdd7ee3-e31d-4e0b-8b58-1b30fca958af","listingId":"a2b5411e-ff9e-4018-88bb-f0c1d33deee7","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"Dynatrace","category":"dynatrace-for-ai","install_from":"skills.sh"},"createdAt":"2026-05-11T18:57:14.527Z"}],"sources":[{"listingId":"a2b5411e-ff9e-4018-88bb-f0c1d33deee7","source":"github","sourceId":"Dynatrace/dynatrace-for-ai/dt-obs-predictive-analytics","sourceUrl":"https://github.com/Dynatrace/dynatrace-for-ai/tree/main/skills/dt-obs-predictive-analytics","isPrimary":false,"firstSeenAt":"2026-05-11T18:57:14.527Z","lastSeenAt":"2026-05-18T18:56:48.554Z"}],"details":{"listingId":"a2b5411e-ff9e-4018-88bb-f0c1d33deee7","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"Dynatrace","slug":"dt-obs-predictive-analytics","github":{"repo":"Dynatrace/dynatrace-for-ai","stars":78,"topics":["agent-skills","ai-agents","claude-code","devops","dql","dynatrace","mcp","observability"],"license":"apache-2.0","html_url":"https://github.com/Dynatrace/dynatrace-for-ai","pushed_at":"2026-05-15T16:06:09Z","description":"Skills, prompts, and instructions for building AI agents on top of Dynatrace production context","skill_md_sha":"ef8ecacdb176601f0a933df085067d1824b692db","skill_md_path":"skills/dt-obs-predictive-analytics/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/Dynatrace/dynatrace-for-ai/tree/main/skills/dt-obs-predictive-analytics"},"layout":"multi","source":"github","category":"dynatrace-for-ai","frontmatter":{"name":"dt-obs-predictive-analytics","license":"Apache-2.0","description":"Predictive analytics for Dynatrace — time series forecasting with the timeseries-forecast tool, capacity saturation planning, trend and anomaly detection across hosts, services, and infrastructure."},"skills_sh_url":"https://skills.sh/Dynatrace/dynatrace-for-ai/dt-obs-predictive-analytics"},"updatedAt":"2026-05-18T18:56:48.554Z"}}