Skillz · Data Scientist
Updated · 2026-09-22

Skillz Data Scientist
Interview Questions & Guide 2026

THE 60-SECOND BRIEF

As a Data Scientist at Skillz, you sit at the intersection of competitive mobile gaming, real-time data analytics, and platform optimization. Your primary mission is to leverage the vast amounts of telemetry data generated by millions of players to refine game mechanics, improve matchmaking algorithms, and detect fraudulent behavior. Because Skillz operates a high-stakes, real-money competitive environment, your work directly impacts user retention, platform liquidity, and the overall integrity of the ecosystem.

Seniority shifts the scope more than the words in the title do. Earlier-career loops mostly check that you execute a well-posed analysis correctly; senior loops check that you can decide which question is worth answering and defend what you chose not to do.

Skillz candidates report 3 rounds · ≈ 3-5 weeks. The stages below are what candidates describe, not a published process.

Compute expected cost of pity-timer tablesDiagnose churn by progression stage, not calendar dayPrice cosmetics without cannibalising existing sinks

35 min read

Practice 17 Data Scientist prompts
17Practice promptsAcross five skill areas
3With worked solutionsIncluded in the practice prompts

As a Data Scientist at Skillz, you sit at the intersection of competitive mobile gaming, real-time data analytics, and platform optimization. Your primary mission is to leverage the vast amounts of telemetry data generated by millions of players to refine game mechanics, improve matchmaking algorithms, and detect fraudulent behavior. Because Skillz operates a high-stakes, real-money competitive environment, your work directly impacts user retention, platform liquidity, and the overall integrity of the ecosystem.

This role is highly product-focused. You will not be working in a silo; you will collaborate closely with product managers and engineers to design experiments that test new features and analyze the impact of changes on core business metrics. You will be expected to move quickly, translating ambiguous business problems into rigorous, data-driven hypotheses. The environment is fast-paced and requires a blend of strong technical execution and the ability to communicate findings to stakeholders who may not have a technical background.

01

Recruiter Screen

reported

A screening call is a matching exercise run by someone who will not evaluate your statistics. They are checking that the work described on your resume is work you personally did, and that its scope matches the level the role is written for. Logistics get settled in the same half hour so nobody spends an interviewer's afternoon on a mismatch. The answer that fails is the one narrated in the plural. If every sentence is 'we built' and 'the team decided', there is nothing specific to write down about you. Name the piece that was yours, the decision you made inside it, and what changed after.

What to demonstrate

  • Whether the ownership implied by your resume survives one round of follow-up about who actually did which part
  • Whether your described scope (data size, stakeholders, what shipped) matches the seniority the role is written at
  • Whether timeline, location and compensation expectations make the rest of the loop worth scheduling

How to prepare

  • Rewrite your top three resume bullets in the first person singular, each with the decision you made and what moved afterwards, then say them out loud once so the 'we' does not return under pressure
  • Attach one number to each project: the baseline, the change, and the window it was measured over. Where impact was never measured, say that plainly rather than inventing a figure
  • Settle your compensation range before the call and give it as a range with a reason behind it, such as current total comp or a competing timeline, instead of deflecting the question twice
PracHub interview research
02

Technical Assessment

reported

A handful of shapes account for most of what gets asked in this format: a ranking or deduplication inside groups, a running or rolling total, a period-over-period comparison, and a cohort tracked forward over time. Recognising the shape quickly is most of the speed here; deriving it from scratch while a clock runs is where the time goes. Know that a window function keeps every row while a GROUP BY collapses them, and know which one the question needs. If the exercise is in Python instead of SQL, the same shapes arrive as groupby with transform, shift and merge, and the same grain mistakes are available.

What to demonstrate

  • Whether you reach the right construct without a detour, such as ROW_NUMBER over a partition to deduplicate instead of a self-join against a MAX subquery
  • Whether you know what your window frame actually is, since adding ORDER BY inside OVER changes the default frame and silently changes a running total
  • Whether the thing runs. A near-miss that throws an error scores below a plainer query that returns the right rows.

