IO by Hour by Day

Overview

The I/O by Hour by Day report shows when one database does its I/O.

It is the database-level member of the by-hour-by-day family, and it answers a question that matters for scheduling more than for tuning: when is this database actually reading and writing? That tells you when a backup will hurt, when an index rebuild will collide with real work, and whether the storage this database sits on is busy at the same times as everything else on the volume.

Hours run down, days across, one cell per hour.

This report shows the I/O figures themselves rather than a percentage of the busiest hour. Volume is the point here – knowing an hour was at 60% of the peak is less useful than knowing what it actually moved.


The I/O by Hour by Day report
One database, hour by hour. When it reads and writes – the scheduling question, answered.

Where to find it

A database-level historic report. Select a database in the tree and open it from its historic reports. The page title names both the instance and the database.


Reading the heat map

Each cell is one hour of one day, and darker means more I/O.

The ramp is monotone in perceptual lightness, so the magnitude reads from lightness alone – in greyscale, on a projector, or under any form of colour vision deficiency. Cell text picks black or white per fill and always clears a 4.5:1 contrast ratio against it.

Dark mode inverts the ramp’s anchor so hot advances off the surface. Colour-blind mode uses a single blue hue across the same lightness steps, which is safe under every form of colour vision deficiency by construction.

Cumulative counters, differenced

SQL Server’s I/O counters are cumulative since startup, so the raw numbers only become an hourly figure once each sample is differenced against the one before it. The report does that differencing.

The consequence worth knowing: an hour containing a service restart cannot be differenced against the previous sample, because the counter went back to zero. Around a restart, expect one hour that does not fit the pattern.

No data is not zero

An hour where nothing was recorded is drawn differently from an hour of no I/O. A collection gap is not a quiet database.


The toolbar

Button What it does
Show More Adds a week to the range.
Show Less Removes a week.

One to six weeks in one-week steps; the buttons hide themselves at the ends.

The range is shared with every other by-hour-by-day report, which is what lets you read this database’s I/O against the instance’s CPU or disk latency over exactly the same window.


Requirements

A historic report reading the collection service’s I/O tracking history from the DBHealthHistory repository. Without collection configured for the instance there is nothing to draw.

It reads history rather than the live instance, so it works when the monitored server is unavailable.


How to read the report

  1. Find the quiet windows first. This report is most often used to decide when to schedule something, and the pale cells are the answer.
  2. Check whether the busy block matches the business day. A database busiest at 03:00 is doing batch work – worth knowing if you thought it was interactive.
  3. Compare with Disk Latency by Hour by Day. Heavy I/O in hours where latency is also high is a storage contention problem rather than a database one.
  4. Compare with the instance CPU map. I/O-heavy and CPU-light hours are usually scans, and often an indexing opportunity.
  5. Look for the restart artefact before treating a single odd hour as a finding.
  6. Widen the range to distinguish a weekly rhythm from a monthly one.

Common patterns

A dark band overnight. Backups, ETL, or maintenance. Expected – but this is the map that shows whether it is finishing before the working day.

Heavy I/O during business hours on a reporting database. Users running reports against live data. A read replica or a scheduled extract is the usual conversation.

One very dark cell each month. Month-end. Schedulable once you know it is there.

High I/O with low CPU. Reading a lot to compute little – typically scans. Missing Indexes and Table Use for this database are where that goes next.

A single hour that breaks the pattern completely. Often the restart artefact described above rather than a real event.

Uniformly pale everywhere. Either a genuinely quiet database, or the busiest hour is so extreme that it flattens everything else. Narrow the range to check.


Report Why you would go there
I/O by Database How this database’s I/O compares with the others on the instance.
Disk Latency by Hour by Day Whether the storage was slow when this database was busy.
Files for Database Which files the I/O lands on.
CPU by Hour by Day Whether I/O and CPU peak together.
Missing Indexes I/O that a better index would remove.

Frequently asked questions

Why does this show figures rather than percentages? Because the volume is the point. “60% of the busiest hour” does not tell you whether a backup will fit in that window.

Why does one hour look wrong around a restart? The counters are cumulative and reset to zero on restart, so that hour cannot be differenced against the previous sample.

Is this instance-wide? No – this page is one database. I/O by Database compares them across the instance.

What does a blank cell mean? Nothing was recorded – a collection gap, not an idle hour.

Why does changing the weeks here change the other heat maps? It is one shared setting, so all the by-hour-by-day reports stay comparable.