Ravindra BagaleCourses & study guides मराठी Track your progress

Guides

RFM Analysis in Excel: Segment Customers by Recency, Frequency and Monetary Value

Ruhi runs Ruhi Organics, a fictional online grocery store in Pune. Her order list has 321 orders from 60 customers. Customer C-1005 last ordered 9 days ago, ordered 14 times and spent ₹29,900: RFM code 555, a Champion. Customer C-1007 also spent well (8 orders, ₹12,710) but the last order was 230 days ago: code 145, At risk. That is the customer Ruhi should call this week, before C-1007 is gone for good.

RFM analysis ranks customers on three questions: how Recently did they buy, how Frequently do they buy, and how much Money do they spend. In Excel you calculate the three values per customer with MAXIFS, COUNTIFS and SUMIFS, turn each into a score from 1 to 5 with percentile cut-offs, and use a simple IF rule to name segments such as Champions, Loyal, At risk and Lost.

Download RFM_Analysis_Template.xlsx

Excel file, 33 KB. Built for Microsoft 365 Excel on Windows; it also opens in Excel 2021 and 2024. All numbers in this workbook are fictional teaching data, not real company figures.

Dashboard sheet of the RFM analysis Excel template: KPI cards, customers and revenue by segment (fictional teaching data)

The Dashboard sheet with the sample data (Ruhi Organics is a fictional business).

Customers sheet of the RFM template with recency, frequency, monetary, scores, RFM code and segment

Quick answer

  1. Put one row per order in a table named Orders (Order ID, Order Date, Customer ID, Amount).
  2. Make a Customers table with each Customer ID once (Data > Remove Duplicates on a copy of the IDs).
  3. Add Last Order =MAXIFS(Orders[Order Date],Orders[Customer ID],[@[Customer ID]]), then Recency Days =AsOfDate-[@[Last Order]].
  4. Add Frequency with COUNTIFS and Monetary with SUMIFS.
  5. Find the 20%, 40%, 60% and 80% cut-offs of each column with PERCENTILE.INC.
  6. Score with COUNTIF against the cut-offs (1 to 5), join the scores into an RFM code and name the segment with IF.
=5-COUNTIF(RCuts,"<"&[@[Recency Days]])
=1+COUNTIF(FCuts,"<"&[@Frequency])
=1+COUNTIF(MCuts,"<"&[@Monetary])

What R, F and M mean

LetterQuestionExcel formula (per customer)Better when
R: RecencyHow many days since the last order?MAXIFS for the last date, then analysis date minus last dateSmaller
F: FrequencyHow many orders?COUNTIFS on Customer IDBigger
M: MonetaryHow much money in total?SUMIFS of Amount on Customer IDBigger

Recency matters most: a customer who bought last week is far more likely to buy again than one who bought last year, even if the old customer spent more. That is why RFM puts R first.

Step 1: Start from one row per order

You need only four columns. Here are the first rows of the sample (the full table has 321 orders):

Order IDOrder DateCustomer IDAmount
R-500102-10-2025C-1009₹310
R-500204-10-2025C-1045₹2,440
R-500305-10-2025C-1010₹1,240
R-500405-10-2025C-1029₹970
  1. Put the cursor in the data and press Ctrl + T to make it a table.
  2. Name it Orders in Table Design > Table Name.
  3. Remove cancelled and fully returned orders first, or they will push customers into the wrong segment.
  4. Pick an analysis date. The template keeps it in a named cell AsOfDate on the Lists sheet (30-09-2026 in the sample). Use a fixed date for a report you will share; use =TODAY() only for a live sheet.

Step 2: Make the customer list

  1. Copy the Customer ID column of Orders to a new sheet.
  2. Select it and click Data > Remove Duplicates > OK.
  3. Press Ctrl + T and name the table Customers.
  4. In Microsoft 365 you can instead type =UNIQUE(Orders[Customer ID]) in an empty cell. It spills the list, but a spilled list cannot sit inside a table, so paste it as values if you want a table.

Step 3: Recency, frequency and monetary formulas

Type each formula once in the first row of the Customers table. The table copies it down to every customer.

