Skip to content
AI Dev Toolkit.
Esc
  • AI Token CounterCount tokens for GPT, Claude, Gemini, DeepSeek, Qwen and more.Tool
  • LLM API Cost CalculatorEstimate per-request, daily and monthly API costs.Tool
  • AI Model ComparisonCompare prices, context windows and features across models.Tool
  • AI Model Pricing PagesSpecs, real costs and cheaper alternatives for popular models.Tool
  • Context Window CheckerSee whether your text fits each model’s context window.Tool
  • Subscription vs API CalculatorFind out whether a chat plan or the API is cheaper for you.Tool
  • GPU / VRAM CalculatorCheck how much VRAM a local model needs and which GPUs fit.Tool
  • Prompt Caching CalculatorEstimate savings from prompt caching.Tool

Prompt template · Code

Code performance review prompt

Find likely bottlenecks for a stated workload, explain their cost and say what to measure before changing anything. Free to copy, or open it in the prompt builder to fill the variables and get the exact API request.

252 tokens unfilled · 399 with the example below · o200k_base (GPT-4o and later)

Template

The prompt

Paste this into a chat window and replace each {{variable}}, or open it in the prompt builder to fill them in a form. Sections are marked with XML tags, which every major model reads well.

Prompt (one message, plain text)
You are a performance engineer. You reason from the workload and data sizes, and you insist on measuring before optimising.

<context>
The workload: how often this runs, on how much data, and the current symptoms:
<workload>
{{workload}}
</workload>

The code:
<code>
{{code}}
</code>
</context>

<constraints>
- Rank issues by their likely impact at the stated data sizes, not by how easy they are to spot.
- For each issue, give the cost in terms of the workload (for example, one query per item means 5,000 queries per request).
- Separate likely bottlenecks from micro-optimisations. Skip micro-optimisations unless the workload makes them matter.
- Say what to measure to confirm each issue before anyone changes the code.
- Keep the code’s behaviour the same.
</constraints>

<output_format>
A numbered list, highest impact first: issue, estimated cost, how to confirm it, and the fix with a short code sketch. Finish with the single change you would try first.
</output_format>

<task>
Identify where this code is likely to spend its time or memory under the workload described, and what would make it faster.
</task>
For an API call: system prompt and user message

With a system prompt, the role, constraints and output format stay fixed across calls (and can be cached), while the context and task go in the user message.

System prompt
You are a performance engineer. You reason from the workload and data sizes, and you insist on measuring before optimising.

<constraints>
- Rank issues by their likely impact at the stated data sizes, not by how easy they are to spot.
- For each issue, give the cost in terms of the workload (for example, one query per item means 5,000 queries per request).
- Separate likely bottlenecks from micro-optimisations. Skip micro-optimisations unless the workload makes them matter.
- Say what to measure to confirm each issue before anyone changes the code.
- Keep the code’s behaviour the same.
</constraints>

<output_format>
A numbered list, highest impact first: issue, estimated cost, how to confirm it, and the fix with a short code sketch. Finish with the single change you would try first.
</output_format>
User message
<context>
The workload: how often this runs, on how much data, and the current symptoms:
<workload>
{{workload}}
</workload>

The code:
<code>
{{code}}
</code>
</context>

<task>
Identify where this code is likely to spend its time or memory under the workload described, and what would make it faster.
</task>

Variables

What to put in each variable

{{workload}}
Real numbers: calls per second, rows or items per call, payload sizes, and the symptom (p95 latency, memory growth, timeouts). Without sizes, every loop looks equally suspicious.
{{code}}
The slow path: the handler or function and the helpers it calls, including database queries.

Use

When to use it

Use it when something is slow and you have a suspect area but no profile yet, or to sanity-check a design before load testing. It is good at spotting structural problems such as N+1 queries, quadratic loops over growing lists, repeated parsing and unbounded caches.

It isn’t a profiler. The model estimates from reading code, so the first step it recommends should usually be a measurement. If you already have profiler output, paste it into the workload section; it is far better evidence than the code alone.

Structure

Why it’s structured this way

The workload comes first because performance depends entirely on scale. A nested loop over ten items is fine, over a million it’s the outage. Giving the model sizes lets it compute costs (“5,000 queries per request”) instead of listing every loop as a potential problem.

Ranking by impact and separating micro-optimisations keep the answer focused. Without that rule, models often lead with string concatenation or loop syntax, which almost never matters, while the database call inside the loop sits further down the list.

Asking for a measurement per issue builds in the discipline that prevents wasted work: confirm the bottleneck, then fix it. The final “single change you would try first” forces a recommendation, which is what you need when deciding where to spend an afternoon.

Example

A filled-in example

{{workload}}
Called on every dashboard load, about 20 times a second at peak. A typical account has 2,000 projects. p95 latency is 4.2 seconds and the database shows high query counts.
{{code}}
def dashboard(account_id):
    projects = db.query("SELECT * FROM projects WHERE account_id = %s", account_id)
    rows = []
    for p in projects:
        owner = db.query_one("SELECT name FROM users WHERE id = %s", p["owner_id"])
        open_tasks = db.query_one("SELECT COUNT(*) FROM tasks WHERE project_id = %s AND done = false", p["id"])
        rows.append({**p, "owner": owner["name"], "open": open_tasks[0]})
    return rows

What to look for. A good answer computes about 4,001 queries per load (one, plus two per project) and recommends a join and a grouped count, after confirming the query count in the database logs. It shouldn’t lead with the SELECT * or the dict copy.

The complete filled-in prompt (399 tokens)
Filled-in prompt
You are a performance engineer. You reason from the workload and data sizes, and you insist on measuring before optimising.

<context>
The workload: how often this runs, on how much data, and the current symptoms:
<workload>
Called on every dashboard load, about 20 times a second at peak. A typical account has 2,000 projects. p95 latency is 4.2 seconds and the database shows high query counts.
</workload>

The code:
<code>
def dashboard(account_id):
    projects = db.query("SELECT * FROM projects WHERE account_id = %s", account_id)
    rows = []
    for p in projects:
        owner = db.query_one("SELECT name FROM users WHERE id = %s", p["owner_id"])
        open_tasks = db.query_one("SELECT COUNT(*) FROM tasks WHERE project_id = %s AND done = false", p["id"])
        rows.append({**p, "owner": owner["name"], "open": open_tasks[0]})
    return rows
</code>
</context>

<constraints>
- Rank issues by their likely impact at the stated data sizes, not by how easy they are to spot.
- For each issue, give the cost in terms of the workload (for example, one query per item means 5,000 queries per request).
- Separate likely bottlenecks from micro-optimisations. Skip micro-optimisations unless the workload makes them matter.
- Say what to measure to confirm each issue before anyone changes the code.
- Keep the code’s behaviour the same.
</constraints>

<output_format>
A numbered list, highest impact first: issue, estimated cost, how to confirm it, and the fix with a short code sketch. Finish with the single change you would try first.
</output_format>

<task>
Identify where this code is likely to spend its time or memory under the workload described, and what would make it faster.
</task>

Models

Tips by model family

  • OpenAI GPT

    OpenAI says reasoning models do well with a clear end goal and success criteria. State the target (“p95 under 500 ms”) in the workload so the model can judge which fixes are enough.

  • Claude

    Anthropic recommends explaining why a constraint matters. If behaviour must stay identical because of, say, a reporting job that depends on row order, say so; Claude generalises better from the reason than from the bare rule.

  • All models

    Include the query plan or profiler output if you have it. Real measurements beat inference from code every time.

Related

Edited the template? Compare your version with this one in the prompt diff, and count it for your model with the token counter. Browse all 29 prompt templates.