How to prepare

  • Write each of the four shapes once from memory against a small schema and keep the working version somewhere you will reread it: dedupe with ROW_NUMBER, a running total, a month-over-month change with LAG, and a retention table
  • Compute one running total twice on data with tied timestamps, once on the default frame and once with ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW, and look at where the two disagree
  • If Python is on the table, rebuild the dedupe and the running total with groupby and cumsum, then assert the two implementations return identical rows
PracHub interview research
03

Technical Interviews

reported

A handful of shapes account for most of what gets asked in this format: a ranking or deduplication inside groups, a running or rolling total, a period-over-period comparison, and a cohort tracked forward over time. Recognising the shape quickly is most of the speed here; deriving it from scratch while a clock runs is where the time goes. Know that a window function keeps every row while a GROUP BY collapses them, and know which one the question needs. If the exercise is in Python instead of SQL, the same shapes arrive as groupby with transform, shift and merge, and the same grain mistakes are available.

What to demonstrate

  • Whether you reach the right construct without a detour, such as ROW_NUMBER over a partition to deduplicate instead of a self-join against a MAX subquery
  • Whether you know what your window frame actually is, since adding ORDER BY inside OVER changes the default frame and silently changes a running total
  • Whether the thing runs. A near-miss that throws an error scores below a plainer query that returns the right rows.

How to prepare

  • Write each of the four shapes once from memory against a small schema and keep the working version somewhere you will reread it: dedupe with ROW_NUMBER, a running total, a month-over-month change with LAG, and a retention table
  • Compute one running total twice on data with tied timestamps, once on the default frame and once with ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW, and look at where the two disagree
  • If Python is on the table, rebuild the dedupe and the running total with groupby and cumsum, then assert the two implementations return identical rows
PracHub interview research

PracHub editorial advice for the preparation topics above.

01

Testing revenue with a difference in means on a heavy-tailed spend distribution.

Player spend is approximately log-normal with a long Pareto-like tail, so the variance of the sample mean is dominated by a few accounts and the central limit approximation converges slowly at realistic sample sizes. A t-test on raw ARPDAU can flip sign when one account buys a large currency pack. Winsorising or capping at a pre-registered percentile, or testing conversion and conditional spend separately, fixes the variance problem, but note the cost: capping biases toward zero exactly when the true effect lives in the tail, so state the cap before you look.

02

Randomising players individually for a change that acts on a shared pool.

Matchmaking parameters, queue populations, tradeable-item supply and event leaderboards are shared resources: a treated player is matched against a control player, and treated supply lands in the control arm's market. The treatment leaks across arms, so the measured difference understates or reverses the true effect, and the control arm is no longer a clean counterfactual. Cluster by region and mode, or switchback on time slices with a burn-in long enough to clear carryover in the shared state.

03

Stopping an experiment the moment it crosses significance

Fix the sample size or duration before launch, or use a method built for continuous monitoring such as a sequential test, always-valid confidence intervals, or group-sequential boundaries. Repeatedly checking a fixed-horizon p-value against 0.05 pushes the real false-positive rate well above 5 percent.

04

Averaging per-user rates to produce a population rate

Decide which quantity you want: the mean of per-user ratios and the ratio of summed numerator to summed denominator are different estimands, and heavy users dominate one but not the other. For a ratio metric, aggregate numerator and denominator separately and use the delta method for its variance.

Choose a category, try a prompt, then open its approach, worked solution or follow-up when you need it.

14 technical prompts3 include a worked solution

If your p-value is 0.06, how do you decide whether to launch a feature…

medium
statistics and probability

If your p-value is 0.06, how do you decide whether to launch a feature?

Approach
  1. Sanity-check the answer against a simple bound or a simulated case.
  2. Quantify uncertainty explicitly rather than reporting a point estimate alone.
  3. Translate the result into the decision it informs, in one plain sentence.
Follow-up
  • How would you explain this result to someone who does not know statistics?
  • What sample size would you need to detect an effect half this size?

How would you design a product metric to measure the "fairness" of a 2…

medium
machine learning and modelling

How would you design a product metric to measure the "fairness" of a 2-player matching algorithm?

