AI Code Assistants: Cursor, Claude Code and Copilot in Production
The verdict first
I pay for two of these, and I would still pay for two — but not the two I expected.
The single most useful thing in my stack is a terminal agent that reads the repository before it writes. When I ask it to change how authentication works across three projects, it finds the five call sites, shows me what it intends to change, and I approve or reject each one. That is a genuine multi-hour task compressed into a review. Inline completion, by contrast, is a typing accelerator that saves me maybe ten minutes a day and occasionally saves me an hour when the pattern is repetitive.
The honest accounting is that these tools moved my bottleneck. Writing the first version of code stopped being slow. Reading code that a model wrote became the slow part. That is a good trade when the code is boilerplate and a bad trade when the code encodes a rule that only exists in your head — because the model’s version will be fluent, idiomatic, and wrong, and the wrongness is expensive to find.
The other thing nobody tells you: the price models are opaque, the limits move, and if you are on a per-seat plan you should check current pricing before you commit to anything. All three of these change their tiers regularly.
What I tested on
- Duration: roughly six months, running all three in parallel on the same work so I could compare rather than switch.
- Codebase: a .NET 8 API and a Python FastAPI service, several hundred files, plus the Playwright publishing layer. Not a toy repo — the kind of codebase where “which module owns this” is a real question.
- Languages: C# and Python, with TypeScript in the front end and SQL in the data layer.
- Daily volume: a normal working day is a few hundred lines read and edited, and my personal usage ran to several agent sessions per day plus continuous inline completion.
- Workload mix: roughly half new feature code, a substantial share of test writing and refactoring, and a long tail of “why does this break” investigation.
- Cost magnitude: per-seat subscriptions, so the bill scales with headcount rather than usage — with usage-based tiers available on the agent products. Check current pricing for each; the tiers have changed more than once during my test period.
- Environment: I did not let any of them have standing production credentials, and I ran one of them against a sandboxed container for the tasks that needed to execute code.
What it does well
- Terminal agents that read before they write. This is the capability that changed how I work. Give it a behavioural change and it greps the repo, finds the real call sites including the ones in tests and in the configuration files you forgot about, and proposes a change set. My manual rate of missing a call site was high. The agent’s was lower than mine.
- Test scaffolding, which is where the ROI is cleanest. Generating a first draft of a test for an existing function is a well-bounded task with an objective right answer, and the assistants are good at it. They are also good at generating the mocks and fixtures that nobody wants to write. This is the category where I would tell any sceptical engineer to start.
- Explaining unfamiliar code. “Where does the tenant routing actually get decided, and what happens if the tenant id is missing” is a question I would have spent twenty minutes answering with grep. An agent answers it in a couple of minutes with file references, and I can spot-check its claims quickly because I know what the answer should roughly look like.
- Mechanical refactors across a codebase. Renaming a method, changing a signature, updating every call site including in tests and in a separate service. The agent does the whole sweep in one pass. This is where the multi-file awareness pays for itself.
- The migration work nobody wants. Upgrading a dependency, moving from one SDK to another, adapting to a changed API shape. The agent reads the changelog and the docs, finds the usages, and proposes the edits. It is a genuinely different experience from doing it by hand, and the work is repetitive enough that mistakes are cheap to catch.
Where it fell short
- They produce plausible code that encodes the wrong rule. This is the failure mode that matters. The output looks idiomatic, compiles, passes the tests you wrote, and is wrong in a way nobody caught. The classic version: your codebase treats a null tenant id as “use the default tenant” in one place and as an error in another, and the assistant picks one of them for a new code path without telling you. You get a subtle behavioural difference between two routes through your app that nobody finds until a customer complains.
- They cannot know what is not in the code. Rules that live in a wiki, in someone’s head, in a ticket, or in a comment three files away from the change: invisible. The assistant will implement the rule as written in the nearest code it found, which is a reasonable guess and not the answer. This is the single biggest reason I do not let these tools write business logic unsupervised.
- Review load scales with the volume of changes. A 400-line diff that reads well is not faster to review than a 40-line diff that reads well — it is slower, because you have to hold more of it in your head. When I let an agent work unattended over a weekend, I came back to a diff I then spent most of a day reading. The generation was cheap; the reading was not.
- Context window is not the same as understanding, and the inline tier can be actively distracting. Giving a tool a bigger window does not mean it uses the right part of your codebase — it will cite a file that looks relevant and miss the one that governs the behaviour, confidently. And I turned completion off for a day: my typing speed dropped noticeably and my focus improved. If your typing is already fast, the accelerator saves little and the interruption cost is real.
- They quietly broaden the scope of a change. Asked to fix a bug, an agent will sometimes also refactor the surrounding code, rename things for consistency, and add a helper. Every one of those is a diff line you now own and must review. The same principle shows up in prompt-driven systems, where constraining the scope explicitly is what stops the model widening the work — the model routing guide covers how to keep each stage doing one job.
- Terminal agents run commands, and that is a real risk surface. An agent that can run a shell command can run the wrong one, in the wrong directory, against the wrong environment. The security angle matters more here than for a chat tool, because the blast radius is your machine. If you give one of these tools credentials, give it scoped ones.
The setup
My current setup is deliberately boring, and the boring part is the point: the agent reads and explains, I approve, then it writes.
The pattern I use for a terminal agent — Claude Code or the agent mode in an IDE — is a read-only first pass:
# Phase 1 — investigate only. No writes, no commands that change state.
claude "Find every place that resolves the default tenant when a tenant id is
missing. Read the relevant files, list each call site with file:line, and
explain what each one does. Do not edit anything yet."
Then I read the list, and only then:
# Phase 2 — a specific, bounded change, with an explicit constraint.
claude "Change ONLY the tenant resolver in src/tenants/resolve.py so a missing
tenant id raises TenantResolutionError instead of returning the default tenant.
Update the two call sites you found in phase 1 and their tests. Do not change
any other file. Show me the diff before applying."
Two things make this work. The scope is named explicitly, including what must not change, and the diff is shown before it lands. A general instruction like “fix the tenant handling” produces a much wider diff than the same request with the file named.
For the inline tier, the configuration that helped most was giving it the project conventions explicitly. A project-level instructions file that the tool reads automatically is worth more than any prompt I type:
<!-- .github/copilot-instructions.md -->
- Target .NET 8 and C# 12. Nullable reference types are enabled; do not
add `#nullable disable`.
- All public methods take a CancellationToken as the last parameter.
- Tenant-scoped data access goes through ITenantDbContext. Never query the
DbContext directly from a service.
- Tests use xUnit with FluentAssertions. One test class per production class.
- Do not add new NuGet packages without asking.
The last line is the highest-value one. An agent that installs a package you did not approve is an agent that has just changed your supply chain.
For repository-wide search, the agent’s own search tools beat asking for a file listing, because it can grep and read rather than summarise from filenames:
# What I actually reach for when I do not know where something lives
rg -n "resolve_tenant|TenantResolver|default_tenant" --type py --type cs
Let the agent run the search itself. If you paste grep output into a prompt instead, you have done its job and you have also given it no way to check whether it found everything.
What it cost
Subscription cost. All three price per seat for the IDE and editor tools, with the terminal agents adding a usage allowance on top of, or instead of, a flat fee. The exact tiers and limits have moved more than once during my test period, so check current pricing rather than trusting anything written down — including this paragraph.
For an individual, the honest comparison is: the inline tier is cheap enough to be worth having on a personal plan for the typing acceleration alone. The terminal agent is the expensive one, because you are paying for the reasoning, not the keystrokes. If your daily work is writing code, the agent tier is where the money goes.
Token consumption in agent sessions. A single agent task can read a lot of files. Long-running sessions that read thirty files, then re-read them after an edit, then re-read again to verify, burn through an allowance surprisingly fast. I now break large tasks into smaller scoped ones, which is better for review quality anyway, and I watch the usage meter rather than discovering the limit at the end of a task.
The review cost, which is the real cost. This is the number that decides whether the subscription pays for itself. If the tool generates code at ten times your typing speed but you read every line carefully, your throughput improves by the ratio of generation time to review time, and review time does not shrink. The same discipline applies to judging the output: an assistant generates candidate text, so it needs the kind of regression harness you would put on a prompt — the evaluation guide covers building one, and the principles transfer. The saving comes from the tasks where review is cheap: boilerplate, tests, mechanical sweeps. For everything else, the honest framing is that you have moved the work, not removed it.
The cost of getting it wrong. A bad merge is far more expensive than a slow one. An agent that quietly changes a permission check or drops an error branch is a security finding, not a style comment, and it will surface in production rather than in review. The agent security checklist covers the specific failure modes worth guarding against.
What broke along the way
An agent “fixed” a null check in a way that changed behaviour. The task was to make a handler reject a missing tenant id. The agent found the check, moved it into the resolver, and did it consistently — except the resolver was also used by the internal admin path, where a missing tenant id was legitimate. The change broke admin logins. Nothing in the diff looked wrong; the agent had followed the nearest pattern in the code. The fix was a per-path parameter rather than a global default, and now that rule lives in the instructions file.
A refactor touched 60 files when 12 were needed. I asked for a method rename across the solution. The agent also updated a legacy adapter directory, a generated client, a documentation folder and a set of scripts that referenced the old name in string form. All of it was correct, all of it was in scope by a literal reading, and reviewing it took three times as long as the original change. Now I name the directories to touch and say “leave everything else alone”.
The agent ran a command in the wrong directory. A task that ran a test suite executed it from the repository root instead of the project directory, and the failure output looked like the code was broken when it was only the working directory. Nothing was damaged, but I now have the agent confirm the working directory before running anything, and I run it inside the project container rather than on my host.
An agent conversation silently hit the context limit mid-refactor. It was making good progress across a long session and then stopped mid-file with a message that looked like a refusal. It had simply run out of context and was asking me to start over. The lesson is that long agent sessions need explicit checkpoints: I ask it to summarise the plan so far into a file, so a new session can resume without re-reading everything.
Would I use it again?
Yes, and I would start smaller than I did. If you are sceptical, start with test scaffolding on one module and measure. That is where the value is clearest and the risk lowest.
I would recommend the terminal-agent tier to anyone working in an unfamiliar codebase or doing repetitive multi-file changes. It is the strongest of these tools by a wide margin, because it can read before it writes. I would recommend the inline tier only if your typing is slow or your code is repetitive — if you type quickly, the marginal benefit is small and the distraction is real.
I would not let any of these tools write business rules unsupervised, in a codebase where the rules are not written down. That is where the failure is silent and the cost is high.
One more recommendation: if you are on a team, agree on what is off-limits before anyone starts. An assistant that reads your infrastructure configuration or your secrets is a decision your whole team should make, not one developer. The privacy section below covers what to check.
Pros and cons
What it gets you
- Multi-file refactors that would otherwise take an hour of grep and edit
- Test scaffolding and fixture boilerplate, which is the cleanest ROI
- Fast answers to “where does this behaviour actually live” questions
- Dependency migrations, mechanical API adaptations, and a first draft for unfamiliar code that you then refine
What it costs
- Review time, which does not shrink even though generation time does
- Plausible code that encodes the wrong rule, found late or not at all
- Scope creep in diffs you did not ask for
- A real command-execution risk surface in terminal agents, plus subscription cost that scales with seats and variable usage for agent tiers
Who this is for
This is for professional developers on an existing codebase — the kind of person who spends their day reading unfamiliar modules, updating call sites, and writing tests for code other people wrote. It is also for teams that have already decided their privacy posture and want the productivity, because the tools will not set that posture for you.
It is a poor fit for someone learning to code from scratch, because the assistant will happily produce a correct-looking answer that hides the concept they were trying to learn. It is a poor fit for a codebase with heavy domain logic and no written rules, because the models will confidently guess those rules wrong. And it is a poor fit for regulated environments until someone has explicitly written down what the tools may read.
FAQ
Q: Do AI coding assistants actually save time? A: On the tasks where they are strong — boilerplate, test scaffolding, mechanical refactors across many files, explaining unfamiliar code — yes, substantially. On work where correctness depends on domain knowledge you have not written down, they produce plausible code that needs a careful human read, and the review is the new bottleneck.
Q: Which one is best for a large existing codebase? A: Terminal-driven agents with repository-wide search beat inline autocomplete, because they read the code before they write it. Inline completion is fast but only sees the file you have open, which is exactly the wrong scope for work that crosses modules.
Q: Do these tools train on my private code? A: It depends entirely on the plan and the settings, and the default is not always the safe one. Business and enterprise tiers generally offer explicit no-training terms, while individual plans may include your code unless you opt out. Read your own agreement rather than trusting a marketing summary, and check the retention settings before you commit.
Q: Is it worth paying for two of them at once? A: For a professional developer, often yes — one for inline completion while you type and one terminal agent for multi-step work, since they occupy different moments. For a team, the cost is per seat and the question is whether the review time you save exceeds the licence.
Q: How do I stop the assistant from making changes I did not ask for? A: Give it smaller, more explicit instructions and require it to show a plan before editing. The most productive setup I have used is a read-only first pass — the agent investigates and explains, and only writes when I approve the specific change.
FAQ
Do AI coding assistants actually save time?
On the tasks where they are strong — boilerplate, test scaffolding, mechanical refactors across many files, explaining unfamiliar code — yes, substantially. On work where correctness depends on domain knowledge you have not written down, they produce plausible code that needs a careful human read, and the review is the new bottleneck.
Which one is best for a large existing codebase?
Terminal-driven agents with repository-wide search beat inline autocomplete, because they read the code before they write it. Inline completion is fast but only sees the file you have open, which is exactly the wrong scope for work that crosses modules.
Do these tools train on my private code?
It depends entirely on the plan and the settings, and the default is not always the safe one. Business and enterprise tiers generally offer explicit no-training terms, while individual plans may include your code unless you opt out. Read your own agreement rather than trusting a marketing summary, and check the retention settings before you commit.
Is it worth paying for two of them at once?
For a professional developer, often yes — one for inline completion while you type and one terminal agent for multi-step work, since they occupy different moments. For a team, the cost is per seat and the question is whether the review time you save exceeds the licence.
How do I stop the assistant from making changes I did not ask for?
Give it smaller, more explicit instructions and require it to show a plan before editing. The most productive setup I have used is a read-only first pass — the agent investigates and explains, and only writes when I approve the specific change.