ColumnFormulaWhat it does
Last Order=MAXIFS(Orders[Order Date],Orders[Customer ID],[@[Customer ID]])Latest order date of this customer
Recency Days=AsOfDate-[@[Last Order]]Days between the last order and the analysis date
Frequency=COUNTIFS(Orders[Customer ID],[@[Customer ID]])Number of orders
Monetary=SUMIFS(Orders[Amount],Orders[Customer ID],[@[Customer ID]])Total spend

Format Last Order as a date and Recency Days as a whole number. If you see a 5-digit number in Last Order, the cell is just showing the date as a number: choose Home > Number Format > Short Date.

Older Excel

MAXIFS needs Excel 2019, 2021, 2024 or Microsoft 365. In Excel 2016 use =AGGREGATE(14,6,Orders[Order Date]/(Orders[Customer ID]=[@[Customer ID]]),1) instead. It returns the largest date where the ID matches.

Step 4: Turn the values into scores from 1 to 5

A score of 1 to 5 makes customers easy to compare. The common way is quintiles: the best 20% of customers get 5, the next 20% get 4, and so on. You need four cut-off points per column: the 20th, 40th, 60th and 80th percentile.

=PERCENTILE.INC(Customers[Recency Days],0.2)
=PERCENTILE.INC(Customers[Frequency],0.2)
=PERCENTILE.INC(Customers[Monetary],0.2)

With the sample data the cut-offs are:

PercentileRecency DaysFrequencyMonetary
20%18.42.0₹1,432
40%38.63.0₹2,866
60%87.65.4₹7,810
80%213.08.0₹11,878

The template types the percentiles 20%, 40%, 60% and 80% in column A and uses =PERCENTILE.INC(Customers[Recency Days],$A6), so you can change them. The four recency cut-offs sit in Calculations!B6:B9 and have the name RCuts (frequency FCuts, monetary MCuts). Then one COUNTIF gives the score:

  1. R Score =5-COUNTIF(RCuts,"<"&[@[Recency Days]]). C-1007 has 230 days. All four cut-offs are smaller, so COUNTIF gives 4 and the score is 5 - 4 = 1.
  2. F Score =1+COUNTIF(FCuts,"<"&[@Frequency]). C-1007 has 8 orders. Three cut-offs (2, 3 and 5.4) are smaller than 8, so the score is 1 + 3 = 4.
  3. M Score =1+COUNTIF(MCuts,"<"&[@Monetary]). ₹12,710 is above all four cut-offs, so the score is 5.
  4. RFM Code =[@[R Score]]&[@[F Score]]&[@[M Score]] joins them: 145.

Recency is reversed (5 minus the count) because fewer days is better. Frequency has many ties (lots of customers with 1 or 2 orders), so its groups are not exactly 20% each. That is normal.

Step 5: Name the segments

The 125 possible codes are too many to act on, so group them. The template uses R and F only, which is the most common teaching version:

SegmentRule
ChampionsR 4-5 and F 4-5
LoyalR 3 or more and F 3 or more (not Champions)
New / promisingR 4-5 and F 1-2
At riskR 1-2 and F 3 or more
Lost / hibernatingR 1-2 and F 1-2
Needs attentionEverything else (R 3, F 1-2)
=IF(AND([@[R Score]]>=4,[@[F Score]]>=4),"Champions",
 IF(AND([@[R Score]]>=3,[@[F Score]]>=3),"Loyal",
  IF([@[R Score]]>=4,"New / promising",
   IF([@[F Score]]>=3,"At risk",
    IF([@[R Score]]<=2,"Lost / hibernating","Needs attention")))))

The order of the IFs matters: each IF only sees customers that the earlier ones did not catch. With the sample data the Segment summary on the Calculations sheet shows:

SegmentCustomersRevenueShare of revenueAvg recency (days)Avg ordersAvg spend
Champions12₹2,67,30050.3%1411.7₹22,275
Loyal10₹1,05,77019.9%456.3₹10,577
New / promising9₹20,3803.8%201.9₹2,264
Needs attention5₹4,8100.9%641.0₹962
At risk11₹1,10,52020.8%1776.4₹10,047
Lost / hibernating13₹22,2104.2%2312.0₹1,708

