Back to blog
Engineering11 min read

Frequency and Presence Penalty Explained

OpenAI's frequency_penalty and presence_penalty, verified against the API reference: ranges, defaults, Gemini's binary version, and why Anthropic and reasoning models don't expose them the same way.

NH
Nafiul Hasan
Founder, Prompt Architects

TL;DR: frequency_penalty and presence_penalty are OpenAI parameters, -2.0 to 2.0, default 0, that discourage token repetition by different math: one scales with how often a token has appeared, the other is a one-time flag. Gemini documents its own binary version with no published range. Anthropic exposes neither at all.

What do frequency penalty and presence penalty actually do?

Both parameters push a model away from repeating itself, and both come from OpenAI's own API. What they penalize is different, though, and the difference is the whole point of having two knobs instead of one.

OpenAI's API specification describes frequency_penalty this way: "Number between -2.0 and 2.0. Positive values penalize new tokens based on their existing frequency in the text so far, decreasing the model's likelihood to repeat the same line verbatim" (developers.openai.com, read September 3, 2026). The key word is "frequency": the penalty scales with how many times a token has already appeared. A word used four times gets pushed away from harder than a word used once.

presence_penalty is documented separately, and reads almost the same until you notice what's missing: "Number between -2.0 and 2.0. Positive values penalize new tokens based on whether they appear in the text so far, increasing the model's likelihood to talk about new topics" (developers.openai.com, read September 3, 2026). The operative word there is whether, not how often. A token that has appeared once and a token that has appeared twenty times receive the identical presence penalty. It's a single flag, not a running count.

That distinction is the entire reason both exist. frequency_penalty targets verbatim repetition: the same phrase, the same line, over and over. presence_penalty targets topic fixation: the model circling one subject regardless of exact wording. A response that repeats one sentence needs frequency_penalty; a response that keeps returning to the same theme in different words needs presence_penalty. Turning up the wrong one for your actual symptom does very little.

What are the exact ranges and defaults, per vendor?

OpenAI's is the only one with a published range and a published default:

Verified against each vendor's own current API reference, September 3, 2026.
FeatureOpenAIGoogle GeminiAnthropic Claude
Frequency penalty fieldfrequency_penaltyfrequencyPenaltyNot exposed
Presence penalty fieldpresence_penaltypresencePenaltyNot exposed
Numeric range published-2.0 to 2.0Not publishedN/A
Default value0Not publishedN/A
Presence penalty behaviorAppearance-based, not scaled by countExplicitly documented as binary on/offN/A
On the vendor's newest API surfaceAbsent from the Responses APIAbsent from the Interactions APIN/A

Both OpenAI fields carry identical bounds: a number between -2.0 and 2.0, defaulting to 0, on both frequency_penalty and presence_penalty. That default is worth stating explicitly, because it means the parameter does nothing at all unless you set it. OpenAI does not apply a background repetition penalty you're implicitly opting out of. A negative value is legal and does the opposite of what most people assume: it makes the model more likely to repeat itself, not less, and at strongly negative settings the documentation's own framing (encouraging reuse of tokens already written) describes a model that can get stuck circling one output.

# OpenAI Chat Completions: both parameters, minimum working request
curl https://api.openai.com/v1/chat/completions \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-5.6",
    "messages": [
      {"role": "user", "content": "Write three taglines for a coffee shop."}
    ],
    "frequency_penalty": 0.8,
    "presence_penalty": 0.2
  }'

Both fields sit at the top level of the request body, alongside messages and model. Neither lives inside a nested sampling object, and neither requires the other to be set.

Does Anthropic support either parameter?

No, and not in a deprecated-but-accepted way: genuinely absent. Anthropic's Messages API reference, read directly rather than assumed, contains zero occurrences of frequency_penalty or presence_penalty anywhere in the document. Compare that to top_k and top_p, which the same reference does mention, explicitly marked deprecated on models released after Claude Opus 4.6. Frequency and presence penalty were never there to deprecate.

If you're porting an integration from OpenAI to Claude and your code sets frequency_penalty as a pass-through parameter, there is no Anthropic field to map it to. The request will either be ignored by whatever adapter you're using or rejected outright, depending on how strict that adapter is. Anthropic's own prompting guidance for repetition problems is prompt-level: name the unwanted pattern and ask directly for something else, the same lever available to anyone typing into a chat window with no API access at all.

Why is Gemini's presence penalty different from OpenAI's?

Gemini exposes both fields on its generateContent endpoint's generationConfig, but documents presencePenalty as categorically different from OpenAI's version, in its own words: "This penalty is binary on/off and not dependant on the number of times the token is used (after the first). Use frequencyPenalty for a penalty that increases with each use" (ai.google.dev, read September 3, 2026).

Read that carefully against OpenAI's presence_penalty description above and the two are actually describing the same underlying behavior (appearance-based, not count-scaled), but Google states it as an explicit design contrast against its own frequencyPenalty, where OpenAI's docs leave the reader to infer the same distinction from two adjacent, similarly-worded paragraphs. Neither Gemini field publishes a numeric range or a default value the way OpenAI's -2.0-to-2.0-default-0 is spelled out, so any specific number attached to a Gemini frequency or presence penalty in a tutorial is not sourced from Google's own reference.

