App Store Optimization sounds like it should be simple. Pick keywords that describe your app, put them in the keyword field, wait for downloads. In practice, ASO across a portfolio of 27 apps in 38 locales is a metadata logistics problem disguised as a marketing exercise.
The keyword field gives you exactly 100 characters per locale. That is not 100 words — 100 characters, including commas. A single German compound word like "Strompreisvergleich" consumes 19 characters. With 27 apps and up to 38 locales each, we manage over a thousand individual keyword strings. Each one needs to be the right language, under the character limit, free of competitor brands, and actually relevant to what real people search.
This post covers what we learned doing ASO at scale: the character budget, locale contamination, the competitor brand trap, and why quiz apps and utility apps need completely different keyword strategies.
The 100-Character Budget
Apple gives you three metadata fields that affect search ranking: the app name (30 characters), the subtitle (30 characters), and the keyword field (100 characters). Together that is 160 characters of searchable text per locale.
The keyword field uses comma-separated terms. No spaces after commas — Apple ignores them, but they consume your character budget. No plural forms either — Apple's search algorithm matches singular and plural automatically. Every unnecessary space or duplicate word is a character wasted.
# Bad: 47 characters for 4 terms (spaces waste 3 chars) energy, prices, electricity, widget # Good: 44 characters for 5 terms energy,prices,electricity,widget,meter
Three characters saved means one more keyword fits. Across 38 locales, small inefficiencies compound. We wrote a validation script that checks every locale's keyword string before pushing to App Store Connect:
for locale, keywords in locale_keywords.items():
if len(keywords) > 100:
raise ValueError(
f"{locale}: {len(keywords)} chars (limit 100)"
)
The API accepts the full request and returns a 200 status code even when individual locales fail validation. You only find out through a separate error response per locale. Without pre-validation, you push keywords for 38 locales and discover that 9 of them silently failed because they were over the limit.
Locale Contamination
This is the most insidious ASO mistake we found, and we found it in our own keyword strings.
Locale contamination is when keywords in the wrong language end up in a locale's keyword field. We discovered German words sitting in our en-US keyword strings for Wattora — terms like "strompreis" and "tibber" that make perfect sense for the de-DE locale but are invisible to English-speaking searchers. They consumed 20+ characters of the 100-character en-US budget, effectively cutting our English keyword capacity by a fifth.
This happens because keyword research tools often mix languages. If your app is relevant in both Germany and the US, the tool might suggest German terms in the English results. It also happens during bulk keyword pushes — a copy-paste error puts de-DE keywords into the en-US slot, and nobody notices because the API does not validate language.
The fix is a pre-push audit: for each locale, verify that every keyword is actually in the expected language. We flag any keyword that appears in a different locale's natural language. "Strompreis" in en-US is a contamination signal. "Electricity" in de-DE is also contamination — it wastes German character space on a word that only English speakers would type.
The Competitor Brand Trap
It is tempting to include competitor names in your keywords. If someone searches "Monefy" (a popular expense tracker), and your expense app appears in results, that feels like free traffic. Apple disagrees.
Guideline 4.1(c) explicitly prohibits using competitor brand names in your metadata. "Monefy", "Every Dollar", "Mint" — none of these belong in your keyword field. Apple's review team runs automated scans for known brand terms, and including them risks rejection or metadata removal.
The same applies to app names and subtitles. We had a rejection on one of our apps because the subtitle referenced a well-known third-party brand. The rejection cited Guideline 4.1(c) — Copycats. The fix was straightforward: replace the brand name with a generic category term. "AI assistant" instead of the brand name. "Expense tracker" instead of the competitor's name.
The rule of thumb: use category terms, feature terms, and problem terms. Never competitor names, celebrity names, or trademarked terms you do not own. "Budget tracker", "receipt scanner", "spending report" are all safe. "Mint alternative" is not.
Quiz Apps vs Utility Apps: Different Keyword Strategies
Our portfolio includes both categories, and they need fundamentally different ASO approaches.
Quiz and exam prep apps have a natural advantage: the search terms are highly specific and high-intent. Someone searching "CSCS card test" or "Einbürgerungstest 2026" knows exactly what they want. The keyword strategy is to capture every variation of the exam name, abbreviation, and colloquial term in each target locale:
# CSCS Quiz (en-GB locale) cscs,card,test,health,safety,construction, site,mock,exam,revision,labourer,operative # Einbuergerungstest (de-DE locale) einbürgerungstest,leben,deutschland,bamf, staatsbürgerschaft,integration,test,prüfung
For quiz apps, the title and subtitle do most of the work. "CSCS Card Quiz" in the title already captures the primary search term. The keyword field fills in the long tail: "revision", "mock exam", "operative card".
Utility apps compete in broader categories. eXpense competes against hundreds of expense trackers. Wattora competes against energy apps across five countries. The keyword strategy here is different: focus on specific use cases and differentiating features rather than the category name, which is already saturated.
# Wattora (en-US locale) - specific, not generic spot,price,electricity,hourly,widget, alert,cheap,expensive,chart,kwh,rate # eXpense (en-US locale) - feature-focused receipt,scan,ai,budget,category,report, spending,monthly,export,csv,track
For utility apps, the subtitle is critical for differentiation. "AI Expense Tracker with Receipt Scanning" beats "Expense Tracker App" because it captures additional long-tail terms and tells Apple's algorithm what makes the app distinct.
The Version Shell Problem
A detail that caught us off guard: when you create a new version shell in App Store Connect, it does not always inherit all locale keyword data from the prior version. We observed locales silently dropping — a version with 39 locales would create a new shell with only 31. The missing 8 locales had empty keyword fields.
This means any ASO push on a new version needs a pre-check: list all localizations on the new shell and cross-reference against the prior version. Refill any missing locales before pushing keywords. Without this step, your carefully researched keywords for 8 locales vanish silently on every version update.
# Verification step before any keyword push
current = list_localizations(new_version_id)
previous = list_localizations(prior_version_id)
missing = set(previous.keys()) - set(current.keys())
if missing:
for locale in missing:
create_localization(new_version_id, locale)
# Now safe to push keywords
Batch Keyword Pushes at Scale
Pushing keywords to 27 apps across 38 locales means over a thousand API calls. Apple's App Store Connect API has rate limits — not officially documented, but empirically we found that 6 concurrent calls is safe. Beyond that, requests start failing with rate-limit errors.
Our batch pipeline:
- Generate keyword strings per locale per app (from research)
- Validate: every string under 100 characters, correct language, no competitor brands
- Check version shells: ensure all locales exist on the current version
- Push in batches of 6 concurrent requests
- Log results: which locales succeeded, which failed, character counts
The entire push for 27 apps takes about 15 minutes with this pipeline. Without the pre-validation and batch limiting, it takes an hour of debugging failed locales and re-pushing.
What Actually Moves Rankings
After running ASO passes across the full portfolio, the patterns that made measurable differences were:
- Subtitle matters more than the keyword field. The subtitle is visible in search results and influences both the algorithm and the user's tap decision. Invest time here first.
- Locale-specific keywords outperform translated keywords. "Fischerprüfung" in de-DE is better than translating "fishing exam" into German, because that is what German users actually type.
- Character efficiency compounds. Saving 3 characters per locale across 38 locales means 114 characters of additional keyword space per app — enough for several more search terms.
- New version shells need keyword verification. Never assume locales carry over. Check every time.
- Contamination is invisible. German words in en-US waste budget but produce no error. The only way to catch it is a language audit.
ASO is not a one-time activity. Search trends change, competitors update their metadata, and Apple occasionally adjusts the algorithm. We run a keyword audit roughly once a quarter, or whenever we ship a major update. The pipeline makes re-pushing fast enough that it is worth doing regularly.