Approach
  1. Pick an evaluation metric that matches the cost of each error type, not a default.
  2. Check what information would not exist at prediction time, and exclude it.
  3. Set a baseline first, so any model has something honest to beat.
Follow-up
  • How would you choose the decision threshold, and who owns that choice?
  • Where could label leakage enter this setup?

Three integrity checks over a ledger and purchase join

mediumWorked solution
data qualityjoin fan-outreversals

Given ledger (ledger_id, player_id, occurred_at, currency_code, delta_amount, balance_after, is_reversal, reversed_ledger_id, transaction_id) and txns (transaction_id, player_id, purchase_ts, price_usd_net, status), write check_ledger(ledger, txns) returning violations as rule_code, player_id, ledger_id, detail. Rule 1: balance_after that does not equal the prior balance_after plus delta_amount within (player_id, currency_code) ordered by (occurred_at, ledger_id). Rule 2: is_reversal rows whose reversed_ledger_id is missing, points at a different player or currency, or whose delta_amount is not the exact negative of its target. Rule 3: transaction_ids carried on more than one ledger row. For rule 3 also report completed net revenue computed before and after an inner merge of txns onto ledger.

Approach
  1. Rule 1 is a shifted comparison inside the sorted group: take balance_after.shift() within (player_id, currency_code) ordered by (occurred_at, ledger_id) and flag where balance_after minus the prior value does not equal delta_amount. Compare the first row of each group against delta_amount alone. Keep the arithmetic in int64; a float cast makes large balances differ at the eighth significant digit and floods the rule with phantom violations.
  2. Rule 2 is a self-merge of the reversal rows back onto the ledger by reversed_ledger_id. Use a left merge so a dangling pointer survives as a null and becomes a violation. An inner merge deletes precisely the rows you were asked to find.
  3. Split rule 2 into three codes rather than one: missing target, mismatched player or currency, and a delta that is not the exact negative. Collapsing them throws away the diagnostic that tells you whether this is a bad backfill or a bad writer.
  4. Rule 3 is ledger.groupby('transaction_id').size() over non-null transaction_ids, kept where the count exceeds one. Then compute completed net revenue two ways: from txns alone, and from the same rows after an inner merge onto ledger. The merged figure is inflated by exactly the fan-out multiplicity, and it is the figure that ends up in a revenue deck when someone joins for an item name.
  5. Return one long frame with a rule_code column rather than three separate frames. A monitor wants counts per rule per day, and a wide shape makes that awkward to chart and awkward to alert on.
Worked solution 30 min
  1. Sort once on (player_id, currency_code, occurred_at, ledger_id) and build the shifted balance comparison in int64, handling the first row of each group as its own case.
  2. Left-merge reversal rows onto the ledger by reversed_ledger_id and emit three distinct rule codes from the merged result.
  3. Group the non-null transaction_ids, keep the fan-out cases, and compute the two revenue totals.
  4. Concatenate all violations into one long frame with rule_code, and return it alongside the two revenue figures.
EXPECTED RESULTA long frame of (rule_code, player_id, ledger_id, detail) plus two revenue totals, where the merged total exceeds the true total by the sum, over fan-out transactions, of (row_count - 1) times price_usd_net.
Follow-up
  • Rule 1 fires on 0.02 percent of rows, all on one currency, all inside one hour. Incident or backfill, and what distinguishes them in the data?
  • How do you run rule 1 incrementally each day without re-reading the full history, given that the check is defined over adjacent rows?
  • Rule 3 flags a transaction with three grant rows that turns out to be legitimate. What produces several ledger entries per purchase, and how do you whitelist it without blinding the rule?

For a candidate whose interviews will centre on A/B testing, metric movement and causal claims. Design comes before arithmetic, arithmetic before analysis, and the week ends by rehearsing the readout rather than the derivation.

Small steps. Visible outcomes.0 / 7 completed
ONE WEEK · YOUR PACE

Prepare, practise & reflect

One practical outcome each day. Spend longer where you need it.