Google's own field descriptions carry a directional caution neither OpenAI page states as plainly. The presencePenalty description spells out both directions as separate sentences: "A positive penalty will discourage the use of tokens that have already been used in the response, increasing the vocabulary." The negative direction gets its own sentence too: "A negative penalty will encourage the use of tokens that have already been used in the response, decreasing the vocabulary." The frequencyPenalty description, separately, names the failure mode at the extreme: "Larger negative values will cause the model to start repeating a common token until it hits the maxOutputTokens limit" (ai.google.dev, read September 3, 2026). That last case is worth pausing on: a strongly negative penalty doesn't just make output repetitive, it can push generation all the way to your output-length ceiling on a single stuck token, which looks like a different, unrelated bug if you don't already know the setting is at fault.

Do these parameters apply to reasoning models?

Undocumented either way, which is itself worth knowing before you assume support or its absence. OpenAI's Chat Completions reference carries a general disclaimer: "Parameter support can differ depending on the model used to generate the response, particularly for newer reasoning models. Parameters that are only supported for reasoning models are noted below. For the current state of unsupported parameters in reasoning models, refer to the reasoning guide" (developers.openai.com, read September 3, 2026).

Checked directly, that reasoning guide contains zero mentions of either penalty parameter, as of September 3, 2026. Compare this silence to how the same Chat Completions reference treats stop, which it flags explicitly: "Not supported with latest reasoning models o3 and o4-mini." No comparable sentence exists anywhere for frequency_penalty or presence_penalty. That is not confirmation that reasoning models honor the setting. It is the absence of the restriction OpenAI does publish for other parameters it has actually turned off, which is a meaningfully different, weaker kind of evidence than an explicit "supported" statement would be.

Which API surface do you even set this on?

This is the migration trap. frequency_penalty and presence_penalty are documented as top-level parameters on OpenAI's Chat Completions endpoint. Neither field appears anywhere in the current Responses API reference: not renamed, not nested under a different object, absent.

Gemini's version of the same trap is structural rather than a rename. frequencyPenalty and presencePenalty are documented on the generateContent endpoint's generationConfig, but the newer Interactions API reference (the surface Google's structured-outputs documentation now points to as current) contains no mention of either field, or of temperature, top-p, or top-k for that matter. If you build against the Interactions API today, sampling-level repetition control is not part of what that surface currently documents.

What actually changes when you turn the value up or down?

Honestly: this section is not five live API calls at five settings, because publishing real sampled output would require running a paid API call against a production key for content-generation purposes, which this piece deliberately does not do. What follows is the documented mechanism, illustrated arithmetically, not a transcript of an actual run.

Per OpenAI's own description, the model computes each next-token probability, then subtracts a penalty before sampling: for frequency_penalty, the subtraction scales with how many times that exact token has already appeared in the response so far; for presence_penalty, the subtraction is a flat amount applied once a token has appeared at all, with no further scaling on repeat appearances. A token used three times under a frequency penalty of 1.0 is pushed down roughly three times as hard as a token used once; the same three-times-used token under a presence penalty of 1.0 gets the identical, flat push as a token used exactly once.

That arithmetic difference explains the practical guidance implicit in both vendors' own wording rather than any folklore about "good" values: raise frequency_penalty when the symptom is the same phrase or line recurring verbatim, and raise presence_penalty when the symptom is the model refusing to leave one topic even though its wording keeps changing. Setting either one strongly negative does not merely add variety: both vendors' documentation describes it as actively encouraging reuse, and Gemini states the failure mode explicitly as a runaway single token repeated until the output-length ceiling is hit.

Is "repetition penalty" a different thing?

Often, yes, and the ambiguity is worth naming directly since it's one of the terms people searching this topic actually type. Hugging Face's transformers documentation describes a distinct parameter under that name: "The parameter for repetition penalty. 1.0 means no penalty" (huggingface.co, read September 3, 2026).

That's a meaningfully different design from OpenAI's. Hugging Face's repetition_penalty is multiplicative and unsigned: 1.0 is neutral, values above 1.0 discourage repetition, and there's no equivalent to OpenAI's negative range that actively encourages it. OpenAI's frequency_penalty and presence_penalty are additive and signed instead, with 0 as neutral and the same numeric range extending in both directions. If you're moving a prompt or a generation config between an OpenAI-style API and a self-hosted or Hugging Face-ecosystem model, treat these as two different mechanisms solving a similar problem, not two names for the same number. A repetition_penalty of 1.2 and a frequency_penalty of 1.2 are not comparable settings, and porting the number directly from one to the other will not produce comparable output.

For the sampling parameters these two sit alongside (temperature, top-p, and top-k), see the full cross-provider parameter reference, or the dedicated pages on temperature, top-p and top-k and what happens when you set both top-p and top-k. If repetition is the symptom you're actually fighting, why ChatGPT repeats itself covers the causes that have nothing to do with sampling at all, including the fact that neither penalty does anything inside the consumer ChatGPT app, since it exposes no API parameters to the person typing into it.

Free Chrome Extension

Stop rewriting prompts. Start shipping.

Works with ChatGPT, Claude, Gemini, Grok, Midjourney, Ideogram, Veo3 & Kling. 4.8★ on the Chrome Web Store.

Create An Account

Frequently asked questions

Free Chrome Extension

Stop rewriting prompts. Start shipping.

Works with ChatGPT, Claude, Gemini, Grok, Midjourney, Ideogram, Veo3 & Kling. 4.8★ on the Chrome Web Store.

Create An Account