Nano Banana 2.1 vs Nano Banana 2: one poster, then two edits

Compare Nano Banana 2.1 and 2 on one poster and two edits each. Inspect six real images, timings, reported tokens and practical migration checks.

Black ink compass on a pale card with geometric accents and a Nano Banana 2.1 title.

Tested October 13, 2026. We sent the same three prompts through Ofox’s native Gemini API route for Nano Banana 2.1 and Nano Banana 2. Each model generated an event poster, changed its headline, and then changed the bowl’s color. That is one three-step chain per model, not three independent trials or a benchmark of either model’s overall quality.

Ofox publishes this article and operates the gateway tested here. The draft was AI-assisted; the API requests and output files were verified with tools, and a separate AI review was performed before publication. The six generated images below—not the public model-page interface—are the evidence for the visual comparison. You can inspect the files and request material in the downloadable reproduction kit.

The six outputs

StepNano Banana 2.1Nano Banana 2
Generate posterNano Banana 2.1 poster reading ORCHARD MARKET and SATURDAY 10 AM, with three apples in a blue bowlNano Banana 2 poster reading ORCHARD MARKET and SATURDAY 10 AM, with three apples in a blue bowl
Edit headlineNano Banana 2.1 poster after headline edit to ORCHARD FAIRNano Banana 2 poster after headline edit to ORCHARD FAIR
Edit bowl colorNano Banana 2.1 poster after changing the bowl to dark greenNano Banana 2 poster after changing the bowl to dark green

Both models completed the requested semantic sequence in this run. Their first posters spell ORCHARD MARKET and SATURDAY 10 AM correctly and show three red apples in a blue bowl. Both headline edits say ORCHARD FAIR while retaining the smaller line, apples, and blue bowl. Both third-turn outputs change the bowl to dark green and retain the requested words and layout.

There is also a shared miss: despite “no border” in the first prompt, both models present the design as a paper sheet with an outside margin or shadow. If “no border” means artwork must reach the image’s edges, neither first output satisfies that constraint. The result is useful for a poster concept, but it is not evidence that either model obeys every layout instruction exactly.

What was sent, and what the comparison can establish

The exact prompts, in order, were:

  1. Create a square minimalist event poster on warm cream paper. Large exact headline: ORCHARD MARKET. Smaller exact line: SATURDAY 10 AM. Draw three red apples in a blue ceramic bowl below the text. No other text, no logos, no border.
  2. Change only the headline from ORCHARD MARKET to ORCHARD FAIR. Keep SATURDAY 10 AM exactly unchanged. Preserve the three red apples, blue bowl, cream background, composition and all other pixels as closely as possible.
  3. Now change only the bowl from blue to dark green. Preserve ORCHARD FAIR, SATURDAY 10 AM, the three red apples and the layout.

For each model, turn two included its own generated poster; turn three included that model’s preceding conversation and headline edit. We sent the previous full candidates[0].content back as the assistant turn, rather than rebuilding its parts from the displayed PNG. This matters because returned content can contain parts needed to continue the conversation.

The tested Ofox route was POST https://api.ofox.io/gemini/v1beta/models/{model}:generateContent, authenticated with x-goog-api-key. The IDs were google/gemini-nano-banana-2.1 and google/gemini-3.1-flash-image for the older model. Both chains requested responseModalities: ["TEXT", "IMAGE"], a 1:1 aspect ratio, and 1K image size. We did not set a seed or an explicit thinking level. The models may therefore have used different defaults; matching prompts and requested image settings do not make their internal configurations identical.

All six calls returned HTTP 200, a STOP finish reason, and a 1024 × 1024 PNG. We did not run repeat trials, other languages, other aspect ratios, or a production workload. The visual assessment above concerns these six files only. In particular, “preserve all other pixels as closely as possible” is an instruction, not a guarantee of pixel-level editing or editable layers. Even the apparently stable lower portions of the headline edits contain many changed RGB pixels. Exact pixel inequality counts small texture and color differences as changes; it is not a perceptual damage score. For techniques that require tighter control over a product region, see the separate discussion of mask-based preservation and single versus multiple scene references.

Timing and returned usage: observations, not a speed ranking

These are the elapsed times and usage fields returned for the six requests. “Not reported” means the field was absent; it does not mean zero thoughts or zero associated cost.

