Google released Gemini 4 Hydrogen (gemini-4-hydrogen) on November 12, 2026. It's the fast, cheaper model in the Gemini 4 family, sitting below Carbon and Argon. It's on the free and paid tiers of the Gemini API and AI Studio, and the paid price is flat across the whole context window: $1.50 per 1M input tokens and $7.50 per 1M output tokens (thinking tokens count as output).
Google's launch post says that compared with Gemini 3.8 Flash it finishes tasks 2.5x faster at its default setting and more than triples Terminal-Bench 4.1 scores (57% vs. 18.2%). Those are Google's numbers. I haven't benchmarked them myself.
What I did test is the boring part: wiring Hydrogen into a streaming React chat with the Vercel AI SDK, and checking what actually goes over the wire. A few details in the migration guide are easy to miss.
What changed for developers
From the official "What's new in Gemini 4 Hydrogen" guide:
- Four thinking levels:
low,medium,high(the default) and a newxhigh.minimalis rejected with an error. - One unified window: input, thinking and output share 1,048,576 tokens. A single request still caps at 65,536 output tokens, streaming or not. To go longer you use background execution or client-side continuation.
- Sampling params are gone: remove
temperature,top_pandtop_k. In-range values are ignored, and out-of-range values return a400. - No explicit caching:
cachedContents/caches.createaren't supported. Implicit caching runs automatically on prompts of at least 4,096 tokens and discounts cached input by 95%. - Thought signatures matter: if you manage history yourself with
generateContent, send prior model turns and thought signatures back unchanged.
The guide also suggests running your evals at all four levels and picking the lowest level that meets your quality bar. That's good advice for a chat UI, where latency is most of the user experience.
SDK support
@ai-sdk/google 4.0.119 added the gemini-4-hydrogen model ID and the xhigh thinking level (see the package changelog). I used ai@7.0.173 with @ai-sdk/google@4.0.121.
The route handler
// app/api/chat/route.ts import { streamText, convertToModelMessages, type UIMessage } from 'ai'; import { google } from '@ai-sdk/google'; export const maxDuration = 60; type Level = 'low' | 'medium' | 'high' | 'xhigh'; export async function POST(req: Request) { const { messages, level = 'medium' }: { messages: UIMessage[]; level?: Level } = await req.json(); const result = streamText({ model: google('gemini-4-hydrogen'), messages: await convertToModelMessages(messages), // No temperature/topP: Hydrogen ignores them (out-of-range values return a 400). providerOptions: { google: { thinkingConfig: { thinkingLevel: level, includeThoughts: true } }, }, }); return result.toUIMessageStreamResponse({ sendReasoning: true }); } I default to medium because Google's own table recommends it for responsive chat and interactive coding. high is the API default, though, so if you omit the level you pay for more thinking than a chat turn usually needs.
The client
A plain useChat component that shows reasoning in a collapsible block and lets the user pick the thinking level for each message:
'use client'; import { useState } from 'react'; import { useChat } from '@ai-sdk/react'; export function Chat() { const [input, setInput] = useState(''); const [level, setLevel] = useState<'low' | 'medium' | 'high' | 'xhigh'>('medium'); const { messages, sendMessage, status, stop } = useChat(); return ( <div className="mx-auto flex max-w-2xl flex-col gap-4 p-4"> {messages.map((m) => ( <div key={m.id} className={m.role === 'user' ? 'self-end' : 'self-start'}> {m.parts.map((part, i) => part.type === 'reasoning' ? ( <details key={i} className="text-sm text-muted-foreground"> <summary>Thinking</summary> <p className="whitespace-pre-wrap">{part.text}</p> </details> ) : part.type === 'text' ? ( <p key={i} className="whitespace-pre-wrap">{part.text}</p> ) : null, )} </div> ))} <form className="flex gap-2" onSubmit={(e) => { e.preventDefault(); if (!input.trim()) return; sendMessage({ text: input }, { body: { level } }); setInput(''); }} > <select value={level} onChange={(e) => setLevel(e.target.value as typeof level)}> <option value="low">low</option> <option value="medium">medium</option> <option value="high">high</option> <option value="xhigh">xhigh</option> </select> <input className="flex-1 border px-2" value={input} onChange={(e) => setInput(e.target.value)} /> {status === 'streaming' ? ( <button type="button" onClick={stop}>Stop</button> ) : ( <button type="submit" disabled={status === 'submitted'}>Send</button> )} </form> </div> ); } Swap the raw elements for shadcn Button, Select and Collapsible if that's your stack. The data flow stays the same.
How I tested it (and what I didn't)
To be upfront: I didn't call the live API for this post. I ran the code above on Node 24 with a custom fetch that records the outgoing request and replies with a fake SSE stream. That checks the wiring, not the model's quality or speed. Here's what it showed:
- The request is right. It hits
models/gemini-4-hydrogen:streamGenerateContent?alt=ssewiththinkingConfig: { thinkingLevel, includeThoughts: true }. The UI stream comes back asreasoning-start / reasoning-delta / reasoning-endfollowed bytext-*parts, which is exactly what thedetailsblock renders. -
temperatureis still forwarded, with no warning. Passingtemperature: 0.2put"temperature": 0.2ingenerationConfig, andresult.warningswas empty. Per Google's guide the server ignores in-range values, so this won't break anything. But if your shared config sets something out of range, you'll get a400and the SDK won't have warned you. I'd strip sampling params for Hydrogen. -
thinkingLevel: 'minimal'passes through unchanged. The provider's types still allow it for older models, so a config copied from a Gemini 3 app will type-check and then fail at the API. Search your code forminimal. - The portable
reasoningoption maps correctly.reasoning: 'xhigh'becamethinkingLevel: 'xhigh'on Hydrogen. Ongemini-4-argon, the SDK downgraded it tohighand raised a compatibility warning, which matches the changelog note thatxhighmaps only for Hydrogen.
Honest limits
- The speed and benchmark figures above are Google's, not mine.
-
xhighcosts more and responds more slowly, and Google warns it can overthink simple prompts. Don't make it the default in a chat box. - Thinking tokens are billed as output at $7.50/1M, so
includeThoughtsplushighon every turn adds up. Logusage.outputTokenDetails.reasoningTokens, which the SDK exposes, and watch it. - If you rely on explicit context caching for a big system prompt, that path is gone. Check whether implicit caching (prompts of 4,096+ tokens) covers your case.
Sources
- Google: Introducing Gemini 4 Hydrogen (Nov 12, 2026)
- Google AI Studio docs: What's new in Gemini 4 Hydrogen
- Vercel AI SDK: @ai-sdk/google changelog (4.0.119)
If you'd rather not hand-roll the reasoning, tool-call and message components, Cuelark UI has shadcn-style ones built for this kind of stream.