0 / 7 done
01Design one test end to end on paper
  • Take a single feature change and write the full design: randomization unit, the exact point of exposure, the primary metric with its grain, guardrails, allocation, planned duration, and the decision rule committed before any data exists.
  • Write why the randomization unit must sit at or above the level where treatment can spill over, and give one case where user-level randomization is still contaminated (shared accounts or devices, or two participants in the same marketplace).
  • State in advance what you will do if the primary metric is flat while a secondary metric is significant.

Deliverable: A one-page test design with a decision rule written before launch.

Practice prompt ↗Practice prompt ↗Practice prompt ↗Worked solution ↗
02Power arithmetic until it is automatic
  • Compute required sample size per arm for a binary metric with the normal approximation, n is approximately 2 times (z for alpha/2 plus z for power) squared times p(1 minus p) divided by delta squared, for baselines of 2, 10 and 40 percent at a 5 percent relative lift, and note that for a fixed relative lift the requirement falls as the baseline rises because delta grows proportionally with p.
  • Redo the calculation for a continuous metric using variance in place of p(1 minus p), and show why a heavy-tailed quantity such as revenue per user needs either far more traffic or a capped version with a stated cap.
  • Convert one of the results into weeks given a weekly eligible traffic figure, then list the two honest ways to shorten it (accept a larger detectable effect, or reduce variance) and write why quietly lowering the power target is a decision to miss more real wins, not a speedup.

Deliverable: A small script or sheet that maps baseline, minimum detectable effect, alpha and power to sample size and weeks, cross-checked against a published calculator.

Practice prompt ↗Practice prompt ↗Practice prompt ↗
03Variance and the unit-of-analysis problem
  • Take a ratio metric whose denominator is not the randomization unit (clicks per session, randomized by user) and compute the standard error twice, once naively at session level and once by the delta method or a user-level bootstrap, then record how much the naive version understates it.
  • Implement CUPED on simulated data: choose a pre-period covariate X measured before assignment, estimate theta as Cov(Y, X) divided by Var(X), and analyse Y minus theta times (X minus its mean) in place of Y. Confirm the variance of the adjusted outcome equals the raw variance multiplied by one minus the squared correlation between Y and X, so a correlation of 0.45 removes about 20 percent of the variance and not 80.
  • Now run that simulation a few hundred times and confirm the adjusted effect estimate is unbiased for the same effect rather than numerically identical to the raw one. Within any single run the two differ, sometimes by a large fraction of the true effect, because the two arms' pre-period covariate means never coincide exactly in a finite sample; they agree in expectation, which is the property that matters and the one to state out loud.

Deliverable: A notebook showing the adjusted estimator with a measurably smaller variance than the raw one, plus a repeated-simulation table showing the two estimators agreeing on average while differing run by run.

Practice prompt ↗Practice prompt ↗Practice prompt ↗
04Validity threats you can actually test for
  • Run a sample ratio mismatch check as a chi-square goodness-of-fit test against the intended allocation, and write the three causes you would chase first (assignment logged before exposure, an arm-specific redirect or load failure, bot filtering applied asymmetrically).
  • Simulate peeking: generate A/A data, test daily at alpha 0.05 across 14 looks, record the inflated false positive rate, then apply an alpha-spending boundary or commit to a fixed horizon and confirm the rate returns to nominal.
  • Write how you would separate a novelty effect from a durable lift using the treatment effect plotted against days since first exposure, and what shape would change your recommendation.

Deliverable: One table showing the peeking false positive rate before and after correction, plus a written SRM triage list.

Practice prompt ↗Practice prompt ↗Worked solution ↗
05When randomization is not available
  • Write the identifying assumption for difference-in-differences (parallel trends in the absence of treatment), then plot pre-period trends for two candidate control groups and justify rejecting one of them.
  • Design a switchback test for a change where user-level randomization would leak across participants, choosing a time-block length against the carryover you expect and saying how you would detect carryover in the data.
  • List what an interrupted time series or a synthetic control buys you and the one thing neither can rule out: an unobserved shock that coincides with the launch.

Deliverable: A one-page memo recommending a single quasi-experimental design and naming its weakest assumption explicitly.