Model and turnElapsed secondsInput tokensReported text-output tokensImage output tokensThoughts tokens
2.1 — poster15.4654801,120639
2.1 — headline edit17.481,167Not reported1,120358
2.1 — bowl edit18.442,272Not reported1,120Not reported
2 — poster10.0854Not reported1,120Not reported
2 — headline edit13.991,167Not reported1,120Not reported
2 — bowl edit13.062,272Not reported1,120Not reported

The first 2.1 response reported 80 TEXT output tokens but contained no visible text part. The table reports metadata categories, not a count of visible words.

Nano Banana 2 returned sooner on each of these three paired turns. Six serial requests, without repetition or controlled load conditions, cannot establish that it is generally faster. Likewise, both meeting the main text-and-edit tasks here does not establish equal reliability across prompts. The increasing input-token counts reflect the multi-turn requests as reported by the API; they do not, by themselves, specify exactly how submitted history was billed. The migration steps below turn these narrow observations into checks for your own workload.

Reproduce the three-step chains

The kit contains the test material and output images. To make fresh calls, install requests, set an Ofox API key, and run the script below. It uses the exact prompts above, saves every returned inline image part, and retains each response’s full candidate content for the next turn. Fresh generations need not match the six published PNGs.

python -m pip install requests
export OFOX_API_KEY="your-key"
python compare_posters.py
# compare_posters.py
import base64
import json
import os
import time
from pathlib import Path

import requests

KEY = os.environ["OFOX_API_KEY"]
OUT = Path("poster-comparison")
OUT.mkdir(exist_ok=True)

PROMPTS = [
    "Create a square minimalist event poster on warm cream paper. Large exact headline: ORCHARD MARKET. Smaller exact line: SATURDAY 10 AM. Draw three red apples in a blue ceramic bowl below the text. No other text, no logos, no border.",
    "Change only the headline from ORCHARD MARKET to ORCHARD FAIR. Keep SATURDAY 10 AM exactly unchanged. Preserve the three red apples, blue bowl, cream background, composition and all other pixels as closely as possible.",
    "Now change only the bowl from blue to dark green. Preserve ORCHARD FAIR, SATURDAY 10 AM, the three red apples and the layout.",
]

MODELS = {
    "21": "google/gemini-nano-banana-2.1",
    "2": "google/gemini-3.1-flash-image",
}
STAGES = ("poster", "edit", "turn3")

for label, model in MODELS.items():
    history = []
    url = f"https://api.ofox.io/gemini/v1beta/models/{model}:generateContent"

    for stage, prompt in zip(STAGES, PROMPTS):
        user_turn = {"role": "user", "parts": [{"text": prompt}]}
        payload = {
            "contents": history + [user_turn],
            "generationConfig": {
                "responseModalities": ["TEXT", "IMAGE"],
                "imageConfig": {"aspectRatio": "1:1", "imageSize": "1K"},
            },
        }

        started = time.monotonic()
        response = requests.post(
            url,
            headers={"x-goog-api-key": KEY},
            json=payload,
            timeout=180,
        )
        elapsed = time.monotonic() - started
        response.raise_for_status()
        body = response.json()

        candidates = body.get("candidates") or []
        if not candidates:
            raise RuntimeError(f"{label}/{stage}: no candidate: {body}")
        candidate = candidates[0]
        if candidate.get("finishReason") != "STOP":
            raise RuntimeError(
                f"{label}/{stage}: finishReason={candidate.get('finishReason')}"
            )

        content = candidate["content"]  # Keep all returned parts intact.
        saved = []
        for index, part in enumerate(content.get("parts", [])):
            inline = part.get("inlineData")
            if not inline:
                continue
            mime = inline.get("mimeType", "")
            if not mime.startswith("image/"):
                continue
            extension = ".png" if mime == "image/png" else ".img"
            path = OUT / f"{stage}-{label}-{index}{extension}"
            path.write_bytes(base64.b64decode(inline["data"]))
            saved.append(str(path))

        if not saved:
            raise RuntimeError(f"{label}/{stage}: STOP but no inline image")
        print(json.dumps({
            "model": model, "stage": stage, "seconds": round(elapsed, 2),
            "images": saved, "usageMetadata": body.get("usageMetadata"),
        }))

        history += [user_turn, content]

