Claude Code Extended Thinking: When to Ask It to Think Harder
You type "fix this bug" into Claude Code and it fixes the wrong thing. You type "think hard about this bug" and it finds the real root cause on the first try. That difference isn't magic and it isn't placebo — it's extended thinking, a real budget of extra reasoning tokens that Claude Code allocates when you ask for it with specific trigger phrases. Most developers either never use these phrases, or sprinkle them on every single prompt like seasoning. Both are mistakes. Extended thinking has a cost in latency and tokens, and it has a shape: some tasks benefit enormously, others don't move at all. This piece is about learning which is which, so you stop guessing and start spending your thinking budget where it actually pays off.
What Extended Thinking Actually Is
Claude Code sits on top of Claude models that support a distinct "thinking" mode, separate from the visible response. When thinking is enabled, the model generates an internal reasoning trace — working through the problem, checking its own logic, considering alternatives — before it writes the answer you see. In the terminal, you'll notice this as a visible "Thinking..." block that streams before the actual code or explanation appears.
This isn't the same as the model just "trying harder" in some vague sense. It's a token budget. Anthropic's models can be given more space to reason before committing to an answer, and Claude Code exposes that budget through a small set of magic words in your prompt. The current tiers, from lowest to highest budget, are:
- think — a baseline bump in reasoning tokens
- think hard / think a lot — a larger budget
- think harder — larger still
- ultrathink — the maximum budget Claude Code will allocate
Each tier gives the model more room to reason step by step before answering. You don't need to know the exact token counts to use this well — what matters is the practical effect: more budget means Claude explores more of the solution space, double-checks assumptions, and catches edge cases it would otherwise skip past. Less budget means faster, cheaper, more reflexive answers.
The important nuance is that this is not a universal multiplier on quality. Extended thinking helps with problems that have depth — problems where the right answer depends on reasoning through multiple steps, weighing tradeoffs, or holding several constraints in your head at once. It does nothing for problems that are shallow but tedious — renaming a variable across twelve files, formatting a JSON payload, writing a getter. For those, extended thinking is wasted latency.
The Trigger Words, and What They Really Do
Let's get concrete, because vague guidance ("use it for hard problems") isn't actionable. Here's how the tiers map to real Claude Code sessions.
"think" is your default upgrade from a bare prompt. Use it when you want Claude to pause and consider more than the first plausible answer, but the problem isn't genuinely gnarly.
think about the best way to paginate this API response —
should we use cursor-based or offset-based pagination
given that the table has ~40M rows?This is a real decision with real tradeoffs (offset pagination degrades badly at scale, cursor pagination needs a stable sort key), but it's not a multi-file architectural problem. A light "think" nudge gets you a reasoned answer instead of a reflexive "use LIMIT/OFFSET" response.
"think hard" is for problems where the obvious first answer is often wrong, or where the cost of a wrong answer is expensive to undo — schema migrations, concurrency bugs, authentication flows.
think hard about this race condition — two requests can both
read the same inventory count before either writes the
decremented value back, and I need a fix that doesn't require
a distributed lockNotice what this prompt is doing: it's not just saying "think hard," it's handing Claude the actual constraint (no distributed lock) that makes the naive answer wrong. The trigger phrase earns its keep only when paired with a real problem statement — "think hard, fix my code" without specifics wastes the budget on guessing what "fix" means.
"think harder" is for when you've already tried "think hard" and the fix didn't hold, or the problem spans multiple interacting systems.
think harder about why the webhook retries are causing duplicate
charges — I already added idempotency keys on the Stripe side
and it's still happening intermittently under loadThis phrasing tells Claude that the obvious fix (idempotency keys) has already been tried and failed, which forces it to reason about second-order causes: is the idempotency key itself non-deterministic under retries, is there a race between key generation and the charge request, is the webhook handler itself non-idempotent even though the charge call is. That's a multi-hypothesis investigation, which is exactly what a bigger thinking budget is for.
"ultrathink" is reserved for the rare cases where you're asking Claude to reason about system-wide tradeoffs with real consequences: a database migration strategy for a production table with zero downtime, a security review of an auth flow before launch, or an architectural decision that's expensive to reverse.
ultrathink this: we need to migrate from a single Postgres
instance to a read-replica setup with zero downtime, our ORM
doesn't natively support read/write splitting, and we have
active traffic we can't pause — walk through the full migration
plan including rollback pointsThis is intentionally the heaviest tier. If you find yourself typing "ultrathink" more than a couple of times a week, that's a signal you're either using it as a superstition ("just in case") or you're facing genuinely hard problems often enough that you should be breaking them into smaller pieces first.
When Extended Thinking Actually Moves the Needle
The pattern across all four tiers is the same: extended thinking helps when the task has branching logic — multiple plausible paths where picking the wrong one costs you real time. Concretely, that includes:
- Debugging non-obvious bugs. Anything where the stack trace points at the symptom, not the cause — race conditions, memory leaks, flaky tests, intermittent 500s that only happen under load.
- Architectural decisions. Choosing between denormalizing a schema vs. adding a cache layer, deciding whether a feature belongs in a Lambda or a long-running worker, picking a state management approach for a frontend that's about to get more complex.
- Security-sensitive code. Auth flows, payment webhook handlers, anything touching signature verification or token validation, where a subtly wrong assumption is a real vulnerability, not just a bug.
- Multi-constraint refactors. "Refactor this without breaking the public API, without adding a new dependency, and without regressing the p95 latency" is a reasoning problem, not a mechanical one.
- Reviewing someone else's (or your own past) code for correctness. Extended thinking during review means Claude actually traces through edge cases instead of pattern-matching on "this looks like normal code."
Here's a debugging example that shows the difference in practice. A flat prompt:
the checkout page is throwing a null pointer error sometimes,
can you fix it...tends to get you a patch that guards against null in the one place the traceback pointed to. A thinking-triggered version:
think hard about the checkout page null pointer error — it only
happens for users who abandon and return to checkout after their
session token refreshes, so I suspect it's a stale closure over
the old user object somewhere in the payment stepgives Claude a hypothesis to test, and the reasoning budget to actually trace whether that closure theory holds up across the whole component tree, not just patch the null and move on. The second version fixes the actual bug. The first one usually just moves it somewhere else.
When It's a Waste of Tokens (and Time)
Extended thinking has a real cost: it's slower, and on some plans it's metered token spend. Using it reflexively on every prompt is like proofreading your grocery list with the rigor of a legal contract. Skip it for:
- Mechanical edits. Renaming a function across a codebase, updating an import path after a file move, bumping a dependency version. There's no branching decision here — "think" adds latency without adding insight.
- Boilerplate generation. Scaffolding a new React component with the same shape as ten others in the repo, writing a standard CRUD endpoint that mirrors an existing one. Claude already has the pattern; reasoning harder about it doesn't produce a better result.
- Formatting and style fixes. Converting tabs to spaces, applying a linter's suggestions, reformatting JSON. Purely mechanical, zero ambiguity.
- Well-specified, single-path tasks. "Add a
created_attimestamp column to theorderstable with a default ofnow()" has exactly one reasonable interpretation. Thinking harder about it just delays the obvious answer. - Tasks you're going to iterate on anyway. If you're prototyping and expect to throw away the first three attempts, a fast, low-thinking response lets you iterate quicker. Save the thinking budget for when you've converged on the right problem statement and want the best possible single shot at it.
A good gut check: if you can predict with high confidence what a competent engineer would write without pausing to think, don't ask Claude to pause and think either. If you genuinely don't know what the right answer looks like yet, that's exactly the signal to reach for "think hard" or higher.
Reading the Thinking Trace Instead of Skipping Past It
One habit worth building early: actually read the "Thinking..." block instead of waiting for it to finish so you can get to the code. The trace is useful in its own right, independent of the final answer, for two reasons.
First, it tells you whether Claude understood the problem the way you meant it. If you asked Claude to "think hard about why the cache is returning stale data" and the trace immediately fixates on TTL configuration while your actual suspicion is a write-through failure, you know within a few seconds that the framing didn't land — and you can interrupt and re-prompt with sharper context instead of waiting for a confidently-wrong answer to finish generating.
Second, the trace often surfaces alternatives that got rejected, and *why* they got rejected. That "why" is frequently more valuable than the final answer, especially on a team. If Claude considered adding a Redis-backed distributed lock for the inventory race condition and rejected it because you'd explicitly ruled out a distributed lock, that's a decision worth copying into a PR description or a comment, so the next engineer who looks at the code doesn't re-propose the same rejected approach six months later.
A useful pattern is to explicitly ask for this in the prompt:
think hard about the best caching strategy for this product
listing endpoint, and in your answer call out which alternatives
you considered and specifically why you ruled them outThis doesn't change the size of the thinking budget, but it does change what surfaces in the final answer — you get a decision record, not just a decision. That matters more than it sounds like it should, because the single biggest source of wasted engineering time on a team is redoing an investigation someone already did and abandoned for a documented reason.
Combining Extended Thinking with Plan Mode
Extended thinking and Claude Code's plan mode solve adjacent but different problems, and the strongest results often come from using both together. Plan mode forces Claude to lay out its approach before touching any files, which gives you a checkpoint to correct course early. Extended thinking makes the reasoning *behind* that plan more rigorous.
A prompt like:
think hard about how to add rate limiting to our public API —
we're on a multi-region deployment behind a load balancer, so a
simple in-memory counter won't work across instances. Plan mode:
lay out the approach before writing any code.gets you the best of both. The extended thinking budget makes sure Claude actually reasons about the distributed-counter problem (Redis-backed sliding window vs. token bucket vs. a rate-limiting service) instead of defaulting to the simplest in-memory answer. Plan mode surfaces that reasoning as a reviewable plan before any file gets touched, so if Claude picks an approach that doesn't fit your infra (say, you don't want to add a Redis dependency), you catch it before code exists, not after.
This combination is especially valuable for anything touching production infrastructure, database schemas, or code that's expensive to unwind once merged. The plan gives you a human checkpoint; the thinking budget makes the plan worth reviewing in the first place.
A Practical Workflow: Escalating the Thinking Budget
Rather than guessing which tier to reach for up front, a more reliable habit is to escalate only when needed:
- Start with a plain prompt. No trigger words. Most tasks — even ones that feel intimidating at first glance — resolve fine with Claude's default reasoning.
- If the first answer misses the point or feels shallow, add "think." Restate the problem with any extra context you withheld the first time (constraints, things you already tried, why the obvious answer doesn't work).
- If "think" still isn't cutting it, escalate to "think hard," and make sure your prompt is doing its share of the work — specific symptoms, specific constraints, what you've ruled out.
- Reserve "think harder" and "ultrathink" for genuinely multi-system problems where getting it wrong is costly: production migrations, security-sensitive flows, architecture decisions you'll live with for a year.
This escalation habit does two things. It keeps your average token spend low, since most tasks never need more than a plain prompt. And it trains you to notice, over time, which categories of problems in *your* codebase tend to need the higher tiers — usually it clusters around concurrency, auth, and anything touching money, because those are the places where the first plausible answer is disproportionately likely to be wrong.
One more practical note: the trigger phrase is not a substitute for context. "Ultrathink, fix the bug" with no other detail will not out-reason a well-specified "think" prompt that includes the actual stack trace, the conditions under which the bug reproduces, and what you've already ruled out. Extended thinking amplifies the reasoning Claude can do with what you've given it — it doesn't manufacture missing information. The highest-leverage move is almost always spending thirty extra seconds writing a better problem statement, then adding the trigger word on top of that.
Common Mistakes to Avoid
A few patterns show up repeatedly among developers first learning to use extended thinking:
- Using "ultrathink" as a habit rather than a decision. If every prompt gets the maximum tier regardless of the task, you're paying maximum latency for tasks that didn't need it. Reserve it.
- Treating the trigger word as the whole prompt. "Think hard" with no problem detail gives Claude a bigger budget to reason about a vague ask, which mostly just produces a longer vague answer.
- Never using it at all. Some developers avoid extended thinking entirely because it feels slower, and then wonder why Claude Code keeps missing subtle bugs. If you've never seen the "Thinking..." block appear, you're leaving a real capability on the table for exactly the debugging and architecture work where it matters most.
- Not escalating when the first attempt fails. If a plain prompt or a "think" prompt gives you a fix that doesn't hold up under testing, that's the signal to escalate to "think hard" with the added context of what you tried and why it didn't work — not to just ask the same question again.
Wrapping Up
Extended thinking in Claude Code isn't a mysterious performance switch — it's a token budget you control with plain-English trigger phrases, and it pays off specifically on problems with real branching logic: debugging root causes instead of symptoms, architectural tradeoffs, security-sensitive code, and multi-constraint refactors. It does nothing useful for mechanical, single-path tasks, where it just adds latency. The skill worth building isn't memorizing which tier to use — it's noticing, in the moment, whether the task in front of you has a genuinely uncertain right answer or an obvious one. That judgment, paired with escalating from plain prompts up through "think," "think hard," and "ultrathink" only as needed, is what separates developers who get inconsistent results from Claude Code from developers who get it to reliably solve hard problems on the first pass.
If you want to build this kind of judgment systematically — not just extended thinking, but the full range of Claude Code workflows including plan mode, subagents, hooks, and MCP integrations — our Claude Code Tutorial for Beginners course walks through all of it with real projects, not toy examples. It's built for developers who want to move past copy-pasting prompts and start actually reasoning about how to work with Claude Code the way its designers intended.
AI CodingShip full-stack AI apps at conversation speed — specs, agents, deploys, all from the terminal.
Claude CodeGo from zero to confident with Claude Code, the terminal agent that reads, edits, runs, and verifies real code.
Related reading