Practice prompt ↗Practice prompt ↗
06The readout query
  • Write the assignment-to-exposure join that returns exactly one row per unit per experiment, and handle units appearing in both arms by excluding and counting them rather than silently keeping one.
  • Compute the per-arm metric, its variance and the relative lift with a confidence interval in SQL, then reproduce the identical numbers in a notebook as a cross-check.
  • Add a segment breakdown and write the sentence that keeps it from being p-hacking: segments declared in advance, everything else reported as exploratory and corrected for multiplicity.

Deliverable: A single query that outputs the full readout table, matched to a notebook recomputation.

Practice prompt ↗Practice prompt ↗
07Present it to someone who will not read the appendix
  • Give a 10-minute readout of a real or simulated experiment in the order decision, number, uncertainty, caveat.
  • Have your listener ask "can we ship it" in the case where the primary is flat and a guardrail moved, and answer with a recommendation rather than a request for more data.
  • Rewrite your opening line so the recommendation lands before any methodology.

Deliverable: A one-page readout whose first line is the recommendation.

Practice prompt ↗Practice prompt ↗Worked solution ↗

Expand any day for tasks and deliverables. Your progress is saved on this device.

A number you shipped turned out to be wrong, and someone had already acted on it. That is one of the most useful stories a data person can carry. What is being scored is how fast you noticed, who you told first, and what you changed in the process so the same class of error could not repeat quietly.

How do you maintain high quality and rigor in your work when the busin…

medium
behavioural and stakeholder questions

How do you maintain high quality and rigor in your work when the business is pushing for speed?

Approach
  1. Quantify the outcome, including what you would not claim credit for.
  2. Name the disagreement or constraint, and how you resolved it with evidence.
  3. Close with what you would do differently, concretely.
Follow-up
  • What would you do differently if you ran that project again?
  • How did you know the outcome was caused by your change?

Disagree with a queue-tolerance change using guardrail data

medium
guardrailsconditioning on successswitchbackdisagreement

A product manager proposes widening matchmaking skill tolerance in one region because p95 matchmaking wait there is 71 seconds against 34 seconds elsewhere. You have fct_match_participant with matchmaking_wait_seconds, skill_rating_before, result, disconnected, server_region and game_mode. Your concern is that the wait percentile is computed only over matches that actually formed, and that wider tolerance raises mismatch and abandon rate. The PM has a deadline and reads your concern as blocking. Make the disagreement in a way that keeps the decision moving, and state the evidence that would change your mind.

Approach
  1. Agree on the problem in the first sentence. The wait gap is real and worth fixing; the disagreement is about the price of this particular fix, which is a far easier conversation than one that sounds like a veto.
  2. Name the measurement defect concretely rather than generally. p95 matchmaking wait is an order statistic over matches that formed, so players who gave up in queue are absent from it entirely. A queue that fails outright reports an excellent p95. Pair it with a queue-abandonment rate measured on queue entries, and with match abandon rate defined over result = 'abandon' or disconnected = true.
  3. Bring a quantity instead of an objection. From current data, bucket matches by absolute skill gap between teams using skill_rating_before and plot abandon rate and disconnect rate per bucket, cut by game_mode and server_region. That converts 'mismatch is bad' into a rate per unit of tolerance, which the PM can trade against seconds of wait.
  4. Propose the design that settles it, and explain why the obvious one is invalid: queue population is shared, so a treated player is matched against a control player and the treatment leaks across arms. Randomise by region and mode cluster, or switchback on time slices with a burn-in long enough for the queue to clear, and analyse at the randomisation unit.
  5. State your falsifier explicitly, for example that if abandon rate is flat across the top two skill-gap buckets in this region, you withdraw the objection.
  6. Give the PM something shippable inside the deadline, such as a bounded tolerance increase in the worst hours only, with the guardrail thresholds pre-registered before launch.
Follow-up
  • How long a burn-in would you use for a switchback here, and what in the data tells you it is long enough?
  • Queue-abandonment is not in the tables listed. What would you instrument, and what would you do for this decision in the meantime?
  • The PM ships it globally without a test. What do you measure afterwards, and what can that measurement honestly support?