The code treats text parts as text, not as images. It also fails visibly if a successful HTTP response has no candidate, a non-STOP finish reason, or no inline image—cases worth handling before integrating image generation into a workflow. The public Ofox 2.1 model page lists the model and protocols, but its embedded Playground requires login; a model-page screenshot is evidence of a public interface, not evidence that these images were produced there. No authenticated Agent model-selection test was performed, so this article does not claim that an Agent automatically selects 2.1. For more on response-handling failures, see the no-image error guide and Google’s API troubleshooting documentation.

What the tokens imply—and what they do not

Image tokens, input tokens, reported text output, and reported thoughts are distinct usage components. In Ofox’s October 13 runtime catalog snapshot, the listed rates were $1.50 per million input tokens, $7.50 per million text-output tokens, and $30 per million image-output tokens for 2.1. The corresponding older-model snapshot listed $0.50, $3, and $60 per million. The 2.1 snapshot also listed $0.014 per search request; this poster test did not exercise search. A null provider-price field did not confirm a provider discount. Ofox’s catalog endpoint is dynamic, rather than a static price table in the site’s Git repository, and a snapshot conversion is not a verified invoice. Check the current pricing guide and your billing records before budgeting.

For the first 2.1 poster request, applying those snapshot rates gives an image component of 1,120 × $30 / 1,000,000 = $0.0336, an input component of 54 × $1.50 / 1,000,000 = $0.000081, and a reported text-output component of 80 × $7.50 / 1,000,000 = $0.0006. If its 639 reported thoughts tokens are charged at that same text-output rate, they add an estimated $0.0047925, making the illustrative sum $0.0390735. That conditional calculation is not a bill. Do not turn absent thoughts fields for the older model into assumed zero charges.

At the snapshot image rate, 100 generated 1K 2.1 images alone would contribute $3.36; generating 125 to obtain 100 accepted images—an illustrative 80% acceptance rate—would make that image component $4.20. Inputs, text, potentially billed thinking, retries, and other applicable charges remain outside those image-only figures. The older model’s listed image component for a 1,120-token output would be $0.0672, but these figures do not prove that switching models will reduce a particular workload’s total bill or cost per accepted design.

Google’s Gemini pricing page independently lists the 2.1 text-plus-thinking and image rates and gives 1K as 1,120 image tokens. Its published 4K figures do not align cleanly across Google sources: the image-generation pricing table gives 2,520 tokens, while Vertex documentation gives 3,780. We made no 4K request here; neither figure should be presented as an exact Ofox 4K bill from this test.

Should an existing workflow switch IDs?

Switch if this model’s behavior or available capabilities solve a problem you have actually checked—not because these six images prove a universal winner. Google documents Nano Banana 2.1’s model capabilities and image-generation workflow, including higher-resolution options and reference-image workflows. Documentation of a capability is not verification that every option was exercised through this Ofox route: this comparison used 1K, no external reference images, and English prompts only. It also did not compare Pro or Lite; their documented positioning is a reason to evaluate them for different needs, not measured superiority here.

A cautious upgrade has four parts:

  1. Pin the model ID. Change google/gemini-3.1-flash-image to google/gemini-nano-banana-2.1 in a test configuration, rather than silently changing every production call.
  2. Keep configuration and conversation history explicit. Record requested resolution, aspect ratio, modalities, prompts, and the full assistant content passed between turns. Avoid publishing unsupported seed, temperature, or top-p tuning recipes as if they made these outputs reproducible.
  3. Check output limits against the real deliverable. Test exact wording, unwanted margins, reference handling where needed, missing-image responses, acceptance rate, latency distribution, and total billed usage on your own material. The focused poster-editing guide covers further constraints for this kind of job; the API guide covers integration.
  4. Keep a rollback path. Preserve the old ID and routing configuration until the new model passes your checks. Nothing in this test establishes that the older ID has shut down.

Finally, an attractive generated poster is not a rights clearance or a secure-data policy. Check rights to supplied inputs and the applicable Gemini API terms before commercial or sensitive-data use. SynthID documentation should not be read as a promise of a visible watermark, exclusive ownership, or noninfringement. Here the defensible conclusion is narrower: in one matched three-turn English poster chain, both models made the requested text and bowl edits, and both missed the no-border instruction.