Skip to content

RFM Customer Segmentation

Know which customers are active, which are drifting, and which are gone.

Overview and Use Cases

No two customers behave the same way. Some buy constantly, while some spent heavily last year and have not been back. RFM tells them apart using three things you already know: how recently each person bought, how often they buy, and how much they spend. Those three answers sort your customer list into audience groups you can act on, showing you who to recognize, who to nurture, who to win back, and who has moved on.

Mechanically, RFM AI Signals runs that analysis across your customer profiles and places every customer into one of ten industry-standard segments, from Champions through Lost customers. Rankings come from your own customers, so what counts as a frequent buyer is defined by your business. Each customer arrives labeled, with the underlying scores alongside, ready to build audiences from.

Common use cases

  • Identify and reward top-performing customers with VIP offers before competitive pressure increases
  • Launch automated re-engagement campaigns for at-risk high-value customers who have gone quiet
  • Exclude low-priority customers from expensive paid channels to improve marketing efficiency
  • Adjust communication cadence by customer tier
  • Feed RFM scores as input features into CLTV, propensity, and lookalike models

Who benefits most: Marketing analysts, CRM managers, and lifecycle marketing teams who need fast, actionable customer segments without a data science team on standby.

How It Fits with the Other AI Signals

Question you're asking Use
Who matters, based on past purchasing?RFM AI Signals (you are here): descriptive segments, no modeling required
How likely is this customer to do X?Propensity Scoring AI Signals: a calibrated probability per event
How much will this customer be worth?CLTV AI Signals: a value forecast and percentile rank
Which product should I recommend next?NBP AI Signals: a ranked list of products, services, or content
Which action should I take for this customer?NBA AI Signals: a learned per-user policy across candidate actions

RFM or CLTV? This is the pair readers regularly confuse, since both speak to customer worth. RFM is descriptive and backward-looking: it summarizes what a customer has already done and sorts them relative to everyone else. CLTV is predictive and forward-looking: it forecasts spend over a horizon you choose. RFM tells you who your best customers have been; CLTV tells you who they will be. Reach for RFM when you want segments today with no training step, and for CLTV when you are allocating budget against future value.

These signals feed each other rather than compete. RFM quartiles make strong input features for CLTV, propensity, and lookalike models.

Quick Start

RFM runs as a single function on the Treasure AI ML Batch API. There is no separate training and prediction step: rfm reads your aggregated table, computes quartiles across the whole base, and writes the scored output in one run.

Your input is one row per customer with four columns: an identifier, plus recency, frequency, and monetary_value. RFM does not aggregate transactions for you, so those three metrics must already be calculated. Only the identifier can be named freely, using user_column. The other three names are fixed, so alias them in the query that builds the table. Data Preparation covers the full schema and data requirements.

You only need to set two parameters. input_table and output_table are required. Add user_column only if your identifier column is not already named user. Everything else in this document has a working default.

Security

Store your Treasure AI API key as a Workflow secret named td.apikey, never as a literal value in the workflow definition. Referencing it as a secret keeps the key out of version control, so teams can securely manage sensitive information. See Setting Workflow Secrets from Treasure Console.

# rfm_workflow.dig
# Score every customer in the input table and write quartiles,
# an RFM score, and a named segment.
+run_rfm:
  http>: https://ml-batch-api.treasuredata.com/v1/runs
  method: POST
  headers:
    - authorization: "TD1 ${secret:td.apikey}"
    - X-TD-ML-SESSION-ID: ${session_id}
    - X-TD-ML-ATTEMPT-ID: ${attempt_id}
  store_content: true
  content:
    input_table: your_database.rfm_aggregated
    output_table: your_database.rfm_output
    solution_name: rfm
    solution_arguments:
      user_column: user
      use_sql: true
      # mv_threshold: 0.05   # Uncomment to set a monetary floor

+print_response:
  echo>: "RFM job submitted. Response: ${http.last_content}"

# Poll until the job completes. The API returns HTTP 408 while the job
# is running; Treasure Workflow retries until it receives HTTP 200.
+poll_status:
  http>: https://ml-batch-api.treasuredata.com/v1/runs/${JSON.parse(http.last_content)['id']}/status
  method: GET
  headers:
    - authorization: "TD1 ${secret:td.apikey}"