Turn 'engagement is down' into a scoped answerable brief

easy
scopingrelease calendartriagemetric definition

A studio lead messages: engagement is down, can you look into it. You have dim_player, fct_session, fct_match_participant and the release calendar. Daily core-loop players, defined as distinct players per UTC day with at least one match reaching a terminal result other than abandon, is down 6% week over week, and a content release landed nine days ago. You have 30 minutes before a standup. Produce the scoping questions you would ask, the first three cuts you would run, and the one-paragraph brief you send back before doing deeper work.

Approach
  1. Pin the metric and the comparison before touching data. Ask which number the lead actually saw and over what window, because a week-over-week read nine days after a release is measuring post-release decay by construction, and that alone may be the whole answer.
  2. Ask the decision question, not more metric questions: what would the lead do differently if this turns out to be new players versus returning, one platform versus all, one region versus global. Scope follows the decision, and an investigation with no decision attached should be declined or deferred.
  3. Run three cheap cuts that split the space rather than confirm a hunch. First, new versus existing by install cohort age, which separates an activation problem from a retention problem. Second, platform crossed with app_version, where a bad build shows as a concentration of fct_session.ended_reason = 'crash' and truncated duration_seconds. Third, server_region, where an infrastructure incident shows as elevated match abandon rate and p95 matchmaking wait rather than as fewer app opens.
  4. Re-baseline against the matched day in the previous release cycle instead of against last week, so the comparison is not dominated by the release calendar.
  5. Send a brief that states what you confirmed, what you ruled out, the current best explanation with its confidence, and the size of the next block of work with the question it would close.
Follow-up
  • The crash concentration is on one device_model at one app_version. What do you send, to whom, and how urgently?
  • How would you tell a genuine drop apart from an instrumentation change that altered which sessions get logged?
  • If all three cuts come back flat, what is your fourth cut and why that one?
  • 01

    How do you maintain high quality and rigor in your work when the business is pushing for speed?

  • 02

    A product manager proposes widening matchmaking skill tolerance in one region because p95 matchmaking wait there is 71 seconds against 34 seconds elsewhere. You have fct_match_participant with matchmaking_wait_seconds, skill_rating_before, result, disconnected, server_region and game_mode. Your concern is that the wait percentile is computed only over matches that actually formed, and that wider tolerance raises mismatch and abandon rate. The PM has a deadline and reads your concern as blocking. Make the disagreement in a way that keeps the decision moving, and state the evidence that would change your mind.

  • 03

    A studio lead messages: engagement is down, can you look into it. You have dim_player, fct_session, fct_match_participant and the release calendar. Daily core-loop players, defined as distinct players per UTC day with at least one match reaching a terminal result other than abandon, is down 6% week over week, and a content release landed nine days ago. You have 30 minutes before a standup. Produce the scoping questions you would ask, the first three cuts you would run, and the one-paragraph brief you send back before doing deeper work.

PracHub interview preparation framework
Is this an official Skillz interview guide?

No. It is PracHub's own research and practice material for the Data Scientist role at Skillz. Rounds and questions reflect what candidates have reported, not a process Skillz has published, and they change over time. Confirm the current format and scope with your recruiter.

PracHub interview research
How difficult are the coding assessments?

A: The assessments are generally straightforward but require speed and accuracy. Focus on writing clean code that handles edge cases effectively, rather than over-engineering your solution.

PracHub interview research
Does the team value senior experience?

A: The team has a mix of experience levels. While the culture is growth-oriented and often favors high-potential talent, they do look for seasoned individuals who can mentor others and drive complex, ambiguous projects.

PracHub interview research
What is the best way to prepare for the case study round?

A: Practice "product-sense" questions. Treat the case study as a conversation where you explore the metrics, potential biases, and the business trade-offs of your proposed solution.

PracHub interview research
How long does the entire process take?

A: The timeline can vary, but typically it spans several weeks from the initial recruiter screen to the final decision. Stay engaged and responsive to keep the momentum going.

PracHub interview research
Sources & methodology 3 sources ↗

Official role evidence, timestamped platform data and clearly labeled preparation advice.