Skip to content

Azure SQL DB gets no tempdb monitoring, and the reason recorded for that is not true #2512

Closed

Description

@erikdarlingdata

Found by running the collector's own SQL against live Azure SQL Database, both service tiers.

The gate

// TempDbStatsCollector.cs:70
public override bool AppliesTo(CollectorTargetInfo target) => !target.IsAzureSqlDb;

Its doc comment explains why:

The second result set (sys.dm_db_session_space_usage, two-part and in-database) WOULD work on Azure SQL DB. Recovering that half needs an Azure-specific query variant rather than a gate … the immediate defect is a collector that can only ever fail

The premise is that the FIRST result set — the three-part tempdb.sys.dm_db_file_space_usage — cannot bind on Azure SQL Database.

It binds, and returns real data

The collector's SQL, verbatim, both result sets, run over an Entra token (2026-08-22):

General Purpose serverless (GP_S_Gen5_2, EngineEdition 5, 12.0.2000.8)

result set returned
1 — tempdb.sys.dm_db_file_space_usage user 5.44 MB, internal 1.81 MB, version store 0.00 MB, total 7.25 MB, unallocated 54.19 MB
2 — sys.dm_db_session_space_usage session 74, 0.13 MB, 1 session over threshold

Hyperscale serverless (HS_S_Gen5_2, EngineEdition 5)

result set returned
1 user 1.88 MB, internal 0.00 MB, version store 0.00 MB, total 1.88 MB, unallocated 60.69 MB
2 session 1, 0.00 MB, 0 sessions over threshold

SELECT COUNT(*) FROM tempdb.sys.dm_db_file_space_usage returns 4 on both tiers.

So the collector does not "only ever fail" on Azure SQL Database. It works, on both tiers, with no query variant needed.

What this costs today

Every Azure SQL Database target — the whole tier, both GP and Hyperscale — collects no tempdb data at all. No get_tempdb_trend, no tempdb space alerting, nothing in the viewer's tempdb surfaces. On a platform where tempdb contention is a common and consequential problem, and where the customer cannot simply look at the box themselves.

Worse, after #2485 the reads will now explain that absence confidently and wrongly — see #2511.

What to check before flipping the gate

I have verified the SQL binds and returns plausible values. I have not:

  • run it through the actual collector pipeline against an Azure target (payload composition, column typing, the RunsPerDatabase interaction);
  • checked whether the numbers are meaningful on Azure SQL DB, as opposed to merely returned — tempdb on Azure SQL DB is per-replica and its size is tier-governed, so "unallocated_mb" may not mean what it means on a box. This matters more than the binding: a number that returns but describes something different is worse than a gap, and is precisely the trap this collector's own comment was trying to avoid;
  • confirmed behaviour on Managed Instance is unchanged (the gate is IsAzureSqlDb specifically, so MI already collects).

So: flip the gate only after deciding what these figures MEAN on the tier, and say so in the doc comment. If they turn out to be misleading rather than merely available, the right fix is to keep the gate and correct the stated reason, because the current one is checkably false and will invite exactly this issue again.

Related

Activity

  1. erikdarlingdata commented on Aug 22, 2026

    @erikdarlingdata
    OwnerAuthor

    Settled empirically — the numbers are real, and they mean what the collector expects. This was the open question ("do these figures describe something, or merely return"), so I went and moved the needle rather than reasoning about it.

    Live on GP_S_Gen5_2, one session, allocating into a #temp table:

    step user_mb unallocated_mb
    before 1.88 60.69
    after allocating ~57 MB 59.75 (+57.87) 2.69 (−58.00)
    after DROP TABLE 59.75 2.69 (deferred dealloc, as expected)

    sys.dm_db_session_space_usage attributed 59.25 MB to session 74 in the same instant — the session that did the allocating.

    Three things follow:

    1. The counters track actual allocation, to within the reserved-versus-allocated difference you would expect. This is not a constant, not a stub, and not another database's tempdb.
    2. unallocated_mb is the real remaining headroom for this database's tempdb — it fell by 58 MB as 57.87 MB was taken.
    3. The session view works too, so the collector's second result set is meaningful as well as bindable.

    This makes the monitoring MORE valuable on Azure, not less

    The total here is ~62 MB, and that is the point. On Azure SQL Database the tempdb ceiling is governed by the service tier and you cannot add files or grow your way out of it. On a box, "tempdb is filling" means "go look at the disk". Here it means "you are approaching a hard limit you cannot raise without changing tier" — which is more actionable, more urgent, and completely invisible today.

    Verdict

    Remove the !target.IsAzureSqlDb gate on TempDbStatsCollector. The reason recorded in its doc comment is checkably false, and the alternative I raised when filing — keep the gate and correct the reason — is now off the table, because there is no reason left.

    Still to check when doing it, as originally listed: the payload composition through the real collector pipeline, column typing, and that Managed Instance behaviour is unchanged (the gate is IsAzureSqlDb specifically, so MI already collects and must keep doing so).

  2. added 2 commits that reference this issue on Aug 22, 2026
  3. added 3 commits that reference this issue on Aug 24, 2026
    6c3867a
    a453004
    84f59e8
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions