System.LimitException: Too many SOSL queries: 21
Apex caps a single transaction at 20 SOSL `FIND` queries. Hit 21 and the transaction throws. Same family of bug as the SOQL 101 cap — almost always a SOSL inside a loop. Cure: lift it out and search for everything in one query.
Also seen asToo many SOSL queries: 21·Too many SOSL queries·SOSL query limit
SOSL has a stricter cap than SOQL — 20 per transaction instead of 100. The lower limit reflects that SOSL queries are more expensive (they hit the search index, not the indexed columns).
The shape of the bug
for (String term : userInputs) {
List<List<SObject>> hits = [FIND :term IN ALL FIELDS RETURNING Account(Id)];
process((List<Account>) hits[0]);
}
20 inputs → 20 queries → fine. 21 inputs → boom.
Fix: combine into one search
SOSL supports searching for multiple terms at once with OR:
String combined = String.join(userInputs, ' OR ');
// e.g., 'Acme OR Globex OR Initech'
List<List<SObject>> hits = [FIND :combined IN ALL FIELDS RETURNING Account(Id, Name)];
That's one query, regardless of how many terms. The platform's search index handles the OR efficiently — it's what the index is built for.
If you need to know which input matched which result, the index doesn't tell you natively. Match it back in Apex by checking which terms appear in each result's name/text fields.
When the loop is unavoidable
Sometimes you genuinely need 21+ separate searches because each one filters by a different sObject + field combination. In that case, batch the work:
- Move to async — each queueable invocation starts with a fresh 20-SOSL budget.
- Pre-flight check —
Limits.getSoslQueries()lets you skip the 21st call and report a partial result.
if (Limits.getSoslQueries() >= Limits.getLimitSoslQueries()) {
// fail gracefully, log, surface to user
return;
}
Don't confuse SOSL with SOQL
If your code says [FIND ...], that's SOSL. If it says [SELECT ...], that's SOQL. They have different governors:
| Query type | Cap per transaction |
|---|---|
SOQL (SELECT) | 100 |
SOSL (FIND) | 20 |
Both are checked independently. A transaction running 19 SOQL + 19 SOSL queries is fine; running 21 of either fails.
A subtle source: SOSL inside a Flow Apex Action
If your Apex Action is invoked once per record by Flow's per-record dispatcher, and your method does one SOSL per call, 21 records = 21 invocations = 21 SOSL queries in the same transaction. Bulk-process inside the invocable: take the List<Input> and do one SOSL covering all of them.
