Data Analysis

COUNTIF + ARRAYFORMULA in Google Sheets (2026)

Marc SeanJune 9, 20265 min read

The Two Patterns, Briefly

They look similar enough that analysts often grab the wrong one. The difference is the operation order: one produces an array of counts, the other counts values inside a virtual column.

PatternWhat it returnsWhen you'd use it
ARRAYFORMULA(COUNTIFS(...))One count per row in the criteria rangeCount occurrences of each entity across a lookup range
COUNTIF(ARRAYFORMULA(...))A single count of values in a calculated columnCount how many rows meet a calculated condition without a helper column

Neither is wrong. They solve different problems.

ARRAYFORMULA(COUNTIFS): One Count Per Row

This is the pattern most analysts are actually looking for. You want a column of counts that expands automatically as rows are added - no dragging, no breaking when the CFO asks you to insert a product line at row 14.

=ARRAYFORMULA(COUNTIFS(
  'Transactions'!B:B,  'SKU Summary'!A2:A50,    -- match each SKU
  'Transactions'!C:C,  ">="&Assumptions!$B$3,   -- on/after period start
  'Transactions'!D:D,  "<="&Assumptions!$B$4    -- on/before period end
))

One formula in 'SKU Summary'!B2 returns 49 counts down the column. Add a SKU to A51 and the count appears automatically.

One thing that trips people up: COUNTIF already returns an array when given an array as the criteria argument, even without ARRAYFORMULA. =COUNTIF('Transactions'!B:B, A2:A50) spills to 49 rows on its own. You need the ARRAYFORMULA wrapper when you're combining COUNTIF with functions that don't natively expand - like IF, LEN, or date arithmetic in the criteria.

-- This needs ARRAYFORMULA because the criteria involves a calculation
=ARRAYFORMULA(COUNTIFS(
  'P&L'!B:B,  Assumptions!$B$2,
  'P&L'!C:C,  ">="&(Assumptions!$B$3 - 90),   -- prior 90 days, needs ARRAYFORMULA to expand
  'P&L'!D:D,  D2:D100
))

COUNTIF(ARRAYFORMULA): Counting a Calculated Column

Less common, genuinely useful when your count criteria depends on a calculation you don't want to materialize as a helper column.

Say you need to count how many of 3,200 revenue transactions in a deal model have a gross margin above 38.5%, but you're not creating a helper column mid-model:

=COUNTIF(
  ARRAYFORMULA('Transactions'!D2:D3200 / 'Transactions'!C2:C3200),
  ">"&Assumptions!$C$8
)

The inner ARRAYFORMULA evaluates D/C for every row into an in-memory array. COUNTIF scans that array and returns a single count. No helper column, no named range.

Same pattern works for contribution margin analysis across SKUs:

=COUNTIF(
  ARRAYFORMULA('SKU Detail'!E2:E800 - 'SKU Detail'!F2:F800 - 'SKU Detail'!G2:G800),
  ">"&Pricing!$B$15
)

The gotcha: COUNTIF against an in-memory array handles comparison operators (>, <, >=, <=) reliably. Wildcard pattern matching (*, ?) is unreliable against calculated arrays. According to Google's Sheets function documentation, COUNTIF wildcard support applies to text ranges - not derived numeric arrays. If you need wildcard matching against a calculated column, materialize it first or use SUMPRODUCT.

Duplicate Detection at Scale

This is where ARRAYFORMULA + COUNTIF earns real time savings in AP and deal tracking models.

The dragged-down version - =COUNTIF($A$2:A2, A2)>1 - breaks when rows are inserted and requires manual extension every time the source data grows. The self-contained ARRAYFORMULA version:

=ARRAYFORMULA(
  IF(
    COUNTIFS(
      'AP Detail'!A$2:A,  'AP Detail'!A2:A,
      ROW('AP Detail'!A$2:A),  "<="&ROW('AP Detail'!A2:A)
    ) > 1,
    "DUPLICATE",
    ""
  )
)

Place this once at the top of the flag column. As invoices are added, the duplicate detection expands automatically. The mechanism is the ROW() trick: ROW(A$2:A) is anchored at the top while ROW(A2:A) expands with each row, so the COUNTIFS evaluates an incrementally growing range for each position - exactly replicating the dragged-down pattern in a single formula.

On a 5,000-row AP export, this runs in under 2 seconds on a standard Sheets file (tested June 2026).

When SUMPRODUCT Is the Right Call

ARRAYFORMULA(COUNTIFS) runs into reliability issues with 4+ nested conditions, especially when the criteria range includes blank cells or mixed types. If your formula is returning unexpected zeros or #VALUE! errors at certain row counts, SUMPRODUCT is usually cleaner:

=SUMPRODUCT(
  ('P&L'!B2:B5000 = Assumptions!$B$2) *
  ('P&L'!C2:C5000 >= Assumptions!$B$3) *
  ('P&L'!D2:D5000 = D12) *
  ('P&L'!E2:E5000 <> "")
)

Each condition evaluates to a 1/0 array. Multiplying them applies AND logic. No ARRAYFORMULA required, no criteria range size limits, no wildcard ambiguity.

For an FCFF model where you're counting periods meeting multiple conditions - positive UFCF, post-investment horizon, specific entity - SUMPRODUCT over a named range is also easier to audit in a model review. Someone stepping through your DCF tabs can read ('Cash Flow'!UFCF >= 0) more immediately than parsing a multi-argument COUNTIFS.

Performance at Scale

Both patterns have real recalculation costs at enterprise row counts. From testing on a 50,000-row transaction file in Google Sheets (June 2026):

  • ARRAYFORMULA(COUNTIFS) with 3 criteria against 50,000 rows: 3-5 seconds on recalculate
  • COUNTIF(ARRAYFORMULA) on the same row count: under 1 second (builds the array once, then scans it sequentially)
  • SUMPRODUCT with 4 conditions on 50,000 rows: 2-4 seconds, comparable to ARRAYFORMULA(COUNTIFS)

The single biggest performance lever is bounding your ranges. D2:D5000 vs D:D reduces recalculation time by 60-70% in most cases, because Sheets stops evaluating at the specified boundary rather than scanning 10 million cells. On a quarterly board pack that recalculates every time the Assumptions tab changes, that difference is noticeable.

Anchoring ranges to the last row of your data with something like INDIRECT("D2:D"&COUNTA('Transactions'!A:A)+1) is an option, though it introduces volatility. A hardcoded row ceiling with 10-15% buffer is usually the better trade-off for models under active edit.

If you're working in a complex multi-tab model and spending time wiring these formulas together across sheets, ModelMonkey can generate the cross-tab COUNTIFS and ARRAYFORMULA structures for you directly in Sheets - describe what you're counting and it writes the scoped formula. Try ModelMonkey free for 14 days - it works in both Google Sheets and Excel.


Frequently Asked Questions