Rediger

Del via


Query trend data with OData aggregation

Azure DevOps Services | Azure DevOps Server | Azure DevOps Server 2022

Analytics stores daily snapshots of every work item in two entity sets: WorkItemSnapshot (tracks field values like state and effort) and WorkItemBoardSnapshot (tracks board column positions). Because each entity contains one row per work item per day, these tables grow quickly. Use OData aggregation extensions to filter by date and group results before returning data to a client tool.

This article shows how to build trend queries by date range and by iteration, using $apply with filter, groupby, and aggregate.

Note

The Analytics service is automatically enabled and supported in production for all services within Azure DevOps Services. Power BI integration and access to the OData feed of the Analytics service are generally available. You're encouraged to use the Analytics OData feed and provide feedback.

Available data is version-dependent. The latest supported version of the OData API is v2.0, and the latest preview version is v4.0-preview. For more information, see OData API versioning.

Note

The Analytics service is automatically installed and supported in production for all new project collections for Azure DevOps Server 2020 and later versions. Power BI integration and access to the OData feed of the Analytics service are generally available. You're encouraged to use the Analytics OData feed and provide feedback. If you upgrade from Azure DevOps Server 2019, you can install the Analytics service during upgrade.

Available data is version-dependent. The latest supported version of the OData API is v2.0, and the latest preview version is v4.0-preview. For more information, see OData API versioning.

Note

The examples shown in this article are based on an Azure DevOps Services URL. Substitute your Azure DevOps Server URL as needed.

https://{servername}:{port}/tfs/{OrganizationName}/{ProjectName}/_odata/{version}/

Tip

You can use AI to help with this task later in this article, or see Enable AI assistance with Azure DevOps MCP Server to get started.

Prerequisites

Category Requirements
Access levels - Project member.
- At least Basic access.
Permissions By default, project members have permission to query Analytics and create views. For more information about other prerequisites regarding service and feature enablement and general data tracking activities, see Permissions and prerequisites to access Analytics.

Query trend data by date range

When you query snapshot tables, follow two requirements:

  1. Filter by date — each table contains one row per work item per day, so an unfiltered query returns a very large result set.
  2. Group by date — if you omit the date grouping, the response includes a warning.

The following query returns a daily bug count by state for March 2016:

https://analytics.dev.azure.com/{OrganizationName}/{ProjectName}/_odata/{version}/WorkItemSnapshot?
  $apply=
    filter(DateValue ge 2016-03-01Z and DateValue le 2016-03-31Z and WorkItemType eq 'Bug')/
    groupby((DateValue, State), aggregate($count as Count))
  &$orderby=DateValue

Returns:

{
  "value": [
    { "DateValue": "2016-03-01T00:00:00-08:00", "State": "Active", "Count": 2666 },
    { "DateValue": "2016-03-01T00:00:00-08:00", "State": "Closed", "Count": 51408 }
  ]
}

This query returns at most 31 days multiplied by the number of bug states (Active, Resolved, Closed) - 93 rows maximum, regardless of how many work items exist.

Query trend data by iteration

Instead of hard-coding dates, filter by iteration and reference its start and end dates so the date range adjusts automatically. The Iteration/EndDate eq null check handles iterations that don't have an end date yet.

https://analytics.dev.azure.com/{OrganizationName}/{ProjectName}/_odata/{version}/WorkItemSnapshot?
  $apply=
    filter(WorkItemType eq 'Bug')/
    filter(Iteration/IterationName eq 'Sprint 99')/
    filter(DateValue ge Iteration/StartDate and (Iteration/EndDate eq null or DateValue le Iteration/EndDate))/
    groupby((DateValue, State), aggregate($count as Count))
  &$orderby=DateValue

Returns:

{
  "value": [
    { "DateValue": "2016-04-04T00:00:00-07:00", "State": "Active", "Count": 320 },
    { "DateValue": "2016-04-04T00:00:00-07:00", "State": "Closed", "Count": 38 }
  ]
}

Note

If your query on snapshot tables doesn't include $apply or $select, the response returns a warning. Always use aggregation with snapshot entity sets.

Use AI to build trend queries

If you configure the Azure DevOps MCP Server, you can use AI assistants to help construct and troubleshoot trend queries against snapshot entity sets.

Example prompts

Task Example prompt
Bug trend by date range Write an OData trend query that shows the daily bug count by state over the last 30 days in <ProjectName>.
Sprint snapshot Create an OData query against WorkItemSnapshot that shows work item counts grouped by date for the current sprint in <ProjectName>.
Filter by iteration Generate an OData trend query that uses the iteration start and end dates from <IterationName> to show story point burndown in <ProjectName>.
Board column trend Write an OData query against WorkItemBoardSnapshot to track work items by board column over the past two weeks in <ProjectName> in the <OrganizationName> organization.
Optimize performance My WorkItemSnapshot trend query for <ProjectName> is timing out. Suggest specific date filters and aggregation to reduce the row count without losing the key metrics.
Compare sprints Create an OData trend query that compares bug counts between <SprintName> and the previous sprint in <ProjectName> in the <OrganizationName> organization.
Remaining work trend Write an OData trend query that shows the daily sum of remaining work grouped by Area Path for the current iteration in <ProjectName>.
Detect state changes Create an OData snapshot query that tracks how many work items moved from Active to Resolved each day over the past <NumberOfDays> days in <ProjectName>.
Scope change analysis Generate an OData trend query that shows the daily count of user stories added or removed from <SprintName> by comparing WorkItemSnapshot data in <ProjectName>.

Tip

If you're using Visual Studio Code, agent mode is especially helpful for iterating on trend queries—refining date ranges, troubleshooting $apply syntax, and validating snapshot results.

Next step