What is collected · collector 0.6.0 · measured 19 October 2026
Exactly what is read, what leaves, and how big it is.
The collector reads what Windows already records about Delivery Optimization, and a report is a few kilobytes. This page lists every source, says what is hashed, truncated, or dropped before anything is sent, and gives the size of each report, measured.
A routine report, compressed
1,758 B
43% of the 4,096 B budget
- Per device, a day
- 2.5 KB
- 10,000 devices, a day
- 25.2 MB
- 10,000 devices, a month
- 755.5 MB
Daily reports, request bodies only. The signed headers add about 1.7 KB a request: see “What the budgets leave out”.
In short
- Reads
- Delivery Optimization’s own status, log and settings, its registry keys, what the Enrollment Status Page recorded, and some network and device facts. No setting on the device is changed.
- Sends
- Two kinds of report, an inventory and telemetry, signed by the device and posted to your own ingest endpoint in your Azure subscription. No report goes to the DoctorDO project.
- Weighs
- A routine telemetry report is 1,758 B compressed, and an inventory is 5,322 B. A bad day is 4,462 B.
- Never
- File contents, credentials, full URLs, or who is signed in. User names are scrubbed from the text it keeps, and peer addresses are hashed or cut to a network.
1 · What the collector reads
Nine kinds of fact, each with its source.
The collector changes none of what it reads. It runs as SYSTEM, once per run, and every source below is a Windows cmdlet, class, registry key, or log. A source it cannot read is named in the report with the reason (not collected), never filled in or shown as a pass.
Delivery Optimization status and performance
What Delivery Optimization itself records about each download. This is the heart of the data, and every source is a cmdlet or log that Windows ships.
| What | Read from |
|---|---|
| Every download job in the cache: file ID, size, bytes from each of the five sources (the HTTP source, usually Microsoft’s CDN; Connected Cache; and LAN, group, and internet peers), download mode, status, priority, calling app, the host it came from, the cache server, expiry, and how long it took | Read fromGet-DeliveryOptimizationStatusMicrosoft Learn: Monitor Delivery Optimization (opens in a new tab), DOSwarmStats (opens in a new tab) |
| The peers behind those jobs: address (hashed on the device before anything is kept), type, bytes sent and received, whether the connection was made | Read fromThe CIM class behind Get-DeliveryOptimizationStatus -PeerInfo (root/Microsoft/Windows/DeliveryOptimization, MSFT_DeliveryOptimizationFilePeerInfo); the cmdlet itself if the class is missingMicrosoft Learn: Monitor Delivery Optimization (opens in a new tab) |
| Counters: peers now, Connected Cache connections, average download rate, and bytes per source | Read fromGet-DeliveryOptimizationPerfSnap -Verbose. Bytes per source come from its verbose text when that parses, otherwise they are summed from the job list, and the report says whichMicrosoft Learn: Monitor Delivery Optimization (opens in a new tab) |
| Errors (HRESULT codes, whether the log writes them as 0x8… or as hr: 8007274c), the peer connections DO tried, and the cache servers it named | Read fromGet-DeliveryOptimizationLog and Get-DeliveryOptimizationLogAnalysis -ListConnections. A fleet run reads the log as it is on disk and never flushes it; only the local bundle flushes, which stops DoSvc for a momentMicrosoft Learn: Monitor Delivery Optimization (opens in a new tab) |
| The settings in force, and who set each one (policy, Group Policy, the Settings app, or the default) | Read fromGet-DOConfig -VerboseMicrosoft Learn: Monitor Delivery Optimization (opens in a new tab), Delivery Optimization reference (opens in a new tab) |
| Whether the Delivery Optimization service is running, its start type, and whether it is listening on TCP 7680 | Read fromGet-Service DoSvc, and its own TCP table through Get-NetTCPConnection -OwningProcessMicrosoft Learn: Get-NetTCPConnection (opens in a new tab), Delivery Optimization frequently asked questions (opens in a new tab) |
Policy and registry values
The whole of each Delivery Optimization registry key is read, every value name exactly as found, because probing for expected names finds nothing when Microsoft’s pages disagree on a name.
| What | Read from |
|---|---|
| Six keys, up to 256 values each, as found: the policy key, the MDM (Policy CSP) key, the service configuration, the user settings, the NetworkService profile’s settings (the Settings app’s choices), and the service key | Read fromHKLM\SOFTWARE\Policies\Microsoft\Windows\DeliveryOptimization; HKLM\SOFTWARE\Microsoft\PolicyManager\current\device\DeliveryOptimization; HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\DeliveryOptimization\Config and \Settings; HKU\S-1-5-20\Software\Microsoft\Windows\CurrentVersion\DeliveryOptimization\Settings; HKLM\SYSTEM\CurrentControlSet\Services\DoSvcMicrosoft Learn: Delivery Optimization reference (opens in a new tab), Policy CSP: DeliveryOptimization (opens in a new tab) |
| Whether an MDM policy blocks its Group Policy twin | Read fromHKLM\SOFTWARE\Microsoft\PolicyManager\current\device\ControlPolicyConflict, value MDMWinsOverGPMicrosoft Learn: Policy CSP: DeliveryOptimization (opens in a new tab) |
| Which management service delivered a setting (Intune or another) | Read fromHKLM\SOFTWARE\Microsoft\Enrollments (provider ID, discovery URL, enrolment type, Intune device ID)Microsoft Learn: DMClient CSP (opens in a new tab) |
| Where Windows Update gets its updates (Windows Update for Business, WSUS, or Configuration Manager) | Read fromHKLM\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU, value UseWUServer, and the Configuration Manager client service (CcmExec) |
| Windows build, update revision, edition, display version, and install date | Read fromHKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersionMicrosoft Learn: DevDetail CSP (opens in a new tab) |
Network facts
The things that decide whether devices can find and reach each other.
| What | Read from |
|---|---|
| The adapter Delivery Optimization uses, its type (Ethernet, Wi-Fi, cellular, VPN), its subnet, and which adapter carries the default route and gateway | Read fromGet-NetRoute, Get-NetAdapter, and Get-NetIPAddress. An adapter counts as VPN when it looks like one by DoctorDO’s own keyword list plus the VPN keywords Delivery Optimization is configured with; Delivery Optimization’s own decision may differ |
| Proxy settings: whether one is configured, per-user or device-wide, auto-detect, bypass for local addresses, and the proxy auto-config (PAC) script’s host | Read fromThe machine policy key (HKLM\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\Internet Settings) and the WinINET values of the profile the collector runs in, which in a fleet run is SYSTEM’s, and netsh winhttp show proxyMicrosoft Learn: Delivery Optimization and proxy servers (opens in a new tab) |
| What each PAC script in force says about Delivery Optimization’s endpoints. The script is downloaded and read on the device, and only the answer leaves it | Read fromThe PAC URLs found in those values and in the signed-in users’ and NetworkService’s hives, fetched by the collector (skipped by -SkipConnectivityChecks)Microsoft Learn: Delivery Optimization and proxy servers (opens in a new tab) |
| DHCP options 234 (Group ID) and 235 (Connected Cache), asked for only when Delivery Optimization itself would read them | Read fromDhcpRequestParams on the adapter DO uses, called from the collector (not available under Constrained Language Mode, where it is reported as not collected)Microsoft Learn: Delivery Optimization reference (opens in a new tab) |
| The Active Directory site name | Read fromHKLM\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters, value DynamicSiteName (no directory query) |
| Firewall rules that decide peering: inbound Allow rules for TCP 7680, outbound Block rules for TCP 7680 and UDP 3544, and whether local rules are merged | Read fromGet-NetFirewallRule with its port, program, service and address filters, and Get-NetFirewallProfile, from the active policy storeMicrosoft Learn: Delivery Optimization frequently asked questions (opens in a new tab) |
| Whether the connection is metered | Read fromThe Windows Runtime NetworkInformation API (Windows PowerShell 5.1 only) |
| A salted hash of the public egress address. Off unless an administrator turns it on | Read fromThe Delivery Optimization geo service’s answer, or a URL you name with -PublicIpProbeUri |
Connectivity probes
Whether this device can reach what Delivery Optimization needs. Probes go only to Microsoft’s documented endpoints, hosts the device itself used, the Connected Cache server in use, and peers it already knows.
| What | Read from |
|---|---|
| For each endpoint in the module’s manifest (24 of them, from Microsoft’s endpoint lists): DNS, TCP, TLS with the class of the certificate’s issuer, judged from its issuing chain rather than from the certificate’s own subject name, an HTTP request, and a one-byte range request to see whether a proxy strips byte ranges | Read fromData/endpoints.json, tested on hosts the device used or Microsoft documents. The range request goes to a file the device downloaded itself; its URL is used in memory and never stored or sentMicrosoft Learn: Delivery Optimization endpoints (opens in a new tab), Delivery Optimization and proxy servers (opens in a new tab) |
| The Delivery Optimization geo service’s answer: the cache server it assigns, its DHCP flag, a captive portal | Read fromOne GET to https://geo.prod.do.dsp.mp.microsoft.com/geo?doClientVersion=<OS version>, through the proxy Windows would useMicrosoft Learn: Delivery Optimization endpoints (opens in a new tab) |
| Whether the Connected Cache server is reachable and serving | Read fromTCP 80 and an HTTP probe to the cache host, plus the bytes the job list says it deliveredMicrosoft Learn: Delivery Optimization reference (opens in a new tab) |
| Whether peers accept connections | Read fromA TCP connect to port 7680 on peers the device already knows from its peer listMicrosoft Learn: Delivery Optimization frequently asked questions (opens in a new tab) |
| Whether Teredo is working and can find its server: its operational state (qualified, dormant, or offline), not only how it is configured | Read fromA DNS lookup of win1910.ipv6.microsoft.com, and Teredo’s state from the classes behind Get-NetTeredoState and Get-NetTeredoConfiguration (netsh interface teredo show state when they cannot be read). The UDP port itself is not probedMicrosoft Learn: Required firewall exceptions for Teredo (opens in a new tab) |
| The limits | Read fromProbes run in parallel within each of two batches, one after the other. First the endpoint health probes: 4 seconds a probe and 40 seconds in all. Then the connectivity checks: 5 seconds a probe and 60 seconds in all. At most 88 checks plus 40 endpoint results. Endpoint results are reused for 6 hours by default (-EndpointCacheMinutes). -SkipConnectivityChecks turns all of it off, and the checks are then reported as not collected, never as passed |
Device vitals
The facts that change from one report to the next.
| What | Read from |
|---|---|
| Free space on the system drive and on the drive that holds the cache | Read fromWin32_LogicalDisk (local fixed disks only)Microsoft Learn: Win32_LogicalDisk class (opens in a new tab) |
| Battery: on battery or not, and the charge | Read fromWin32_Battery |
| How much the cache holds, as a total in bytes | Read fromThe size of the files in the cache folder. Names and contents are not read |
| Whether DoSvc can use its cache folder: its access for NETWORK SERVICE and NT SERVICE\DoSvc as full, partial or none, how many Deny entries, and whether dosvcState.dat exists | Read fromGet-Acl on the cache folder, compared by SID so it does not depend on the display language |
| The active power plan, and the Unified Update Stack version | Read fromWin32_PowerPlan (root/cimv2/power), and %ProgramData%\Microsoft\Windows\UUS\State\_active.uusver, a file Microsoft’s troubleshooter reads but does not document (to-verify) |
On-device diagnosis signals
Three counters that only the device can know. A device sends the counter, never a verdict; the thresholds and wording live in the portal (ADR-0040).
| What | Read from |
|---|---|
| How often DoSvc terminated unexpectedly in the last 7 days (sent only when above 0, at most 99) | Read fromSystem event log, Service Control Manager events 7031 and 7034 for the service’s display name, through Get-WinEvent -FilterHashtable. Only the event ID, provider, time and first data value are read, never the message textMicrosoft Learn: Get-WinEvent (opens in a new tab), Service Control Manager events 7031 and 7034 (opens in a new tab) |
| The mean hours a day the device was powered on over 7 days, in whole hours (an upper bound: sleep is not subtracted) | Read fromSystem event log, Kernel-General events 12 and 13; the OS install date and the oldest System record decide whether the device is too new to judgeMicrosoft Learn: Troubleshoot unexpected reboots using System event logs (opens in a new tab), Win32_OperatingSystem class (opens in a new tab) |
| Which connectivity checks changed result at least twice in 7 days (the eight most, each counted up to 99) | Read fromThe collector’s own state file, not Windows |
| The limits | Read fromAt most 5,000 events and 5 seconds for the reads together, run at most once every 24 hours, with the answer (or the failure) kept in the state file. A read that fails is named in notCollected, so it is never mistaken for a healthy week |
Per-source download telemetry (collector 0.4.0)
Where each device’s content came from, and how long it took, by host. It adds no new read: it is worked out from the job list the collector already has.
| What | Read from |
|---|---|
| For each job that has finished (status Complete or Caching) since the last report: bytes, number of jobs, and time, per Connected Cache server (at most 4 named) and per HTTP host (at most 8 named); the rest fold into one row | Read fromGet-DeliveryOptimizationStatus: CacheHost, the host of SourceURL, BytesFromCacheServer, BytesFromHttp, DownloadDurationMicrosoft Learn: Monitor Delivery Optimization (opens in a new tab), DOSwarmStats (opens in a new tab) |
| A job’s time counts for a source only if that source delivered at least 90% of its bytes and at least 4 MiB, because Windows records one duration for the whole job | Read fromDownloadDuration, the whole job including waits for peers |
| Which jobs have been counted already, so each is counted once: up to 2,000 file IDs | Read fromThe collector’s own state file on the device. They are not sent |
Inventory: who and what the device is
Read once, then sent only when it changes (and weekly regardless). Windows already holds all of it, so no Microsoft Graph lookup is needed for the device itself.
| What | Read from |
|---|---|
| Join type, Entra device ID and tenant ID | Read fromdsregcmd /status, parsedMicrosoft Learn: Troubleshoot devices by using the dsregcmd command (opens in a new tab) |
| Whether the device is enrolled in Intune (or another service), the Intune device ID, and the enrolment type | Read fromThe Enrollments keys and the DMClient CSP’s EntDMID, with the device certificate as a fallbackMicrosoft Learn: DMClient CSP (opens in a new tab), DevDetail CSP (opens in a new tab) |
| Manufacturer, model, BIOS version, processor name and logical cores, TPM presence and version, and the kind and size of each physical disk | Read fromDevDetail CSP values, Win32_ComputerSystem, HKLM\HARDWARE\DESCRIPTION\System\BIOS, Win32_Processor, Win32_Tpm, and MSFT_PhysicalDiskMicrosoft Learn: DevDetail CSP (opens in a new tab) |
| Chassis type, memory, whether it is virtual, the baseboard serial number (hashed on the device), and whether it is a Configuration Manager client with its site code | Read fromWin32_SystemEnclosure, Win32_ComputerSystem, Win32_BaseBoard, and the CcmExec service with root\ccm SMS_Authority |
| The connectivity matrix: every check’s result, target, latency and reason code | Read fromThe probes above. Later reports carry only the results that changed |
Autopilot provisioning (Enrollment Status Page)
What the device recorded while Windows Autopilot set it up, sent in the inventory. A device that never showed the Enrollment Status Page has nothing here and sends no such section.
| What | Read from |
|---|---|
| What the Enrollment Status Page tracked: for each Win32 app (up to 30, identified by its Intune app ID), whether it was in device or account setup, its installation state, whether it needed a reboot, and when its first and last status were logged; and when the page itself first and last logged a status | Read fromHKLM\SOFTWARE\Microsoft\Windows\Autopilot\EnrollmentStatusTracking, read on every run (registry values only, at most 3,000 keys)Microsoft Learn: EnrollmentStatusTracking CSP (opens in a new tab), Troubleshooting the Enrollment Status Page (opens in a new tab) |
| What Delivery Optimization downloaded around provisioning: the job list summed by priority (jobs, bytes from each source, time), the jobs smaller than the minimum file size to cache, and the 10 largest jobs with their size, sources, time, and calling app (up to 64 characters) | Read fromGet-DeliveryOptimizationStatus, read once within 7 days of the page’s last status (or of the Windows install date) and then kept in the state file, so later reports carry the same snapshotMicrosoft Learn: Monitor Delivery Optimization (opens in a new tab) |
2 · What leaves the device in a fleet report
Two reports, and a lot that stays behind.
Reading is not sending. Most of what is read is summed, shortened, hashed, or left out before a report is made, and a fleet run applies the -Anonymise profile unless you turn it off.
The two kinds of report
| Report | When it is sent | What it holds | Compressed |
|---|---|---|---|
| Inventory | On a device’s first run, whenever its change-detection hash changes, and at least every 7 days (-KeyframeDays, 1 to 30). A new subnet, gateway, egress hash, DHCP read, or power plan does not count as a change: those travel in telemetry. | Identity and management, hardware, Windows build, network, every Delivery Optimization setting with who set it, firewall rules, the full connectivity matrix, and, on a device that showed the Enrollment Status Page, the Autopilot provisioning section. | 5,322 B |
| Telemetry | On every run, after the inventory when both are due. A run is one Intune remediation run: daily in the deployment guide (see “How often”). | What happened since the last report, bounded: the 25 biggest jobs and one row for the rest, aggregated peers and connections, only the connectivity results that changed, grouped errors, counter changes, vitals, diagnosis counters, and per-source telemetry. | 1,758 B routine |
- Minified JSON, then gzip, posted over TLS 1.2 or later to
https://<host>/v1/ingest, your own deployment. Plain http, other paths and query strings are refused. - Each request is signed with the private key of the device’s Entra device certificate, which the key never leaves. No key, token, or password is configured anywhere, and no TLS client certificate is presented. The certificate (its public part) travels in a header, so your ingest knows the Entra device ID from every request.
- The exchange is one way: only the HTTP status code is used, and the reply’s body is never read. After a 429, 401, or 503 the collector backs off and sends nothing until the wait is over.
- State is committed only after the service accepts a report (HTTP 202). A report over 64 KB compressed is not sent at all.
What happens to each value
A fleet run, with -Anonymise on, as it is by default. Sent as is means the value leaves unchanged, so read those rows first. The hashes are pseudonyms, not anonymity: a hashed address can be recovered by trying candidates once the salt is known, which for peers, egress, Group IDs, and non-Microsoft hosts is derived from your tenant ID. Treat them as the values they stand for.
32 values
| Value | What happens | Detail | Report |
|---|---|---|---|
| Entra device ID | Sent as is | In the inventory, and as the subject of the device certificate that signs every request. It is the key that identifies the device, so -Anonymise does not remove it. | Report: Both |
| Entra tenant ID, Intune device ID, Configuration Manager site code | Sent as is | Also kept under -Anonymise. | Report: Inventory |
| Host name | Dropped | Not sent while -Anonymise is on, which it is by default in fleet mode. The portal then shows the name from your own Entra directory. | Report: Not sent |
| Device ID (deviceId) | Hashed | SHA-256 of host name, machine GUID, and a random salt that stays in the device’s protected state file. It matches nothing on any other device. | Report: Both |
| Baseboard serial number | Hashed | Always a salted SHA-256 with the same per-device salt; never the serial. A placeholder serial is reported as not collected. | Report: Inventory |
| User names and profile paths | Scrubbed | Nothing reads who is signed in. Where a user name appears in text the collector keeps (log lines, error samples, and firewall rules’ program paths and display names), it is replaced: the folder after \Users\ in a path on any drive, with either slash, including a name with a space when the path goes on after it; everything after the server in a UNC path; the account in AzureAD\, MicrosoftAccount\ and DOMAIN\user with an upper-case domain; and user SIDs. E-mail addresses and UPNs become <upn>. Still not caught: a lower-case domain (contoso\jsmith), the part of an account name after a space, and a name written in free text. | Report: Not sent |
| Local IP address | Truncated | Reduced to its subnet (10.20.4.71 becomes 10.20.4.0/22). The subnet is sent in clear, also under -Anonymise, because sites are built from it. | Report: Both |
| Default gateway | Hashed | Under -Anonymise, ip: and 16 hex characters from a per-device salt. | Report: Inventory |
| Public egress address | Hashed | Off by default. When turned on, a SHA-256 with a salt derived from your tenant ID, so devices behind one egress compare equal. The address is discarded at once. Treat the hash as the address: it can be recovered by trying candidates. | Report: Both |
| Peer addresses in the peer list | Hashed | Hashed with the tenant-derived salt, and only the first 16 hex characters travel. Whether a peer was on the same subnet is worked out before hashing. Recoverable by enumeration, like the egress hash. A peer can also appear in the endpoint rows and in log text, which treat it as those rows say. | Report: Telemetry |
Showing 1 to 10 of 32
What is never collected or sent
These hold whatever the settings are. The module’s redaction profile lists them as data you can read before you run it.
- User names, who is signed in, and anything from a user’s files or browsing: nothing reads them. A user name that turns up in text the collector keeps is replaced first when it has one of the forms listed under “What happens to each value”; other forms can get through.
- File contents, the contents of the Delivery Optimization cache, or the names of files in it.
- Credentials, tokens, or keys. The device’s private key signs each request and never leaves it. No key, token, or password is configured anywhere.
- A full URL or a query string. Of a download’s address, only the host and up to two safe path segments leave, and for Microsoft hosts only.
- Firewall remote addresses, the text of a PAC script, proxy names, or Wi-Fi network names (the collector never runs netsh nlm query all).
- Intune compliance state, Entra group membership, assigned apps and policies other than Delivery Optimization, and the primary user, on the device. The processor does read compliance state and owner type from Microsoft Graph for each Intune device, and stores them in your database to check that a reporting device is managed; no finding uses them.
- The ingest service’s reply. Only its HTTP status code is used, and the body is never read.
- A report, or any device data, to the DoctorDO project or to anyone but your own ingest endpoint. There is no telemetry or analytics. Installing and updating the module is not report traffic: see “What the budgets leave out”.
3 · Local mode and fleet mode
Local mode uploads nothing.
Local mode is the collector run by hand on one device: it writes a bundle you keep, or an HTML report you open. Neither has an endpoint to send anything to. Fleet mode is the Intune deployment.
| Local mode (bundle and offline report) | Fleet mode |
|---|---|
| How it runs | |
| LocalAn administrator runs Invoke-DoctorDOCollector by hand (the local bundle), or New-DoctorDODeviceReport (the offline report) | FleetInvoke-DoctorDOCollector -Fleet, from an Intune remediation, as SYSTEM |
| Where the result goes | |
| LocalA zip (doctordo-<time>.zip) or one HTML file, on the device, where you point it | FleetA signed HTTPS POST to https://<host>/v1/ingest, your own deployment |
| Uploaded | |
| LocalNothing. There is no endpoint in that code path, and the report page’s Content-Security-Policy allows no connections | FleetTwo kinds of report, to your ingest endpoint only |
| Anonymise | |
| LocalOff unless you pass -Anonymise | FleetOn by default; -Anonymise:$false turns it off |
| What it holds | |
| LocalThe full bundle: every job, every peer and connection (peers hashed), this month’s counters, and a filtered, scrubbed excerpt of the DO log of up to 200 KB. The zip also holds the DoSvc service key, the network cost, and dsregcmd /status. The offline report holds an inventory and one telemetry report | FleetA compact inventory, and compact telemetry: the top 25 jobs, aggregated peers, only the changes, grouped errors |
| Host name and IDs | |
| LocalIdentified unless -Anonymise. The offline report’s -Anonymise also removes the Entra, tenant and Intune IDs, the site code, and the AD site | FleetHost name dropped. The Entra, tenant and Intune IDs are sent, because identity is the signed request |
| Hash salts | |
| LocalThe bundle uses the device’s salt and the tenant-derived one; the offline report uses a salt made for that report, so its hashes match nothing in the fleet | FleetA per-device salt (the device ID, the serial and the gateway), and a salt derived from your tenant ID for peers, egress, Group IDs, non-Microsoft source hosts and PAC fingerprints |
| Changes on the device | |
| LocalThe log flush stops DoSvc for a moment (-NoFlush avoids it). -ReproduceIssue turns on verbose logging and always turns it off again; it is the only option that changes a setting | FleetNo setting changes: no flush, no verbose logging. It writes its own state in %ProgramData%\DoctorDO and two values under HKLM\SOFTWARE\DoctorDO for the Intune detection script. The remediation installs the module, and the NuGet provider if it is missing, and writes its own log |
| Browsing a bundle in the site | |
| LocalNot built yet. The offline report is the one-device view today | FleetThe portal in your Azure subscription |
What -Anonymise masks
It is off by default for a local bundle and on by default for a fleet run. -WhatIfRedaction prints the full profile and collects nothing.
- The host name (removed), and the device ID (a salted hash).
- The local address (reduced to its subnet), the default gateway (hashed), and the adapter name (removed).
- Group IDs, including DHCP option 234 (hashed with the tenant-derived salt), and the PAC host (hashed).
- Hosts that are not Microsoft’s: a WSUS or internal web server becomes host: and 16 hex characters.
- LAN and group peers in the endpoint rows (reduced to a /24 or /48 network), and addresses in log text (masked).
- In the local bundle’s extras, dsregcmd /status loses every GUID, thumbprint, tenant and domain name, and the account that ran it.
4 · Payload sizes
What a report weighs, measured.
Bytes of the request body, after gzip. The figures were measured on 19 October 2026 with the collector’s reference compaction on realistic samples, in the shape collector 0.4.0 and later send, so they include the per-source telemetry that release added.
The budgets
| Report | Typical budget | Hard cap (collector will not send) | Ingest accepts |
|---|---|---|---|
| telemetry | Typical budget: 4,096 B | Hard cap: 65,536 B | Ingest accepts: 196,608 B |
| inventory | Typical budget: 10,240 B | Hard cap: 65,536 B | Ingest accepts: 196,608 B |
A report over its typical budget is a signal, not a failure: the collector writes a warning and sends it. Over the hard cap it is not sent (exit code 5). The ingest tier’s own ceiling is three times the larger cap, with a 2 MB limit once inflated and a 50:1 ratio cap, and it admits one report per device every 15 minutes (a burst of three).
Five reports, measured
| Report | What it is | Compressed | JSON | Of budget |
|---|---|---|---|---|
| Routine telemetry, nothing wrong | A healthy device that did little: a real Windows 11 laptop with 26 jobs in its cache, of which the 8 that moved bytes since the last report are sent (seven small ones and a 41 MB app), 6 endpoints, 2 peers, no errors, nothing changed since the last report, the usual diagnosis counters, and per-source telemetry for the 8 jobs. | 1,758 B | 5,270 B | 43% |
| A bad day | A busy device (60 jobs in its cache, 15 of them moving bytes since the last report; 40 peers, 180 connections), 24 endpoints, four kinds of error each with a scrubbed sample line, six checks failing and a proxy stripping byte ranges (eight changed results), DoSvc crashing, two flapping checks, and per-source telemetry over 12 hosts and 6 caches. | 4,462 B | 16,973 B | 109% (over) |
| The worst case | The largest report the collector can send: every list full, with 32 error groups each with a sample line, 24 connection groups, 24 endpoints, the cap of 64 changed results, the worst diagnosis counters, and the busy per-source section. | 9,175 B | 52,487 B | 224% (over) |
| An inventory | Everything about the device that does not change per cycle: identity, hardware, the six registry stores, 12 firewall rules, and the full connectivity matrix of 70 results. Sent at enrolment, when the device changes, daily in the device’s first week, and then every 7 days. The sample has no Autopilot provisioning section: a device with Enrollment Status Page history sends more, not yet measured (to-verify). | 5,322 B | 35,830 B | 52% |
| The one-off after a state loss | The routine device again, but its state file is gone (a re-imaged or reset device). The report is a baseline: no bytes at all, so what the cache already held is never counted as new traffic, and every connectivity result is sent once up to the cap of 64. The next report counts from there. An inventory goes with it, so the pair is 9.4 KB. | 4,037 B | 25,085 B | 99% |
“Of budget” is against the typical budget of that report kind. The bad day and the worst case go over the telemetry budget; all stay far under the 65,536 B hard cap. A state loss is a one-off per device, and the same run rebuilds the state file.
What is in a routine report
Each part was measured by leaving it out of the 1,758 B report. They do not add up exactly: the rest is the fixed fields (collector, period, hashes) and what the parts share.
| Part | Compressed |
|---|---|
| The job list: the 8 jobs that moved bytes since the last report (at most 25 rows and one for the rest) | 445 B |
| Facts the collector could not read, each with its reason | 312 B |
| Endpoints that served the bytes (6 rows here, up to 24) | 275 B |
| Counters since the last report, peers, and connections | 243 B |
| Device vitals and the diagnosis counters | 134 B |
| Per-source download telemetry (8 jobs, 1 cache, 1 host) | 50 B |
How often a report is sent
The collector has no schedule of its own: it sends when the Intune remediation runs it. The deployment guide sets the remediation to Daily, and the detection script treats a collection as fresh for 22 hours, shorter than the interval, so a device sends one telemetry report a day. Intune offers Once, Hourly, and Daily schedules, and the daily interval can be set to several days17. An inventory goes with the first run, when the device changes, and at least every 7 days.
Older design notes in the project’s documents work their arithmetic at an hourly cadence. The guide a deployment follows says daily, so daily is the default here, and hourly is shown as the case to plan a ceiling against.
Across a fleet
Per device per day, a routine telemetry report each day plus a seventh of an inventory (2.5 KB), a month of 30 days. Decimal units: 1 MB is 1,000,000 bytes.
| Devices | Daily, a day | Daily, a month | Daily, a bad day for every device | Hourly, a day | Hourly, a month |
|---|---|---|---|---|---|
| 1,000 | 2.5 MB | 75.5 MB | 5.2 MB | 43.0 MB | 1.29 GB |
| 10,000 | 25.2 MB | 755.5 MB | 52.2 MB | 429.5 MB | 12.89 GB |
| 50,000 | 125.9 MB | 3.78 GB | 261.1 MB | 2.15 GB | 64.43 GB |
- The daily columns are the default: one routine report a day (1,758 B). The bad-day column is the ceiling for daily reporting, if every device had the bad day of the table above on the same day (4,462 B).
- Each inventory sent because a device changed adds 5,322 B on top. The OS build is in the change hash, so expect one extra inventory around each Windows quality update, about 5.3 KB a device a month.
- These are the bodies. The costs page works out what receiving and storing them costs in Azure.
What the budgets leave out
- Request headers. Each request carries the device certificate (about 1.3 KB as base64, the ingest tier’s own figure), a signature (344 characters for the 2,048-bit RSA key Entra device registration uses18), a nonce, and a timestamp. They are not compressed and are not in the budgets: allow about 1.7 KB a request, so a routine report is nearer 3.5 KB on the wire. That is an estimate from those parts (to-verify on a real device); it adds about 17.0 MB a day at 10,000 devices.
- The package and the policies. The module’s install and updates, and the Microsoft endpoints the probes touch, are not report traffic. The probes are small (a name lookup, a connection, a one-byte range request each), and the endpoint results are reused for 6 hours.
- Installing and updating the module. The Intune remediation installs the module and keeps it up to date, so it has destinations of its own. With the default
-UpdatePolicy LatestVerifiedit asks the PowerShell repository you choose (PowerShell Gallery unless you change-Repository) for the newest version at most once every 24 hours (-UpdateCheckHours; on every run while no usable version is installed), installs the NuGet provider if it is missing, installs from that repository when a different version is wanted, and downloadscollector-manifest.jsonfrom the project’s GitHub release to verify a version other than the one stamped into the script. With-UpdatePolicy Pinnedit contacts the repository only to install the pinned version. None of these requests carries device data; host the module in your own repository to keep them inside your network. During the preview the module is not on the PowerShell Gallery yet and the project’s repository is private, so publish the module to an internal repository, or deploy it as a Win32 app. - The local bundle. It is not sent anywhere. For scale, the busy device’s bundle.json compresses to 24,980 B, or 98,556 B with a 200 KB log excerpt, about 56 times a routine report. The collector aims to finish a run in under a minute and 5 MB; the two probe batches alone can take up to 100 seconds (40, then 60) when every probe runs to its limit.
How it was measured, and how to measure it again
Measured on 19 October 2026. pnpm bench:wire measures one busy sample and what each addition costs; the wire package’s size tests pin it against the budgets. They do not model three things every report from 0.4.0 on carries: the endpoint rows, the records of what could not be read, and the per-source section. pnpm bench:payload adds them to the same samples and prints the five reports above. The data page’s own test measures again and fails if a figure here drifts by more than 3%.
The sizes use the reference compaction, which the PowerShell collector is checked against byte for byte on golden fixtures, and Node’s gzip. The collector compresses with .NET’s GZipStream, which can differ by a few percent (to-verify on Windows PowerShell 5.1 and 7). The wire package’s test for its busy sample passes at 2,940 B; with the three missing parts it is 4,462 B on a bad day, which is why the typical budget is a signal rather than a promise.
5 · Check it
Read it before you run it.
Nothing here has to be taken on trust. The module ships what it reads and what it hides as data.
- The redaction profile is a data file in the module (
Data/redaction-profile.json);Invoke-DoctorDOCollector -WhatIfRedactionprints it and collects nothing. - The registry paths, cmdlets, and limits on this page are in the module’s PowerShell source, so each can be read line by line. The first public release is coming.
- The report shapes are JSON Schemas (
inventory-v1,telemetry-v1), so a security team can validate what a device would send. - Where the code could not settle a point, this page says to-verify: the header sizes, .NET’s compression, the size of an inventory with Autopilot provisioning history, and the Windows event data that the diagnosis counters match on.
Microsoft documentation cited on this page (21)
- 1Monitor Delivery Optimization (opens in a new tab)learn.microsoft.com/windows/deployment/do/waas-delivery-optimization-monitor
- 2Delivery Optimization reference (opens in a new tab)learn.microsoft.com/windows/deployment/do/waas-delivery-optimization-reference
- 3Policy CSP: DeliveryOptimization (opens in a new tab)learn.microsoft.com/windows/client-management/mdm/policy-csp-deliveryoptimization
- 4Delivery Optimization endpoints (opens in a new tab)learn.microsoft.com/windows/deployment/do/delivery-optimization-endpoints
- 5Delivery Optimization and proxy servers (opens in a new tab)learn.microsoft.com/windows/deployment/do/delivery-optimization-proxy
- 6Delivery Optimization frequently asked questions (opens in a new tab)learn.microsoft.com/windows/deployment/do/waas-delivery-optimization-faq
- 7Troubleshoot devices by using the dsregcmd command (opens in a new tab)learn.microsoft.com/entra/identity/devices/troubleshoot-device-dsregcmd
- 8DMClient CSP (opens in a new tab)learn.microsoft.com/windows/client-management/mdm/dmclient-csp
- 9DevDetail CSP (opens in a new tab)learn.microsoft.com/windows/client-management/mdm/devdetail-csp
- 10Get-WinEvent (opens in a new tab)learn.microsoft.com/powershell/module/microsoft.powershell.diagnostics/get-winevent
- 11Troubleshoot unexpected reboots using System event logs (opens in a new tab)learn.microsoft.com/troubleshoot/windows-server/performance/troubleshoot-unexpected-reboots-system-event-logs
- 12Service Control Manager events 7031 and 7034 (opens in a new tab)learn.microsoft.com/troubleshoot/windows-server/system-management-components/error-1053-1067-7034-after-update-openssh-doesnt-start
- 13Win32_OperatingSystem class (opens in a new tab)learn.microsoft.com/windows/win32/cimwin32prov/win32-operatingsystem
- 14Win32_LogicalDisk class (opens in a new tab)learn.microsoft.com/windows/win32/cimwin32prov/win32-logicaldisk
- 15Get-NetTCPConnection (opens in a new tab)learn.microsoft.com/powershell/module/nettcpip/get-nettcpconnection
- 16DOSwarmStats (opens in a new tab)learn.microsoft.com/windows/win32/delivery_optimization/doswarmstats
- 17Remediations (opens in a new tab)learn.microsoft.com/intune/device-management/tools/deploy-remediations
- 18How Microsoft Entra device registration works (opens in a new tab)learn.microsoft.com/entra/identity/devices/device-registration-how-it-works
- 19Required firewall exceptions for Teredo (opens in a new tab)learn.microsoft.com/windows/win32/teredo/required-firewall-exceptions-for-teredo
- 20EnrollmentStatusTracking CSP (opens in a new tab)learn.microsoft.com/windows/client-management/mdm/enrollmentstatustracking-csp
- 21Troubleshooting the Enrollment Status Page (opens in a new tab)learn.microsoft.com/troubleshoot/mem/intune/device-enrollment/understand-troubleshoot-esp
See what it shows before you deploy it.
Open the portal for ContosoAI, a fictitious company with 46,000 devices, at 41 sites in 16 countries and working remotely. Every company, site, and figure in it is invented. Its figures are modelled, not computed from collector reports.