Data AnalyticsCustomer and product analytics

Analyze support contacts per active customer

PK
Pankit Kumar
Sr. Data Scientist at Parexel (a Goldman Sachs–backed company) · 20 September 2026 · 3 min read
Technically reviewed by Ishaan Sharma
In this article (5 sections)

Support contacts per active customer measures contact volume relative to an activity population. The share of active customers who contacted support measures incidence. They are different: one customer can create several tickets, so the volume ratio can exceed one while the incidence proportion cannot.

Show both when evaluating support demand. A rise in contacts may reflect more affected customers, repeated contacts from the same customers or a change in how tickets are recorded.

Align the period and customer definition

Use the synthetic product analytics lab. The period is January 1 through January 16, 2026 at midnight UTC, exclusive. Active customers are external nonbot users with a valid report creation, publication, view or share in that period.

There are seven active users. The ticket fixture contains seven tickets, one of which belongs to internal user U7. The six external tickets come from U1, U2, U4, U6 and U9; U1 creates two.

For this article, restrict the numerator to tickets from the same active population. Tickets from inactive or unresolved users should be reported separately in a broader support workload report, not silently discarded from operational totals.

Build activity once and join the tickets to it

sql
WITH active AS (
 SELECT DISTINCT e.user_id FROM events e JOIN users u USING(user_id)
 WHERE u.user_kind='external' AND u.is_bot=0 AND e.valid=1
 AND e.event_name IN
     ('report_created','report_published','report_viewed','report_shared')
 AND e.event_time>='2026-01-01T00:00:00Z'
 AND e.event_time<'2026-01-16T00:00:00Z'
), contacts AS (
 SELECT t.* FROM tickets t JOIN active a USING(user_id)
 WHERE t.created_at>='2026-01-01' AND t.created_at<'2026-01-16'
)
SELECT (SELECT COUNT(*) FROM active) AS active_users,
 COUNT(*) AS tickets,COUNT(DISTINCT user_id) AS contacting_users
FROM contacts;

The result is seven active users, six tickets and five contacting users. Contact volume per active user is 6/7 ≈ 0.857, or about 85.7 tickets per 100 active users. Contact incidence is 5/7 ≈ 71.4%.

python
from build_and_verify import database, active_ids, CUTOFF

db = database()
active = set(active_ids(db,'2026-01-01T00:00:00Z',CUTOFF))
tickets = [(ticket,user) for ticket,user,created in db.execute('SELECT * FROM tickets')
           if user in active and '2026-01-01' <= created < '2026-01-16']
db.close()
contacting = {user for ticket,user in tickets}
assert len(active) == 7 and len(tickets) == 6 and len(contacting) == 5
assert sum(user == 'U1' for ticket,user in tickets) == 2
assert contacting <= active
print({'tickets_per_active_user':len(tickets)/len(active),
       'share_contacting':len(contacting)/len(active),
       'tickets_per_contacting_user':len(tickets)/len(contacting)})

Tickets per contacting user are 6/5 = 1.2. That third quantity helps distinguish breadth of impact from repeated contact, although the tiny fixture supports only arithmetic demonstration.

Check what creates a ticket

One conversation can produce multiple tickets if systems reopen cases, split issues or ingest messages from several channels. Define whether the unit is a ticket, conversation, issue or message. Reconcile deduplication and merge rules before comparing periods.

A reduction in tickets could mean fewer problems, but it could also mean a broken contact form or users giving up. Pair contact metrics with successful resolution, response times and relevant product outcomes when those are measured reliably.

The numerator can also be affected by proactive outreach. A support team that opens tickets on customers' behalf should not be compared with a period of customer-initiated contacts without accounting for the changed process.

Avoid an activity denominator that hides affected customers

If a product outage prevents normal usage, impacted customers may stop qualifying as active. Restricting analysis to contemporaneous activity can then omit exactly the users who need help. For an outage investigation, a pre-incident eligible population may answer the question better.

Similarly, a product change can alter both support demand and activity. For a randomized experiment, use a denominator consistent with the assignment and estimand rather than assuming that post-treatment active users are comparable between arms.

Exercise: add a support ticket from a user with no qualifying activity. Keep the active-user ratio unchanged, but include that ticket in a separate reconciliation to total external workload. Explain why both outputs are needed.

NeuraPath's Data Analytics with Generative AI course connects SQL joins with service analytics. A clear support measure identifies its unit, population and relationship to the customer's actual experience.

Continue learning

This article is part of the Customer and product analytics sequence. Use the neighbouring tasks when you need the prerequisite or the next application.

PK
Pankit Kumar
Lead Instructor, NeuraPath Academy

Pankit Kumar has 10 years in Data Science & AI, building and shipping production systems in regulated pharma and clinical environments. He is a freelance trainer at Boston Institute of Analytics, AnalytixLabs and Scaler, and has taught this material to thousands of working professionals.

This article is part of our Data Analytics with Generative AI programme — 3–4 months. The full analyst stack — Excel, SQL, Power BI and Python pipelines — then a generative-AI layer you can prove is right.

Explore Data Analytics with Generative AI
Counselling is free · no obligation

Not sure which programme fits?

Tell us your background and we will map it to the right entry point — including saying so when a cheaper programme is the better fit. A counsellor replies within one working day.