Expected output: one row per customer in your_database.rfm_output, carrying your three input metrics plus r_quartile, f_quartile, m_quartile, rfm_quartile, rfm_score, and rfm_segment.

user     recency  frequency  monetary_value  r_quartile  f_quartile  m_quartile  rfm_quartile  rfm_score  rfm_segment
61612    3181     4          4115            3           1           4           R3F1M4        2.6667     Promising
39408    3290     9          4893            2           4           4           R2F4M4        3.3333     Cannot lose them
21495    3326     6          2770            1           2           3           R1F2M3        2.0        High Value Sleeping

To create and schedule this workflow, see Getting Started with Treasure Workflow.

Model Configuration

RFM AI Signals takes two kinds of input: the aggregated table you point it at, and the parameters you pass it. Both are documented under Data Preparation and Workflow Parameters below.

rfm

rfm ranks every customer on each of the three dimensions, combines the ranks into a score and a label, and writes the result in a single run.

Data Preparation

A pre-aggregated customer table, one row per customer. Unlike CLTV, RFM does not summarize transactions for you: you supply recency, frequency, and monetary value already computed.

Field Type Required Description
userVARCHARYesUnique customer identifier. This is the only column whose name is customizable, via user_column.
recencyINTEGERYesDays since the customer's most recent transaction. Lower means more recent. Column name is fixed.
frequencyINTEGERYesNumber of transactions in the analysis window. Column name is fixed.
monetary_valueDOUBLEYesTotal spend across the analysis window, in whichever currency or unit your business records. Column name is fixed.

Example rows:

user     recency  frequency  monetary_value
61612    3181     4          4115
39408    3290     9          4893
21495    3326     6          2770
45110    3818     2          133
Data quality requirements
  • Missing values are not handled for you. Remove or impute nulls in recency, frequency, and monetary_value before running. This differs from the older AutoML notebook, which imputed on your behalf.
  • Negative or zero values corrupt the scoring. Clean refunds, voids, and promotional credits upstream.
  • Only user can be renamed. The other three column names are fixed, so alias them in the query that builds your aggregated table.
  • Aim for at least 12 months of history. Shorter windows compress the recency signal and push customers toward the same quartile.

Workflow Parameters

Parameter Type Default Required Description
input_tablestringYesSource aggregated table in dbname.table_name format.
output_tablestringYesDestination table for the scored output, in dbname.table_name format.
output_modestringappendNoHow results are written to the output table. Accepted values: append (adds rows to an existing table), replace (truncates and rewrites).
user_columnstringuserNoName of the customer identifier column in your input table.
use_sqlbooleanfalseNoRun the calculation in Trino instead of Python. Strongly recommended above roughly 10 million rows. See Execution Modes.
use_hivebooleanfalseNoRun the calculation in Hive. Must be set together with use_sql: true. See Execution Modes.
mv_thresholdfloatNoMonetary floor. Customers below this value are assigned monetary quartile 1 regardless of their relative rank. See Monetary Value Threshold.
audience_namestringNoCreates a Master Segment and a child Segment per RFM classification.

Output

One row per customer. Your three input metrics are carried through unchanged, followed by the scoring columns.

Field Type Description
userSTRINGCustomer identifier, carried forward from input.
recencyLONGCarried forward from input.
frequencyLONGCarried forward from input.
monetary_valueDOUBLECarried forward from input.
r_quartileLONGRecency quartile, 1 to 4. Higher means more recent.
f_quartileLONGFrequency quartile, 1 to 4. Higher means more frequent.
m_quartileLONGMonetary quartile, 1 to 4. Higher means higher spend.
rfm_quartileSTRINGAll three quartiles encoded as a label, for example R3F1M4.
rfm_scoreDOUBLEAverage of the three quartiles, (r + f + m) / 3. Ranges from 1.0 to 4.0.
rfm_segmentSTRINGNamed segment, for example Champions. See Segment Definitions.

Example rows:

user     recency  frequency  monetary_value  r_quartile  f_quartile  m_quartile  rfm_quartile  rfm_score  rfm_segment
61612    3181     4          4115            3           1           4           R3F1M4        2.6667     Promising
39408    3290     9          4893            2           4           4           R2F4M4        3.3333     Cannot lose them
21495    3326     6          2770            1           2           3           R1F2M3        2.0        High Value Sleeping
45110    3818     2          133             1           1           1           R1F1M1        1.0        Lost customers

