Documentation

Setting up quotas

MX8 Labs allows researchers to define and apply screeners for targeting respondents based on demographic or behavioral conditions. There are two complementary tools: custom quota groups (s.quota() and s.set_quota()), which you build yourself, and pre-built standardized screeners (s.standard_screener()), which apply national demographics and weighting for a country. A survey can use either or both.

This guide outlines how to set up screeners using both methods.

1. Fielding Strategies

MX8 Labs supports three fielding strategies, chosen using the Fielding Strategy setting on the survey:

StrategyWhen a matching line stops accepting respondentsQuota qualificationWhen the survey is complete
StrictAt its explicit maximum, if set; otherwise at its completion target.An open matching line is required in every quota group encountered. Further respondents are rejected once the overall respondent target is reached.Both the overall respondent target and every positive quota completion target must be met.
Quota drivenAt its explicit maximum, if set. Without a maximum, the line remains open after its completion target is met.An open matching line in at least one quota group is required.Every positive quota completion target must be met; the total may be below or above the overall respondent target.
Respondent drivenNeither the completion target nor an explicit maximum closes the line.A matching line in at least one quota group is required, and the overall respondent target must not yet have been reached.The overall respondent target must be met, even if some quota targets remain unfilled.

If there are no positive quota completion targets, the overall respondent target determines completion.

For a fuller explanation of each strategy, how to choose between them, and how they interact with quota design, see the Quota management methodology page.

If you are using the quota-driven strategy, then you may see that the target respondents line is replaced with an "estimated respondents line" that shows the number of estimated respondents required to complete each quota:

Setting Up Quotas

2. Defining Quota Lines

Use s.quota() to define individual quota lines. These specify criteria that respondents must meet.

Code
s.quota(name: str, criteria: bool, quota: float = 0.0, min_respondents: int = 0, max_respondents: int | None = None)

Example:

Code
age = s.numeric_question("How old are you?", min_max=(18, 100)) gender = s.select_question("What is your gender?", options=["Male", "Female"]) s.quota("Young Males", criteria=(age < 35) & (gender == "Male"), quota=0.25)

Notes:

  • s.quota() only defines a quota line — it has no effect until the line is passed to s.set_quota() (see section 3).
  • quota is the proportion of the sample for that group.
  • During fielding, the actual achieved sample may deviate from these targets due to rounding, natural variation in panel availability, or speed differences between groups.
  • In reporting, MX8 Labs automatically applies weights to adjust back to the target proportions defined in the quotas.

Place quota questions early

A quota line references answers to earlier questions, so those questions must be asked before the quota is evaluated. As a best practice, put the questions your quotas depend on (age, gender, region, and other screening demographics) as early in the survey as possible. This means a respondent who is over quota is identified and terminated before they spend time on the main questionnaire, which respects their time and avoids paying for interviews you cannot use.

3. Combining Quota Lines into a Quota

Use s.set_quota() to combine a set of individual quota lines into a single quota. Weighted quota lines within a group must sum to 100% (within ±0.5%). Boost-only lines that set min_respondents without a quota value are exempt. See section 5.

Code
s.set_quota( name="Demographics", quotas=[ s.quota("Young Males", criteria=(age < 40) & (gender == "Male"), quota=0.25), s.quota("Older Males", criteria=(age >= 40) & (gender == "Male"), quota=0.25), s.quota("Young Females", criteria=(age < 40) & (gender == "Female"), quota=0.25), s.quota("Older Females", criteria=(age >= 40) & (gender == "Female"), quota=0.25), ] )

Respondents must qualify for at least one of the quota lines. Those who do not qualify or exceed the quota limits (depending on strategy) are terminated. A terminated respondent is recorded with a quota-screenout status, which maps to the over-quota exit link you configure for your sample provider. See Setting up any sample provider. Their partial data is still available for analysis where useful; see Analyzing partial completes for market sizing.

If you are running more than one quota group at once, see Combining multiple quota groups for how the groups are evaluated together.

Note: If quotas are not perfectly filled (e.g., one group is harder to recruit or fills faster), the final dataset will still reflect the specified proportions through post-fielding weighting.

Exclusive vs. non-exclusive quotas

By default, s.set_quota() is exclusive: each respondent is counted toward only one matching, open quota line (the line with the lowest ratio of completes to completion target). If you want a respondent to count toward every matching, open line, pass exclusive=False:

Code
s.set_quota(name="Device ownership", quotas=[...], exclusive=False)

Non-exclusive quotas are useful for overlapping categories within a single group, such as device ownership, where a respondent may match several lines at once.

4. Using Standard Screeners

MX8 Labs provides pre-defined screeners per country. These include standard demographic questions and weights to national averages, where the selected screener supports them.

To apply a standard screener:

Code
s.standard_screener(country="GB")

Parameters:

  • country: Two-letter country code (e.g., "US", "GB", "AU").
  • name: Optional. Defaults to "GenPop". Alternate versions may be available (e.g., "NestedGenPop", "16to54").
  • id: Optional. A stable identifier prefix for the generated screener questions. If not set, the question text is used.

