You shipped a new feature three months ago. You have a vague sense that some users are using it, but you don't know how many, how often, or whether the users who adopt it stick around longer than those who don't. Your analytics tool shows page views. Your CRM shows nothing useful. The actual answer is sitting in your database, in the events or usage tables your application has been writing to the whole time.
Feature adoption is one of the most important leading indicators for a SaaS product. It tells you which features are driving retention, which are being ignored, and whether your onboarding is getting users to the moments that matter. But most product teams track it badly or not at all because pulling this data requires SQL skills they don't have or a data analyst who has a queue of other priorities.
This guide covers how to think about feature adoption metrics, what queries to run, and how to get this data without depending on someone else to write the SQL for you.
What Feature Adoption Actually Means
Feature adoption is not a single number. It's a family of related metrics that answer different questions:
Reach: What percentage of your active user base has tried this feature at least once?
Depth: Among users who've tried it, how many use it regularly vs. once and never again?
Stickiness: Do users who adopt this feature have higher retention than those who don't?
Time to adoption: How long after signup do users typically discover and use this feature?
Each of these requires a different query, but all of them should be answerable from your application's usage data.
What Your Database Needs to Have
For any of this to work, your application needs to be logging usage events somewhere. The most common patterns:
Events table: A table where your app writes a row every time a user takes a meaningful action.
-- Typical events table structure
CREATE TABLE events (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT NOT NULL,
event_name VARCHAR(100) NOT NULL,
properties JSONB,
created_at TIMESTAMPTZ DEFAULT NOW()
);Feature-specific tables: Some apps log feature usage in dedicated tables e.g., document_exports, api_calls, report_runs. These are often easier to query than a generic events table.
Session or activity tables: Some applications track sessions or active periods, which can be used to infer which features a user interacted with.
If you're not logging usage events yet, start now. The schema above is a good starting point. Instrument every meaningful action feature views aren't enough, you want feature completions (the user actually did the thing, not just opened the modal).
The Core Feature Adoption Queries
Here are the four queries you'll run most often.
1. Reach: What percentage of active users have used this feature?
-- Feature reach: users who used "export_report" in last 30 days
-- as a percentage of all active users in last 30 days
WITH active_users AS (
SELECT DISTINCT user_id
FROM events
WHERE created_at >= NOW() - INTERVAL '30 days'
),
feature_users AS (
SELECT DISTINCT user_id
FROM events
WHERE event_name = 'export_report'
AND created_at >= NOW() - INTERVAL '30 days'
)
SELECT
COUNT(DISTINCT fu.user_id) AS feature_adopters,
COUNT(DISTINCT au.user_id) AS active_users,
ROUND(
100.0 * COUNT(DISTINCT fu.user_id) / NULLIF(COUNT(DISTINCT au.user_id), 0),
1
) AS adoption_rate_pct
FROM active_users au
LEFT JOIN feature_users fu ON au.user_id = fu.user_id;2. Depth: How often do adopters use it?
-- Average usage frequency among users who've adopted the feature
SELECT
user_id,
COUNT(*) AS uses_per_month
FROM events
WHERE event_name = 'export_report'
AND created_at >= NOW() - INTERVAL '30 days'
GROUP BY user_id
ORDER BY uses_per_month DESC;Run this with PERCENTILE_CONT if you want to see the median rather than the average (the average gets skewed by power users):
SELECT
PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY uses_per_month) AS median_uses
FROM (
SELECT user_id, COUNT(*) AS uses_per_month
FROM events
WHERE event_name = 'export_report'
AND created_at >= NOW() - INTERVAL '30 days'
GROUP BY user_id
) sub;3. Stickiness: Do feature adopters retain better?
-- 30-day retention: adopters vs. non-adopters
-- Cohort: users who signed up 60-90 days ago
WITH cohort AS (
SELECT id AS user_id, created_at AS signup_date
FROM users
WHERE created_at BETWEEN NOW() - INTERVAL '90 days' AND NOW() - INTERVAL '60 days'
),
adopters AS (
SELECT DISTINCT e.user_id
FROM events e
JOIN cohort c ON e.user_id = c.user_id
WHERE e.event_name = 'export_report'
AND e.created_at <= c.signup_date + INTERVAL '30 days'
),
retained AS (
SELECT DISTINCT user_id
FROM events
WHERE created_at >= NOW() - INTERVAL '30 days'
)
SELECT
'Adopters' AS segment,
COUNT(DISTINCT a.user_id) AS users,
COUNT(DISTINCT r.user_id) AS retained_users,
ROUND(100.0 * COUNT(DISTINCT r.user_id) / NULLIF(COUNT(DISTINCT a.user_id), 0), 1) AS retention_pct
FROM adopters a
LEFT JOIN retained r ON a.user_id = r.user_id
UNION ALL
SELECT
'Non-Adopters',
COUNT(DISTINCT c.user_id) - COUNT(DISTINCT a.user_id),
COUNT(DISTINCT CASE WHEN r.user_id IS NOT NULL AND a.user_id IS NULL THEN c.user_id END),
ROUND(100.0 * COUNT(DISTINCT CASE WHEN r.user_id IS NOT NULL AND a.user_id IS NULL THEN c.user_id END) /
NULLIF(COUNT(DISTINCT c.user_id) - COUNT(DISTINCT a.user_id), 0), 1)
FROM cohort c
LEFT JOIN adopters a ON c.user_id = a.user_id
LEFT JOIN retained r ON c.user_id = r.user_id;4. Time to adoption: How long until users discover the feature?
-- Median days from signup to first use of a feature
SELECT
PERCENTILE_CONT(0.5) WITHIN GROUP (
ORDER BY EXTRACT(EPOCH FROM (first_use - signup_date)) / 86400
) AS median_days_to_adoption
FROM (
SELECT
u.id AS user_id,
u.created_at AS signup_date,
MIN(e.created_at) AS first_use
FROM users u
JOIN events e ON u.id = e.user_id
WHERE e.event_name = 'export_report'
GROUP BY u.id, u.created_at
) sub;Tracking Adoption Trends Over Time
A single adoption rate number is less useful than the trend. You want to know whether adoption is growing after you improved onboarding, or whether it plateaued.
-- Weekly feature adoption rate over the last 12 weeks
WITH weeks AS (
SELECT generate_series(
DATE_TRUNC('week', NOW()) - INTERVAL '11 weeks',
DATE_TRUNC('week', NOW()),
INTERVAL '1 week'
) AS week_start
),
active_per_week AS (
SELECT DATE_TRUNC('week', created_at) AS week_start, COUNT(DISTINCT user_id) AS active_users
FROM events
GROUP BY 1
),
feature_per_week AS (
SELECT DATE_TRUNC('week', created_at) AS week_start, COUNT(DISTINCT user_id) AS feature_users
FROM events
WHERE event_name = 'export_report'
GROUP BY 1
)
SELECT
w.week_start,
COALESCE(a.active_users, 0) AS active_users,
COALESCE(f.feature_users, 0) AS feature_users,
ROUND(100.0 * COALESCE(f.feature_users, 0) / NULLIF(COALESCE(a.active_users, 0), 0), 1) AS adoption_pct
FROM weeks w
LEFT JOIN active_per_week a ON w.week_start = a.week_start
LEFT JOIN feature_per_week f ON w.week_start = f.week_start
ORDER BY w.week_start;Run this query before and after a change to your onboarding flow and you'll immediately see whether it moved the needle.
Getting These Answers Without Writing SQL
If these queries look intimidating, there's a more direct path. AI for Database connects to your PostgreSQL, MySQL, or other database and lets you ask these questions in plain English:
The tool translates your question into SQL, runs it against your live database, and shows you the result as a table or chart. You can pin the answers to a product dashboard that updates automatically.
This is particularly useful for product managers who need these numbers regularly but don't have a data analyst assigned to them. Instead of logging a request and waiting, you get the answer in seconds.
Turning Adoption Data Into Action
The metrics are only useful if they drive decisions. Here's how to use each one:
Low reach (< 20% of active users have tried the feature):
The feature exists but users don't find it. Check: is it discoverable? Is it surfaced in onboarding? Consider an in-app tooltip or a targeted email to users who haven't tried it.
Low depth (users try it once and don't come back):
The feature isn't sticky. The first-use experience may be confusing, or the feature may not deliver enough value to warrant a repeat. Talk to users who tried it once.
High adoption but no retention lift:
The feature is used but isn't a driver of retention. It might be nice-to-have rather than core. This is fine, but don't over-invest in improving it.
Long time to adoption (> 14 days from signup):
Users are finding the feature, but too late. Move it earlier in the onboarding flow. If users who adopt within their first 7 days retain significantly better than those who adopt later, that's a strong signal.
Setting Up Automated Adoption Alerts
Once you know your baseline adoption rate for a key feature, set up an alert if it drops. A sudden drop in feature adoption might indicate a bug, a UI regression, or a change that confused users.
With AI for Database action workflows, you can define a condition "if this week's adoption rate for export_report drops more than 15% vs. last week" and trigger a Slack notification automatically. No stored procedures, no DBA involvement, just a plain-English workflow definition.
Making Feature Adoption a Habit
The companies that build great products don't just ship features they watch what happens after the ship. Feature adoption metrics give you the feedback loop to know whether what you built is actually being used and whether it's making users more likely to stick around.
The data is already in your database. The hardest part isn't the SQL it's making a habit of looking at the numbers before making the next product decision.
Try AI for Database free at aifordatabase.com to start pulling feature adoption metrics from your database without writing a single line of SQL.