Using the output. Join the table to your customer table so rfm_segment, rfm_score, and rfm_quartile become attributes available to Master Segment rules. Build audiences directly from them: a VIP audience as rfm_segment = 'Champions', a win-back audience as rfm_segment IN ('Cannot lose them', 'High Value Sleeping'), or a suppression list as rfm_score < 1.5. Setting audience_name in the workflow can create the Master Segment and per-segment child Segments for you. Those segments push to downstream activation destinations through standard CDP activation workflows and can feed Journeys, Triggers, and Personalization.

Segment Definitions

How Scoring Works

Each dimension is ranked into quartiles across your entire scored base. Quartile 4 is the top 25%, quartile 1 the bottom 25%. Recency is inverted before ranking, so a recent buyer earns r_quartile 4 even though their raw recency number is low.

The three quartiles combine two ways. rfm_quartile concatenates them into a label such as R3F1M4, useful for exact pattern matching. rfm_score averages them, (r + f + m) / 3, giving a single number from 1.0 to 4.0 for ranking and thresholds.

Segments are then assigned from the quartile pattern. Because quartiles are relative to your own base, every run produces roughly a quarter of customers in each quartile. The segment mix, however, is not fixed: it depends on how the three dimensions correlate in your data.

The Ten Segments

Segment Quartile pattern What it means and what to do
ChampionsR4F4M4Bought recently, buy often, spend the most. Your most valuable customers. Reward them before competitors do.
Loyal CustomersR4F4M3, R4F3M4, R4F3M3, R3F4M4, R3F4M3, R3F3M4, R3F3M3Consistently active and high-value. Responsive to promotions.
Potential LoyalistsR4F4M2, R4F3M2, R4F2M4, R4F2M3, R4F2M2, R3F4M2, R3F3M2, R3F2M4, R3F2M3, R3F2M2Recent buyers who have purchased more than once and spent a good amount. Nurture toward Loyal.
PromisingR4F4M1, R4F3M1, R4F2M1, R4F1M4, R4F1M3, R4F1M2, R3F4M1, R3F3M1, R3F2M1, R3F1M4, R3F1M3, R3F1M2Recent shoppers with strong recency but lower frequency or spend so far. Build the habit.
New CustomersR4F1M1, R3F1M1Purchased recently but only once. Focus on the second purchase.
Cannot lose themR2F4M4, R2F4M3, R2F3M4, R2F3M3, R2F2M4, R2F2M3, R2F1M4, R2F1M3Made large, frequent purchases, but a long time ago. High-value re-engagement priority.
Need AttentionR2F4M2, R2F3M2, R2F2M2Former Potential Loyalists whose engagement is declining. Intervene before they lapse.
HibernatingR2F4M1, R2F3M1, R2F2M1, R2F1M2, R2F1M1Low recency, low frequency, low spend. Low ROI to re-engage.
High Value SleepingR1F4M4, R1F4M3, R1F4M2, R1F3M4, R1F3M3, R1F3M2, R1F2M4, R1F2M3, R1F2M2, R1F1M4, R1F1M3Past Potential Loyalists who have gone quiet. Worth a targeted re-activation.
Lost customersR1F4M1, R1F3M1, R1F2M1, R1F1M2, R1F1M1Lowest scores across all three dimensions. Lowest re-engagement priority.

Reading the Mix

Two segments are worth watching as diagnostics rather than audiences.

Cannot lose them and High Value Sleeping are where retention spend earns the most. Both describe customers who were valuable and have stopped buying, which is the most recoverable form of churn.

A very large Lost customers segment usually points at a data problem rather than a business one. Check the maximum value in your recency column first: if it is far larger than expected, the input table is stale and everyone has drifted toward low recency. If the data is current, the segment is real and reflects acquisition quality or a high one-time purchase rate.

Relevant Topics

Execution Modes

RFM AI Signals can run its calculation three ways. The default is Python, which is fine for small and mid-sized bases.

Mode How to set it When to use it
PythonDefault, set nothingUnder roughly 10 million behavior rows.
Trinouse_sql: trueAbove roughly 10 million rows. Significantly faster at scale and avoids Python memory limits.
Hiveuse_sql: true and use_hive: trueWhen environment constraints require Hive rather than Trino. use_hive alone has no effect.

The output schema is identical across all three modes, so switching is safe and requires no downstream changes.

