10 Prompts for Code Performance Optimization: Find Bottlenecks and Speed Up Your Apps
Introduction
Performance optimization is not about guessing. When a web page loads in 6 seconds or a backend job runs for an hour, you need to locate the exact piece of code responsible. Profilers, tracing tools, and flame graphs can give you data, but turning data into decisions requires experience. This is where Large Language Models (LLMs) shine — if you ask them the right way. A prompt like "optimize my code" produces platitudes. A prompt that provides profiler output, your stack, and a specific question yields a concrete, ranked action plan.
The ten prompts below come from real sessions with tools like cProfile, perf, PostgreSQL EXPLAIN, Chrome DevTools, and pprof. Each has been used in production-critical situations. You can copy them directly, but the real value is in the structure: context, constraint, and expected output. The examples show how to combine them with your existing profiling workflow.
Why Prompt Engineering Matters for Performance
Consider the official Python documentation for cProfile. It states that the profiler "determines where your program is spending most time" — but it does not tell you what to do about it. Interpreting the output is an expert task. Many engineers read a profile and still make a wrong fix, because they don't see the interaction between data structures, caching, and I/O. An LLM, when given a precise prompt, can act as a senior engineer: it ranks functions by impact, identifies the likely root cause, and suggests a verification method.
Prompt engineering also helps avoid cognitive bias. The most recent code you wrote is not necessarily the slowest. A structured prompt forces the model to analyze the entire picture, just like a staff engineer would in a review.
Anatomy of a Performance Prompt
A repeatable prompt contains four parts:
- Role — "You are a senior performance engineer" tells the model how to reason.
- Context — profiler output, stack, architecture.
- Constraint — what to ignore, how many items to return, what order.
- Expected output — a table, a code block, a list.
Here is a template:
[Role]. I'm working with [stack]. Here is [data]. Identify the top [N] [issues] and rank them by [impact]. Suggest a [concrete] solution and provide [output format].
This way, you can generate a new prompt for any performance problem.
The 10 Prompts
Each prompt includes the prompt text, a realistic usage example, and why it works. You can copy-paste the blockquoted prompt into your LLM of choice.
1. Critical Path Analyzer
Prompt:
You are an experienced performance engineer. I'll give you a profiler output for my [language/stack] application. Identify the top 5 functions that together consume the most CPU time. For each, explain why it is likely slow and suggest a concrete optimization. Ignore functions from third-party libraries unless they are called unusually often. Provide a suggested order for implementing these changes.
Example usage:
Capture a profile with a tool. For Python:
python -m cProfile -s cumtime my_app.py
This prints a table of function calls sorted by cumulative time. Paste the first 30 lines into the prompt.
In one case, the output showed a custom parse_date() function being called millions of times. The prompt pointed to changing from datetime.strptime to datetime.fromisoformat — a change that reduced wall time from 14 seconds to 2.3 seconds.
Why it works: By limiting the scope to the top 5 and ignoring third-party code, the model concentrates on the parts of the codebase you control. This avoids generic suggestions like "update your driver" and surfaces internal bottlenecks.
2. Algorithmic Complexity Regressor
Prompt:
Act as an algorithms expert. I'll show you a function and describe how it is called in production. Analyze the worst-case time and space complexity. If a more efficient algorithm or data structure exists, provide a refactored version. Show a table comparing old and new complexity. Assume that input size can be up to [N] elements.
Example usage:
Paste code like this:
def find_duplicates(items):
seen = []
dups = []
for item in items:
if item in seen:
dups.append(item)
else:
seen.append(item)
return dups
The model should recognize it as O(n²) due to list membership test. It will then provide a set-based version:
def find_duplicates(items):
seen = set()
dups = set()
for item in items:
if item in seen:
dups.add(item)
else:
seen.add(item)
return list(dups)
The table will show O(n) time and O(n) space. This change matters when N reaches 50,000 or more.
Why it works: LLMs are trained on countless implementations of classic algorithms. Asking for a complexity table forces the model to articulate trade-offs rather than silently rewriting your code.
3. Database Query Surgeon
Prompt:
You are a database administrator for [PostgreSQL/MySQL]. Here is a schema (SQL DDL) and a slow query. I'll also include the output of EXPLAIN ANALYZE. Identify missing indexes, full table scans, inefficient joins, or unnecessary ORDER BY operations. Write an optimized query and explain how the execution plan changes. Consider a composite or covering index, and only include a denormalization suggestion if there is no other way.
Example usage:
Run:
EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM orders WHERE customer_id = 123 ORDER BY created_at DESC;
Paste the schema, the query, and the EXPLAIN output. The prompt will recommend:
CREATE INDEX idx_orders_customer_created ON orders (customer_id, created_at DESC);
After adding this index, the plan changes from "Seq Scan on orders" (cost 1000...) to "Index Scan using idx..." (cost 0.56..4.58). This is a textbook optimization described in the PostgreSQL documentation. In a real system, adding a composite index reduced a query from 350ms to 3ms.
Why it works: The prompt gives the LLM both schema and execution plan, which is the exact input a DBA needs. Without this context, it would offer a generic answer.
4. Memory Leak Investigator
Prompt:
Act as a memory forensics expert. I'll provide a heap snapshot from [tracemalloc/jmap/memray]. Find the objects that consume the most memory and trace them back to the source assignment in the code. Show the reference chain (what references what) and suggest how to break it. If the service runs for days, highlight patterns that are likely to cause a memory leak.
Example usage:
In Python, use tracemalloc:
import tracemalloc
tracemalloc.start()
# your code here...
snapshot = tracemalloc.take_snapshot()
top = snapshot.statistics('lineno')
for stat in top[:10]:
print(stat)
Paste the output. Suppose the top line is myapp/cache.py:12: 158.3 MiB. The prompt will explore line 12 and find a global dictionary that appends every response to cache without eviction. It will suggest using functools.lru_cache(maxsize=256) or a TTL cache. This is a classic leak pattern.
Why it works: The reference chain requirement makes the model produce an explanation you can verify, rather than a mysterious "memory leak."
5. Concurrency Risk Annotator
Prompt:
You are an expert in concurrent programming. I'll show you a multi-threaded or asyncio function. Identify race conditions, deadlocks, or unnecessary locks. Suggest a concurrency model that better fits the workload, and provide a corrected version with deliberate synchronization. Explain why each primitive is chosen.
Example usage:
Paste a function that increments a shared counter from multiple threads:
counter = 0
def worker():
global counter
for _ in range(1000):
counter += 1
The model will point out that counter += 1 is not atomic and may lose updates. It will show how to use threading.Lock or threading.local. If the code is Python, it may also suggest using multiprocessing if CPU-bound.
Why it works: This prompt is useful not only for fixing bugs but for learning — it explains the trade-offs between locks, channels, and thread pools.
6. Network Waterfall Explainer
Prompt:
Act as a frontend performance auditor. I'll give you a list of requests from a HAR file (URL, start time, duration, size, cache status). Identify requests that block rendering, cause redirects, or have poor TTL. Recommend a list of concrete fixes: HTTP/2 or HTTP/3, CDN usage, preload/preconnect, and deferring non-critical scripts. Prioritize the fixes by expected impact.
Example usage:
Open Chrome DevTools, go to the Network tab, right-click > Export HAR. Paste the JSON array of request entries.
The model might detect that style.css is 240KB and is render-blocking. It will suggest extracting critical CSS or using media="print" trick. It will also notice that your API is on a different origin and recommend preconnect to reduce connection setup time.
Why it works: The HAR contains precise timings; the prompt asks for prioritization, so you don't get a laundry list of every performance tip.
7. Render Pipeline Optimizer (Frontend)
Prompt:
You are a browser rendering expert. I'll provide a React/Vue component. Identify why it re-renders more than necessary or causes layout thrashing. Suggest specific techniques: React.memo, useMemo, useCallback, CSS containment, or moving state down. Write the optimized component with comments explaining each modification.
Example usage:
Paste:
function MessageList({ messages, username }) {
const [unread, setUnread] = useState(0);
const visible = messages.filter(m => m.to === username);
const style = { background: 'white' };
// ... render
}
The prompt should notice that visible is recomputed on every render, including when you type inside an input. It will recommend wrapping visible in useMemo with [messages, username] as dependencies, and memoizing MessageItem if it is a child.
Why it works: This is a very common issue in React, and a well-crafted prompt yields a component that uses hooks correctly.
8. Bundle Slasher
Prompt:
Act as a build optimizer. I'm using [Webpack/Vite]. I'll provide the output of a bundle analyzer tool. Identify the largest dependencies, duplicate chunks, and unused polyfills. Suggest code splitting, dynamic imports, tree shaking, or a lighter alternative library. Give step-by-step configuration changes and warn about migration pitfalls.
Example usage:
Run npx vite build --report or use webpack-bundle-analyzer. Paste the module size tree.
The model will spot that moment is 320KB and only two functions are used. It will suggest replacing it with date-fns which is tree-shakeable. It will also show how to configure manual chunk separation in Vite for vendor libraries.
Why it works: The bundle report is a concrete, data-rich input. The prompt asks for a prioritized list, which makes the output actionable.
9. Cache Strategy Designer
Prompt:
You are a system architect. I'm building a read-heavy service. Here is the data access pattern (write rate, read rate, and typical latency budget). Design a multi-level cache strategy: CDN, Redis, and in-memory. Specify cache keys, TTL, eviction policy, and how to prevent the thundering herd problem. Provide pseudocode for a cache-aside implementation.
Example usage:
Describe:
The service returns product details from a PostgreSQL database. Read throughput: 10,000 req/s; write rate: 100 req/s; required p99 latency < 150ms.
The prompt will design a multi-tier cache: CDN for static assets, Redis for product data with TTL of 300 seconds, and a local Caffeine or LRU cache for the hottest keys. For thundering herd, it will propose using a Redis distributed lock per key and caching null responses for short periods to avoid stampede.
Why it works: The prompt forces the model to consider the trade-off between cache invalidation and speed, which is the essence of caching design.
10. Benchmark Harness Writer
Prompt:
Act as a testing expert. Write a benchmark script in [Java/Go/Python] for this function. The benchmark should include warmup, enough iterations for statistical significance, and a report of mean, max, p50, p95. Also write a regression test that fails if the new implementation is slower than the old implementation by more than 10%. Assume we have two versions of the function.
Example usage:
For Go, the prompt will generate:
func BenchmarkNew(b *testing.B) {
for i := 0; i < b.N; i++ {
// call new implementation
}
}
And for comparison, a BenchmarkOld. The regression test will use testing.AllocsPerRun and time.Now() or a proper benchmark comparison.
Why it works: It gives you a ready-to-run test, turning performance optimization into a CI-guarded practice.
Comparison Table
| Prompt | Best for | Necessary tool | Output type |
|---|---|---|---|
| #1 Critical Path | CPU-bound backends | cProfile, perf, pprof | Ranked list of fixes |
| #2 Complexity | Inefficient algorithms | None | Complexity table + refactor |
| #3 Query Surgeon | Slow SQL | EXPLAIN | Optimized query + index |
| #4 Memory Leak | Long-running services | tracemalloc, jmap | Reference chain + fix |
| #5 Concurrency | Multi-threaded bugs | Race detector | Synchronization code |
| #6 Waterfall | Web latency | HAR export | Preconnect, defer, compress |
| #7 Render | React/Vue UI | React DevTools | Memoized component |
| #8 Bundle | Large JS apps | Bundle Analyzer | Splitting config |
| #9 Cache | Read-heavy APIs | Redis / CDN | Cache strategy + pseudocode |
| #10 Benchmark | Any optimization | go test / timeit | Benchmark + regression test |
Real-World Workflow: Combining Prompts
Let's walk through a realistic scenario. You support a REST API for a mobile app. Users complain that the leaderboard endpoint takes 4 seconds. Start with prompt #1 and paste cProfile output. The profiler shows that 75% of time is spent in a SQLAlchemy ORM call. Shift to prompt #3, paste the generated SQL and EXPLAIN output. The model suggests a missing index. Once applied, the endpoint drops to 400ms. Then, to confirm the improvement, run prompt #10 to write a benchmark that you can run in CI, preventing future regressions.
In another case, a frontend developer used prompt #6 on a HAR file, which led to adding preconnect to the content delivery network, saving 200ms on first paint. These are not imaginary "80% faster" claims — they are concrete, measurable results.
Pitfalls to Avoid
- Using a prompt without profiler data. AI cannot guess what's slow.
- Asking for "best practices" — you will get a generic list.
- Forgetting context (language version, database, environment).
- Not verifying the generated code with a profiler or benchmark.
Quick Start Checklist
- [ ] Run a profiler before changing anything
- [ ] Choose one of the 10 prompts matching your bottleneck
- [ ] Provide profiler output, not just a code snippet
- [ ] Ask the model to rank fixes by impact
- [ ] Implement the top fix
- [ ] Benchmark before/after with prompt #10
- [ ] Document the result
Conclusion
The ten prompts above are a starting point. The ultimate goal is to automate performance analysis: from raw profiler output to a prioritized list of fixes. You can adapt each prompt to your own stack and add your own context. With a clear, structured prompt, you can leverage AI to think like a staff engineer and make data-driven optimization a habit.
Take the first prompt, run a profiler on your codebase, and paste the output into your favorite LLM. You'll be surprised how quickly it finds the bottleneck. If you have your own battle-tested prompt, share it in the comments.
References
- Python cProfile: https://docs.python.org/3/library/profile.html
- PostgreSQL EXPLAIN: https://www.postgresql.org/docs/current/sql-explain.html
- Chrome DevTools Performance: https://developer.chrome.com/docs/devtools/performance/
- Go pprof: https://pkg.go.dev/net/http/pprof
- React useMemo: https://react.dev/reference/react/useMemo
- Webpack Bundle Analyzer: https://github.com/webpack-contrib/webpack-bundle-analyzer
- Google web.dev: https://web.dev/learn/performance/
Comments