Example:

Code
s.standard_screener(country="US", name="GenPop")

If the named screener is not available for the specified country, an error is raised.

The supported combinations are:

json
{ "US": ["GenPop", "NestedGenPop"], "GB": ["GenPop", "16to54"], "AU": ["GenPop"], }

5. Boosting Individual Quota Lines

In some cases, a group may be too small to support reliable analysis even if its proportional target is met. For example, a group with a 5% target in a 500-person survey would only yield 25 respondents.

To ensure a higher base size for analysis, use the min_respondents parameter to boost that line during data collection:

Code
s.quota("LGBTQ+", criteria=(orientation == "LGBTQ+"), quota=0.05, min_respondents=50)

In this example, although 5% of 500 is 25, the min_respondents value of 50 will take precedence.

A positive minimum always replaces the percentage-derived completion target, not only when it is higher. Under respondent-driven fielding, the survey can still finish at its overall respondent target before this minimum is reached.

If you don't include the quota element for your boost line, then it won't be weighted, for example, if you want at least 500 Xbox and PlayStation owners but don't want to weight against this:

Code
s.quota("Has Xbox", criteria=has_xbox, min_respondents=500) s.quota("Has Playstation", criteria=has_playstation, min_respondents=500)

A boost-only group like this is not used for weighting. Its criteria still participate in quota qualification under the selected fielding strategy.

Raising a line's minimum inside your main sample is not the only way to get a bigger subgroup base, and often not the best one, because it changes the composition of the sample you are boosting within. Where the study is nat rep and you want one demographic reportable in its own right, fielding the extra interviews as a separate respondent source keeps the two apart. See Augmenting a nat rep sample with a subgroup boost for the setup and how to report both bases.

Capping a quota line with max_respondents

max_respondents limits assignments under strict and quota-driven fielding. Under strict, an explicit maximum replaces the completion target as the line's admission limit; without a maximum, the completion target is the limit. Under quota driven, a line without an explicit maximum remains open until the survey completes. Respondent-driven fielding does not enforce line maximums.

For example, to limit assignments to a fast-filling line under strict or quota-driven fielding:

Code
s.quota("Easy to reach", criteria=is_easy, quota=0.25, max_respondents=200)

If you omit max_respondents, the line has no explicit cap.

6. Adjusting quotas during fielding

You might start with strict quotas running in your study, and then find that they aren't filling as you had hoped. It's common for the easiest quotas to close early, so you might end up with Hispanic, High Income, 18-24 years olds as your only remaining quotas when you're close to the end of fielding.

It is doubtful that you're going to find enough high-income Hispanic 18-24-year-olds to complete your study, so this would be a good time to switch to a quota-driven strategy where any respondents who are Hispanic, high-income, or 18-24 years old are accepted.

To change the quota strategy on a survey, you can make changes in the survey. However, be aware that making any late changes may not work as expected, as there can be a short lag between respondents completing the survey and the dashboard closing the study, so you might find you've changed strategy after the survey is already closed.

You can also edit quotas during the survey by hitting the edit quotas button on the quotas page:

Setting Up Quotas

This then provides you with editable quotas that can be updated during fielding.

Setting Up Quotas

The recalculate button will show you the expected number remaining based on the changes you have made, as quotas are balanced across all groups.

Not every quota group can be edited through Edit Quotas. Non-editable groups, including least-fill counters, remain visible in the report using their recorded values.

7. Monitoring quotas in real time

The quota report shows every quota group as its own table and updates as respondents complete. Screening quota lines show their target percentage, completion target (a positive minimum, or the percentage-derived count), progress, current completes, and remaining count, so you can see which lines have reached their targets. Least-fill groups show per-item counts rather than screening targets.

The live quota report, showing several quota groups each balanced to its own target

Counts increment only when a respondent completes, so the report always reflects finished interviews rather than respondents still in progress. The Dataset toggle switches between the live data and other datasets, and Edit Quotas opens the in-field editing described in section 6. For a full walkthrough of reading the report across several groups, see Combining multiple quota groups.

8. Soft launching your quotas

Before opening a study to full sample, it is good practice to soft launch: field a small batch first, confirm that the quotas and incidence behave as expected, and only then release the rest. The simplest way to do this in MX8 Labs is to use a separate respondent source for the soft launch: send a small number of respondents through it, review the quota report and the estimated incidence, and then start your main respondent source once you are satisfied. Keeping the soft launch on its own source makes it easy to see the early results in isolation and to stop or adjust before committing the full spend.

9. Reusing a quota setup

If you run similar studies repeatedly, you do not have to rebuild your quotas each time. Save a study as a template survey with its quotas in place, then launch a new study by copying the template. The new survey starts with the same quota groups already configured. See Creating template surveys with customizable blocks.

Going deeper

For the concepts behind quota enforcement (fielding strategies, interlocked vs. marginal design, click balancing, feasibility, the impossible-cell problem, and how weighting corrects residual imbalance), see Quota management methodology.