frequency_penalty vs presence_penalty: 4 Recipes That Ship (2026)
frequency_penalty counts, presence_penalty flags. Four copy-paste recipes for when to grab which OpenAI sampling knob, plus the one config that quietly breaks your JSON.

On this page
Quick Answer: frequency_penalty and presence_penalty both range from -2.0 to 2.0, default 0.0 (OpenAI Chat Completions, 2026). frequency_penalty scales with how many times a token already appeared. presence_penalty is a flat one-time hit the moment a token shows up at all. Reach for frequency_penalty to stop repetition. Reach for presence_penalty to push the model onto new topics. For JSON or code, set both to 0. Four recipes below, each tested and shippable.
These two knobs live on the OpenAI Chat Completions API.
Anthropic's Claude has no direct equivalent, so the recipes here are OpenAI-specific. Docs describe them clinically. Nobody tells you which one to grab. This does.
The one-line difference
frequency_penalty counts. presence_penalty flags.
frequency_penalty looks at how often a token has already appeared and pushes down its odds proportionally. Appear twice, get penalized twice as hard. presence_penalty fires once. Token appeared at all? Flat penalty, no matter if it showed up one time or forty. Positive values suppress. Negative values encourage. Default is 0.0 for both, meaning off.
That is the whole model. The rest is knowing when to turn which one.
Recipe 1: Stop a long answer repeating the same phrase
Claim: Model keeps saying "it is important to note" every paragraph? That is a frequency problem. Fix it with frequency_penalty, not temperature.
Receipt:
{
"model": "gpt-4o-mini",
"messages": [{"role": "user", "content": "Write a 400-word overview of Postgres indexing."}],
"frequency_penalty": 0.5,
"presence_penalty": 0
}
Why: 0.4 to 0.6 is the useful band. It taxes tokens each time they recur, so filler phrases that the model overuses get quietly starved out. Under 0.3 does nothing visible. Over 0.8 starts mangling necessary repeats (the word "index" in an indexing article).
Failure mode: People raise temperature to kill repetition. Wrong tool. Temperature adds randomness everywhere, including your facts. frequency_penalty targets the actual problem. Keep temperature where it was.
Ship: Start at 0.5. Nudge down if technical terms start disappearing.
Recipe 2: Force topic diversity in brainstorming
Claim: Asking for 20 ideas and getting 20 flavors of the same three? That is presence, not frequency.
Receipt:
{
"model": "gpt-4o-mini",
"messages": [{"role": "user", "content": "List 20 distinct blog post angles for a Postgres monitoring tool."}],
"presence_penalty": 0.8,
"frequency_penalty": 0.2
}
Why: presence_penalty penalizes any token that has appeared once, so once a concept is on the page the model is nudged toward genuinely new ground. 0.6 to 1.0 is the broadening band for ideation. Small frequency_penalty on top trims within-idea repetition.
Failure mode: Push presence_penalty past ~1.2 and coherence drops. The model avoids common words so hard it reaches for odd ones. Ideas get weird instead of diverse.
Ship: 0.8 for brainstorming. Drop to 0 the moment you need focused, on-topic prose.
Recipe 3: Break a token loop that keeps regenerating
Claim: Output degenerates into "the the the" or a repeating clause. Frequency penalty is the seatbelt.
Receipt:
{
"model": "gpt-4o-mini",
"messages": [{"role": "user", "content": "Summarize this changelog."}],
"frequency_penalty": 0.7,
"presence_penalty": 0.3
}
Why: Loops are the extreme case of frequency: one token dominates. A firm frequency_penalty (0.6 to 0.8) makes each repeat progressively more expensive, so the loop breaks itself. A little presence_penalty helps the model leave the stuck region entirely.
Failure mode: If the loop is caused by a bad prompt or a truncated context, penalties only paper over it. Fix the input first. Penalties are a finish, not a foundation.
Ship: 0.7 / 0.3 as a rescue combo. If it recurs, look at your prompt, not the knobs.
Recipe 4: JSON or code output? Set both to 0
Claim: The most common penalty bug is using them at all on structured output.
Receipt:
{
"model": "gpt-4o-mini",
"messages": [{"role": "user", "content": "Return a JSON array of 15 user objects."}],
"frequency_penalty": 0,
"presence_penalty": 0
}
Why: JSON and code repeat tokens by design. Braces, quotes, the same field keys across every object, return, const, indentation. Any positive penalty taxes exactly those legitimate repeats. The model starts renaming keys, dropping brackets, or inventing synonyms to dodge the penalty. You get invalid output and blame the model.
Failure mode: Shipping a default penalty config globally, then wondering why structured calls fail intermittently. Penalties are prose tools. Structured output wants them off.
Ship: Both 0 for anything a parser will read. Pair with a JSON mode or a schema for real reliability. If you also need clean recovery when a model returns broken JSON, wire in a repair pass and clear stop sequences so nothing truncates mid-object.
When NOT to touch these
Leave both at 0.0 unless you have a named symptom. They are corrective, not default seasoning. Reasoning-focused and some newer models ignore or reject these fields entirely, so check the model card before you rely on them. And if your real problem is "output too random" or "output too safe," that is temperature, a different dial. Do not stack all three at once and hope.
FAQ
Is frequency_penalty or presence_penalty better for reducing repetition?
frequency_penalty. It scales with how often a token repeats, so it targets repetition directly. presence_penalty is better for pushing the model onto new topics, not for cleaning up repeated phrasing.
What is the default value of frequency_penalty and presence_penalty?
Both default to 0.0, which means no penalty is applied. They accept any value from -2.0 to 2.0 (OpenAI Chat Completions, 2026).
Can I use both at the same time?
Yes. A common combo is a moderate frequency_penalty (0.4 to 0.6) with a small presence_penalty (0.1 to 0.3) for varied, non-repetitive long-form prose. Keep both under 1.0 unless you are deliberately experimenting.
Do negative penalty values do anything useful?
Rarely. Negative values encourage repetition and reuse of seen tokens. Useful for deliberate refrains or highly templated output, but easy to overdo. Most workloads never go below 0.
Why does my JSON break when I set a penalty?
Because structured formats repeat tokens on purpose (keys, braces, syntax). A positive penalty taxes those legitimate repeats and the model distorts the structure to avoid them. Set both to 0 for JSON and code.
Sources
- OpenAI, Chat Completions API reference (frequency_penalty, presence_penalty parameters), 2026: https://platform.openai.com/docs/api-reference/chat/create
- Anthropic, Claude Messages API reference (for contrast; no frequency/presence penalty fields), 2026: https://docs.anthropic.com/en/api/messages
- OpenAI Cookbook, practical parameter guidance, 2026: https://cookbook.openai.com/
Cost to test: about $0.02 (six gpt-4o-mini calls, ~2K tokens each, 2026 prices).
Written by
Sam Q.FAQ
Is frequency_penalty or presence_penalty better for reducing repetition?
frequency_penalty. It scales with how often a token repeats, so it targets repetition directly. presence_penalty is better for pushing the model onto new topics, not for cleaning up repeated phrasing.
What is the default value of frequency_penalty and presence_penalty?
Both default to 0.0, which means no penalty is applied. They accept any value from -2.0 to 2.0 (OpenAI Chat Completions, 2026).
Can I use both frequency_penalty and presence_penalty at the same time?
Yes. A common combo is a moderate frequency_penalty (0.4 to 0.6) with a small presence_penalty (0.1 to 0.3) for varied, non-repetitive long-form prose. Keep both under 1.0 unless you are deliberately experimenting.
Do negative penalty values do anything useful?
Rarely. Negative values encourage repetition and reuse of seen tokens. Useful for deliberate refrains or highly templated output, but easy to overdo. Most workloads never go below 0.
Why does my JSON break when I set a penalty?
Because structured formats repeat tokens on purpose (keys, braces, syntax). A positive penalty taxes those legitimate repeats and the model distorts the structure to avoid them. Set both to 0 for JSON and code.
Related recipes
LLM Temperature Settings: 6 Recipes That Ship (2026)
Six copy-paste LLM temperature and top_p recipes for 2026: the exact setting per task type, why it works, and the failure mode it prevents.
Stop Sequences: 4 Recipes That Ship (2026)
Stop sequences in 2026: four copy-paste recipes that cut a model off at a delimiter, bound a JSON object, force one section, and stop an agent from faking its own turn, plus where they break.
The 2026 Prompt Engineering Cheat Sheet (For People Who Ship)
A terse, production-first prompt engineering cheat sheet for 2026: fifteen patterns, each with a one-line rule, its failure mode, and a link to the full recipe.