Monetary Value Threshold

mv_threshold sets a spending floor. Any customer whose monetary_value falls below it is assigned monetary quartile 1 regardless of where they would rank relatively.

This matters because quartiles are relative. If a large share of your base has negligible spend, free-tier signups or a single low-value order, those customers still fill the lower quartiles and push the boundaries down, compressing the range across which your genuinely valuable customers are distinguished. Setting a floor pins the negligible group at quartile 1 and lets the remaining three quartiles spread across customers who actually vary.

Set it in the same unit as monetary_value. There is no default: leave it unset and every customer is ranked purely relatively.

FAQs

Getting Started

What data do I need? A pre-aggregated table with one row per customer and three metrics already computed: recency, frequency, and monetary_value. Aim for at least 12 months of history.

Do I need to set thresholds or train anything? No. Quartiles are computed from your own base on every run, so the cut points come from your data.

How often should I re-run the model? Match your purchase cycle. Weekly suits e-commerce and retail, where churn signals appear quickly. Monthly is fine for lower-frequency categories like travel or automotive. Stale input pushes everyone toward looking inactive, so the schedule matters more than it might appear.

Data and Quality

What happens to missing values? RFM AI Signals does not impute missing values today, so remove or fill nulls before running.

Can I rename the input columns? Only user, via user_column. The names recency, frequency, and monetary_value are fixed today, so alias them in the query that builds your aggregated table.

Can I use RFM if my customers only buy once? It will run, but the frequency dimension carries no information when everyone has the same value, which effectively reduces RFM to a two-dimensional score. Consider supplementing with behavioral engagement metrics, or use Propensity Scoring against a specific outcome instead.

Why are so many of my customers Lost customers? Check data freshness first. Look at the maximum value in your recency column; if it is far higher than expected, the input table is stale. If the data is current, the segment is genuine and reflects acquisition quality or a high rate of one-time purchases. See Reading the Mix.

Running at Scale

When should I enable use_sql: true? Above roughly 10 million behavior rows. See Execution Modes.

What does use_hive do? It routes the calculation through Hive instead of Trino, and must be paired with use_sql: true. Use it only when environment constraints require Hive.

Limits

Can RFM predict what a customer will do next? No. RFM is descriptive: it summarizes what has already happened. For forward-looking questions use CLTV AI Signals for future value, or Propensity Scoring for a specific outcome.

Are quartiles comparable between runs? No. Quartiles are relative to the base scored in that run, so a customer can change quartile without changing behavior if the population around them shifts. Compare segments over time with that in mind, and use raw recency, frequency, and monetary_value when you need an absolute measure.

Does RFM work for subscriptions? Poorly. When monetary value is effectively constant across customers, as with fixed-price plans, the monetary dimension stops discriminating and RFM reduces to recency and frequency. Propensity Scoring against churn is usually the better fit.

How do I activate segments in a campaign tool? Build audiences from rfm_segment, rfm_score, or rfm_quartile in the output table. Setting audience_name in the workflow can create a Master Segment plus a child Segment per classification automatically. Those segments push to downstream activation destinations through standard CDP activation workflows.

Glossary

Term Definition
RecencyDays since a customer's most recent transaction. Lower values mean more recent, and the dimension is inverted before ranking so recent buyers earn a high quartile.
FrequencyNumber of transactions in the analysis window.
Monetary valueTotal spend across the analysis window, in whichever unit your business records.
QuartileOne of four equal-sized groups ranked on a single dimension. Quartile 4 is the top 25%.
rfm_scoreThe average of the three quartile ranks, from 1.0 to 4.0.
rfm_quartileA label encoding all three quartiles, for example R3F1M4. Also available as a Master Segment attribute.
rfm_segmentThe named business category assigned from the quartile pattern, such as Champions or Hibernating.
mv_thresholdA monetary floor. Customers below it are assigned monetary quartile 1 regardless of relative rank.
use_sqlParameter routing the calculation through Trino instead of Python, for faster processing on large datasets.
Win-back campaignA targeted re-engagement effort aimed at inactive but formerly valuable segments such as Cannot lose them.
Master SegmentA Treasure AI CDP construct holding all scored customers. Child Segments are subsets filtered by RFM classification.
PrecisionMLThe production ML infrastructure powering RFM AI Signals, shared across the AI Signals suite.