12 Champions bring 50.3% of all revenue. The 11 At-risk customers bring another 20.8%, which is a lot of money to lose quietly.

Step 6: Read the R x F grid

The Calculations sheet also counts customers for every pair of R and F scores with formulas such as =COUNTIFS(Customers[R Score],$A25,Customers[F Score],1) (R score in column A, F score fixed per column), and a colour scale turns it into a heat map:

R scoreF = 1F = 2F = 3F = 4F = 5
R = 530126
R = 460222
R = 350331
R = 221351
R = 173020

Top-right (recent and frequent) is where you want customers to be. Bottom-right (frequent but not recent) is the At-risk corner. A full top-left column (recent, one order) means many new customers: the job is to get their second order.

What to do with each segment

SegmentAction
ChampionsThank them, give early access to new products, ask for reviews and referrals. Do not waste discounts here.
LoyalOffer a loyalty or subscription plan and cross-sell the next product.
New / promisingSend a welcome series and a reason for the second order within 30 days.
Needs attentionA short reminder with a popular product; find out what stopped them.
At riskCall or message personally. They used to spend a lot; a win-back offer pays here.
Lost / hibernatingOne low-cost win-back message, then stop spending on them.

Run the analysis again every month with a new analysis date and watch customers move between segments. A rising At-risk count is an early warning, months before revenue drops.

Do it with a PivotTable instead

  1. Click inside the Orders table and choose Insert > PivotTable > OK.
  2. Drag Customer ID to Rows.
  3. Drag Order Date to Values, click it, choose Value Field Settings > Max and format it as a date.
  4. Drag Order ID to Values (it shows Count) and Amount to Values (Sum).
  5. Next to the PivotTable, calculate recency and the scores with normal formulas, or copy the PivotTable and paste it as values first.

The table-and-formula version in the template updates by itself when you add orders; a PivotTable needs Data > Refresh All.

Common mistakes

  • Using =TODAY() in a report you send: the scores change every day, and nobody can check your numbers next week.
  • Leaving cancelled orders or refunds in the data.
  • Scoring over too short a period. Use at least 6 to 12 months of orders, more if customers buy rarely.
  • Using quintiles on a very small list. With fewer than about 20 customers, rank them by hand or use fixed rules such as recency under 30 days.
  • Treating the segment names as fixed laws. They are a starting point; change the IF rules to fit how often your customers normally buy.

Ravindra Bagale's Tip

Before you send any offer, sort the At-risk segment by Monetary, largest first, and look at the top ten names. A personal call to those few customers is worth more than an email blast to everyone.

Practice task

  1. Download the template and open the Customers sheet. Find C-1007 and check its scores: R 1, F 4, M 5, code 145.
  2. On Lists, change AsOfDate to 31-10-2026. Watch recency grow and some Champions drop to Loyal.
  3. Add a new order for C-1007 on the Orders sheet dated 30-09-2026. Check that C-1007 moves out of At risk.
  4. Change the Champions rule to need M Score 4 or more as well, and compare the segment counts.
  5. On Calculations, find which city has the most At-risk customers.

Frequently asked questions

What is a good RFM score?

555 is the best possible code and 111 the worst. What matters more is the segment: Champions and Loyal customers are the ones to protect, At-risk customers are the ones to win back.

Should I use quintiles or fixed rules?

Quintiles (PERCENTILE.INC cut-offs) adjust to your data automatically, so they are a good start. Fixed rules (for example recency under 30 days = 5) are easier to explain and stay stable from month to month. Many teams switch to fixed rules once they know their numbers.

Why is recency scored the other way round?

Fewer days since the last order is better, so the formula subtracts the count of smaller cut-offs from 5. A customer who ordered yesterday gets 5.

Does it work in Google Sheets?

Yes. MAXIFS, COUNTIFS, SUMIFS, PERCENTILE.INC (or PERCENTILE) and COUNTIF all work in Google Sheets. Structured references like Orders[Amount] work only in Sheets tables, so you may need normal ranges such as B2:B400.

Is the data in the template real?

No. Ruhi Organics and all its orders are fictional teaching data.