Data Analysis

COUNTIF by Month in Google Sheets (2026)

Marc SeanMay 25, 20265 min read

Why COUNTIF Returns 0 on Any Mês Range

COUNTIF evaluates dates as serial numbers when you use comparison operators, and as text when you use exact match. Feed it =COUNTIF('Transactions'!B:B, "March") and you get 0, because no cell contains the string "March" - it contains a date serial like 46100. Feed it a bare date value and it's looking for an exact timestamp match, which almost never hits unless you're counting a specific day.

The only safe way to count by month is to either bracket the range with >= / <= date comparisons, or extract the month component directly before comparing.

COUNTIFS + EOMONTH: The Standard Mês Pattern

This is what most FP&A models should use. COUNTIFS with a >= lower bound and <= upper bound built from EOMONTH gives you an exact month window with no array overhead.

=COUNTIFS(
  'Transactions'!B:B, ">=" & DATE(Assumptions!$B$3, Assumptions!$C$3, 1),
  'Transactions'!B:B, "<=" & EOMONTH(DATE(Assumptions!$B$3, Assumptions!$C$3, 1), 0)
)

Assumptions!$B$3 holds the year (e.g., 2026), Assumptions!$C$3 holds the month number (e.g., 3 for March). EOMONTH(..., 0) returns the last day of that month, handling February, 30-day months, and leap years automatically.

For a quarterly board pack counting 8,000 closed deals by month, this runs in under 200ms on a cold sheet open. COUNTIFS processes comparison criteria without building an intermediate array, so memory usage stays flat regardless of row count.

Bolt on additional criteria as more range/criteria pairs. According to Google's COUNTIFS documentation, the function accepts up to 127 range/criteria pairs - so adding a region, product line, or rep filter is just two more arguments:

=COUNTIFS(
  'Transactions'!B:B, ">=" & DATE(Assumptions!$B$3, Assumptions!$C$3, 1),
  'Transactions'!B:B, "<=" & EOMONTH(DATE(Assumptions!$B$3, Assumptions!$C$3, 1), 0),
  'Transactions'!D:D, Assumptions!$D$3
)

SUMPRODUCT + MONTH/YEAR: Flexible Mês Extraction

When you need more expressive criteria - contribution margin by SKU, weighted averages, or conditions that COUNTIFS can't cleanly express - SUMPRODUCT with MONTH+YEAR extraction gives you that flexibility.

=SUMPRODUCT(
  (MONTH('Transactions'!B2:B5001) = Assumptions!$C$3) *
  (YEAR('Transactions'!B2:B5001) = Assumptions!$B$3)
)

On 5,000 rows, this evaluates roughly 10,000 array operations (2 per row). Scale to 50,000 rows and you're at 100,000 evaluations per cell. On a model with 24 monthly columns all recalculating simultaneously, that's 2.4 million operations triggered on every edit. Use SUMPRODUCT when you need the expressiveness, not as a default.

One genuine advantage: SUMPRODUCT handles non-contiguous conditions and calculated criteria without helper columns. If you're counting orders where the month check is one of 4 conditions and one of them involves an array calculation, it often reads cleaner than a 10-argument COUNTIFS.

Building a Monthly Breakdown Across Tabs

The real work is generating 12 or 24 monthly columns from a single transaction log, with the formula propagating horizontally. Structure it so the year and month come from header references rather than hardcoded values:

=COUNTIFS(
  'Orders'!$C:$C, ">=" & DATE($B$2, C$4, 1),
  'Orders'!$C:$C, "<=" & EOMONTH(DATE($B$2, C$4, 1), 0),
  'Orders'!$D:$D, $A6
)

$B$2 is the model year on the Summary tab. C$4 is the month number in the column header - the mixed reference increments horizontally as you copy right. $A6 is the category label - the mixed reference increments vertically as you copy down. Copy across 24 columns and down 15 revenue lines without touching the formula.

This is exactly what breaks when someone hardcodes DATE(2026, 3, 1) instead of referencing Assumptions - correct for March, wrong everywhere else.

Performance: COUNTIFS vs. SUMPRODUCT at Scale

Approach5,000 rows50,000 rowsNotes
COUNTIFS + EOMONTH~40ms~180msNon-array, recalcs incrementally
SUMPRODUCT + MONTH/YEAR~90ms~850msFull array every recalc
SUMPRODUCT + DATE bounds~70ms~620msSlightly faster than MONTH/YEAR extraction

Timing estimates based on single-condition counts on a standard Google Sheets file with no external data connections, as of May 2026. On a 24-column model where every cell recalculates on edit, the COUNTIFS approach saves several seconds per keystroke at 50,000+ rows.

As of May 2026, the Google Sheets function list confirms that COUNTIFS supports the same wildcard and comparison syntax as Excel. Any pattern here transfers to Excel models without modification.

Wiring It Into a Live Model

The reference architecture for a quarterly board pack - 24 monthly columns, 3 business segments, revenue and headcount metrics - that doesn't break under edits:

  • Assumptions tab holds year in $B$3 and a month number series in row 4 (1 through 24, or actual dates)
  • Transaction tabs (Orders, Payroll, COGS) hold raw data with date columns
  • Summary tab uses COUNTIFS with mixed references pointing at the Assumptions row 4 for months, locking column for category rows

Getting the $ placement right across 24 columns and 15 rows is usually where analysts burn 20 minutes. ModelMonkey can build the COUNTIFS formulas with the correct mixed-reference locking directly in your sheet - describe the tab structure and it wires the cross-tab references for you.

Try ModelMonkey free for 14 days - it works in both Google Sheets and Excel.

Frequently Asked Questions