Blog · How-to guides · Finance and FP&A teams
XLOOKUP, VLOOKUP and INDEX MATCH compared side by side on one ledger and customer master: default match, missing IDs, inserted columns, left lookups, two-way lookups, speed and version availability. It ends with a rule a finance team can standardize on.
Use XLOOKUP when everyone who opens the file has Microsoft 365 or Excel 2021 or later. Use INDEX MATCH when the file must also open in Excel 2016 or 2019: it does the same jobs, with more typing. Keep VLOOKUP for maintaining old files, because it matches approximately by default, only looks right and depends on a column number.
| VLOOKUP | INDEX MATCH | XLOOKUP | |
|---|---|---|---|
| Default match | Approximate | Approximate (MATCH's default is 1) | Exact |
| Look left | No | Yes | Yes |
| Column inserted in the table | Returns the wrong field | Unaffected | Unaffected |
| Not-found handling | #N/A; wrap in IFNA | #N/A; wrap in IFNA | Built-in argument |
| Last match instead of first | No | No | Yes, search_mode -1 |
| Several columns at once | One formula per column | One stored MATCH reused by several INDEXes | Yes, one formula spills |
| Two-way lookup | With MATCH as the column number | Yes, two MATCHes | Yes, nested |
| Excel versions | All | All | Microsoft 365, 2021, 2024, web |
Two cells in that table catch people out. MATCH, like VLOOKUP, is approximate unless you type 0: Microsoft's MATCH page gives 1 as the default. And Microsoft's XLOOKUP page states that XLOOKUP is not available in Excel 2016 and Excel 2019.
The task: the account manager for each invoice. The Ledger sheet has invoices in A and customer IDs in B. The Customers sheet is the customer master:
| A: ID | B: Name | C: Segment | D: Account manager | |
|---|---|---|---|---|
| 2 | C-1001 | Harlow Foods | Enterprise | Patel |
| 3 | C-1002 | Brightwell Inc. | Enterprise | Jones |
| 4 | C-1003 | Kestrel Supplies | Mid-market | Patel |
| 5 | C-1004 | Northgate Retail | Mid-market | Okafor |
| 6 | C-1005 | Ashby Engineering | Small | Jones |
VLOOKUP in Ledger!C2:
=VLOOKUP(B2,Customers!$A$2:$D$6,4,FALSE)
INDEX MATCH in Ledger!D2:
=INDEX(Customers!$D$2:$D$6,MATCH(B2,Customers!$A$2:$A$6,0))
XLOOKUP in Ledger!E2:
=XLOOKUP(B2,Customers!$A$2:$A$6,Customers!$D$2:$D$6,"Not in master")
Filled down to row 7:
| Invoice | Customer ID | VLOOKUP | INDEX MATCH | XLOOKUP |
|---|---|---|---|---|
| INV-1001 | C-1001 | Patel | Patel | Patel |
| INV-1002 | C-1004 | Okafor | Okafor | Okafor |
| INV-1003 | C-1002 | Jones | Jones | Jones |
| INV-1004 | C-1099 | #N/A | #N/A | Not in master |
| INV-1005 | C-1003 | Patel | Patel | Patel |
| INV-1006 | C-1001 | Patel | Patel | Patel |
On the five matched rows the three agree. VLOOKUP names the whole table and counts to column 4. INDEX MATCH names the column to return and the column to search separately. XLOOKUP does the same in one function.
C-1099 is on an invoice but not in the master. VLOOKUP and INDEX MATCH return #N/A, which breaks any SUM over the column until someone wraps the formula in IFNA. XLOOKUP returns the label in its fourth argument, "Not in master", which can be counted and totaled as its own line. None of the three says why the ID is missing; that needs a reconciliation, not a lookup.
Insert a Region column between B and C in the master. Segment moves to D and Account manager to E, and Excel rewrites every reference:
| Formula | Becomes | Returns for INV-1001 to INV-1003 |
|---|---|---|
| VLOOKUP | =VLOOKUP(B2,Customers!$A$2:$E$6,4,FALSE) |
Enterprise, Mid-market, Enterprise |
| INDEX MATCH | =INDEX(Customers!$E$2:$E$6,MATCH(B2,Customers!$A$2:$A$6,0)) |
Patel, Okafor, Jones |
| XLOOKUP | =XLOOKUP(B2,Customers!$A$2:$A$6,Customers!$E$2:$E$6,"Not in master") |
Patel, Okafor, Jones |
VLOOKUP's range widens to $A$2:$E$6, but the 4 is typed in, and column 4 is now Segment. Every row returns a segment where an account manager should be, with no error. INDEX MATCH and XLOOKUP point at the column itself, so the reference moves with it. The other ways VLOOKUP fails on a ledger are in VLOOKUP in Excel.
The ID for "Kestrel Supplies" sits to the left of the name. INDEX MATCH:
=INDEX(Customers!$A$2:$A$6,MATCH("Kestrel Supplies",Customers!$B$2:$B$6,0))
XLOOKUP:
=XLOOKUP("Kestrel Supplies",Customers!$B$2:$B$6,Customers!$A$2:$A$6)
Both return C-1003. VLOOKUP cannot: Microsoft's VLOOKUP page requires the lookup value to be in the first column of the table, and the only fix is to rebuild the table with the name first.
A Budget sheet with cost centers down column A and months across row 1 (May to December continue in F to M):
| A: Cost center | B: Jan (USD) | C: Feb (USD) | D: Mar (USD) | E: Apr (USD) | |
|---|---|---|---|---|---|
| 2 | Sales | 120,000 | 118,000 | 125,000 | 122,000 |
| 3 | Finance | 40,000 | 40,000 | 41,500 | 41,500 |
| 4 | Ops | 86,000 | 88,000 | 90,500 | 89,000 |
With Finance in G1 and Mar in H1 on the report sheet, INDEX takes a row number from one MATCH and a column number from another:
=INDEX(Budget!$B$2:$M$4,MATCH($G$1,Budget!$A$2:$A$4,0),MATCH($H$1,Budget!$B$1:$M$1,0))
The MATCHes return 2 and 3, and INDEX returns $41,500. The XLOOKUP version nests one inside the other: the inner XLOOKUP returns the whole March column, and the outer one picks Finance from it:
=XLOOKUP($G$1,Budget!$A$2:$A$4,XLOOKUP($H$1,Budget!$B$1:$M$1,Budget!$B$2:$M$4))
Also $41,500. The same grid shape appears in a cross-sell matrix.
Microsoft's Excel performance guidance says three things that matter here:
Since Office 365 version 1809, exact-match VLOOKUP, HLOOKUP and MATCH also cache an index when several lookups read the same range. The guidance does not rank XLOOKUP against the other two, and forum speed tests rarely match a real workbook. On lookups with two or more criteria, a helper key column such as =A2&"|"&B2 lets Excel search one column instead of building arrays.
For a finance team:
Whichever you choose, tie the looked-up column back to the source total, as in the check in XLOOKUP in Excel. A lookup that returns the wrong customer is still a lookup that worked.
INDEX($D$3:$D$7,MATCH(B2,$A$2:$A$6,0)) returns the value one row down.title: "XLOOKUP vs VLOOKUP vs INDEX MATCH: which to use, on the same ledger" description: "XLOOKUP, VLOOKUP and INDEX MATCH compared side by side on one ledger and customer master: default match, missing IDs, inserted columns, left lookups, two-way lookups, speed and version availability. It ends with a rule a finance team can standardize on." seoTitle: "XLOOKUP vs VLOOKUP vs INDEX MATCH compared" metaDescription: "XLOOKUP defaults to exact match, looks left and survives inserted columns; VLOOKUP does none of these. INDEX MATCH does all three, in every Excel." date: 2026-09-30 category: guides industry: finance-teams solution: excel-analysis keywords: ["xlookup vs vlookup", "index match", "index match vs vlookup", "xlookup vs index match", "is xlookup better than vlookup", "index match formula", "vlookup vs xlookup speed"] answer: "Use XLOOKUP if everyone opening the file has Microsoft 365 or Excel 2021 or later: it defaults to exact match, can look left, survives inserted columns and has a not-found argument. Use INDEX MATCH when the file must work in older Excel: it does the same jobs in every version. VLOOKUP is the weakest: approximate by default, right-only, and tied to a column number." faq:
Use XLOOKUP when everyone who opens the file has Microsoft 365 or Excel 2021 or later. Use INDEX MATCH when the file must also open in Excel 2016 or 2019: it does the same jobs, with more typing. Keep VLOOKUP for maintaining old files, because it matches approximately by default, only looks right and depends on a column number.
| VLOOKUP | INDEX MATCH | XLOOKUP | |
|---|---|---|---|
| Default match | Approximate | Approximate (MATCH's default is 1) | Exact |
| Look left | No | Yes | Yes |
| Column inserted in the table | Returns the wrong field | Unaffected | Unaffected |
| Not-found handling | #N/A; wrap in IFNA | #N/A; wrap in IFNA | Built-in argument |
| Last match instead of first | No | No | Yes, search_mode -1 |
| Several columns at once | One formula per column | One stored MATCH reused by several INDEXes | Yes, one formula spills |
| Two-way lookup | With MATCH as the column number | Yes, two MATCHes | Yes, nested |
| Excel versions | All | All | Microsoft 365, 2021, 2024, web |
Two cells in that table catch people out. MATCH, like VLOOKUP, is approximate unless you type 0: Microsoft's MATCH page gives 1 as the default. And Microsoft's XLOOKUP page states that XLOOKUP is not available in Excel 2016 and Excel 2019.
The task: the account manager for each invoice. The Ledger sheet has invoices in A and customer IDs in B. The Customers sheet is the customer master:
| A: ID | B: Name | C: Segment | D: Account manager | |
|---|---|---|---|---|
| 2 | C-1001 | Harlow Foods | Enterprise | Patel |
| 3 | C-1002 | Brightwell Inc. | Enterprise | Jones |
| 4 | C-1003 | Kestrel Supplies | Mid-market | Patel |
| 5 | C-1004 | Northgate Retail | Mid-market | Okafor |
| 6 | C-1005 | Ashby Engineering | Small | Jones |
VLOOKUP in Ledger!C2:
=VLOOKUP(B2,Customers!$A$2:$D$6,4,FALSE)
INDEX MATCH in Ledger!D2:
=INDEX(Customers!$D$2:$D$6,MATCH(B2,Customers!$A$2:$A$6,0))
XLOOKUP in Ledger!E2:
=XLOOKUP(B2,Customers!$A$2:$A$6,Customers!$D$2:$D$6,"Not in master")
Filled down to row 7:
| Invoice | Customer ID | VLOOKUP | INDEX MATCH | XLOOKUP |
|---|---|---|---|---|
| INV-1001 | C-1001 | Patel | Patel | Patel |
| INV-1002 | C-1004 | Okafor | Okafor | Okafor |
| INV-1003 | C-1002 | Jones | Jones | Jones |
| INV-1004 | C-1099 | #N/A | #N/A | Not in master |
| INV-1005 | C-1003 | Patel | Patel | Patel |
| INV-1006 | C-1001 | Patel | Patel | Patel |
On the five matched rows the three agree. VLOOKUP names the whole table and counts to column 4. INDEX MATCH names the column to return and the column to search separately. XLOOKUP does the same in one function.
C-1099 is on an invoice but not in the master. VLOOKUP and INDEX MATCH return #N/A, which breaks any SUM over the column until someone wraps the formula in IFNA. XLOOKUP returns the label in its fourth argument, "Not in master", which can be counted and totaled as its own line. None of the three says why the ID is missing; that needs a reconciliation, not a lookup.
Insert a Region column between B and C in the master. Segment moves to D and Account manager to E, and Excel rewrites every reference:
| Formula | Becomes | Returns for INV-1001 to INV-1003 |
|---|---|---|
| VLOOKUP | =VLOOKUP(B2,Customers!$A$2:$E$6,4,FALSE) |
Enterprise, Mid-market, Enterprise |
| INDEX MATCH | =INDEX(Customers!$E$2:$E$6,MATCH(B2,Customers!$A$2:$A$6,0)) |
Patel, Okafor, Jones |
| XLOOKUP | =XLOOKUP(B2,Customers!$A$2:$A$6,Customers!$E$2:$E$6,"Not in master") |
Patel, Okafor, Jones |
VLOOKUP's range widens to $A$2:$E$6, but the 4 is typed in, and column 4 is now Segment. Every row returns a segment where an account manager should be, with no error. INDEX MATCH and XLOOKUP point at the column itself, so the reference moves with it. The other ways VLOOKUP fails on a ledger are in VLOOKUP in Excel.
The ID for "Kestrel Supplies" sits to the left of the name. INDEX MATCH:
=INDEX(Customers!$A$2:$A$6,MATCH("Kestrel Supplies",Customers!$B$2:$B$6,0))
XLOOKUP:
=XLOOKUP("Kestrel Supplies",Customers!$B$2:$B$6,Customers!$A$2:$A$6)
Both return C-1003. VLOOKUP cannot: Microsoft's VLOOKUP page requires the lookup value to be in the first column of the table, and the only fix is to rebuild the table with the name first.
A Budget sheet with cost centers down column A and months across row 1 (May to December continue in F to M):
| A: Cost center | B: Jan (USD) | C: Feb (USD) | D: Mar (USD) | E: Apr (USD) | |
|---|---|---|---|---|---|
| 2 | Sales | 120,000 | 118,000 | 125,000 | 122,000 |
| 3 | Finance | 40,000 | 40,000 | 41,500 | 41,500 |
| 4 | Ops | 86,000 | 88,000 | 90,500 | 89,000 |
With Finance in G1 and Mar in H1 on the report sheet, INDEX takes a row number from one MATCH and a column number from another:
=INDEX(Budget!$B$2:$M$4,MATCH($G$1,Budget!$A$2:$A$4,0),MATCH($H$1,Budget!$B$1:$M$1,0))
The MATCHes return 2 and 3, and INDEX returns $41,500. The XLOOKUP version nests one inside the other: the inner XLOOKUP returns the whole March column, and the outer one picks Finance from it:
=XLOOKUP($G$1,Budget!$A$2:$A$4,XLOOKUP($H$1,Budget!$B$1:$M$1,Budget!$B$2:$M$4))
Also $41,500. The same grid shape appears in a cross-sell matrix.
Microsoft's Excel performance guidance says three things that matter here:
Since Office 365 version 1809, exact-match VLOOKUP, HLOOKUP and MATCH also cache an index when several lookups read the same range. The guidance does not rank XLOOKUP against the other two, and forum speed tests rarely match a real workbook. On lookups with two or more criteria, a helper key column such as =A2&"|"&B2 lets Excel search one column instead of building arrays.
For a finance team:
Whichever you choose, tie the looked-up column back to the source total, as in the check in XLOOKUP in Excel. A lookup that returns the wrong customer is still a lookup that worked.
INDEX($D$3:$D$7,MATCH(B2,$A$2:$A$6,0)) returns the value one row down.Covirage joins files by exact keys with its own deterministic tools and shows the unmatched rows and the reconciled total, so no lookup formula has to be chosen or maintained. The external AI model explains the result; it does not do the matching. Upload the files and get joined, reconciled tables; see how it works for finance teams. The same joins sit under sales analytics in Excel and customer concentration in Excel, and when the chain of lookups is what holds the workbook together, read four signs a spreadsheet is no longer enough. To total by a key instead of returning one value, see SUMIFS in Excel, and to merge whole files before they reach a formula, see Power Query in Excel.
For most jobs, yes: exact match by default, left lookups, a not-found argument, and no column number to break. Its one drawback is availability: Excel 2019 and earlier do not have it, so shared files may show #NAME?.
Yes. It works in every Excel version and in Google Sheets, handles left and two-way lookups, and appears in most existing finance models. Anyone maintaining older workbooks will meet it.
Differences are small for typical finance workbooks. Microsoft's guidance is that exact-match time grows with the cells scanned, and that approximate match on sorted keys is fast, like a binary search; XLOOKUP's binary search modes need the same sorting. Range size matters more than the function chosen.
The third argument of MATCH is match_type. 0 means exact match. 1, the default, finds the largest value less than or equal to the lookup value in ascending data, and -1 the smallest value greater than or equal in descending data.