Working with Claude Code on a high-latency or low-bandwidth connection introduces significant challenges, particularly for the iterative "chat with code" workflow. The primary bottleneck is the round-trip time for each context submission, which includes your entire codebase or relevant files.
I've found two practical approaches mitigate this. First, aggressively limit the context you send. Use `.claudeignore` patterns to exclude build artifacts, dependencies (`node_modules`, `vendor`, `__pycache__`), and generated files. Second, structure your prompts to be self-contained and anticipate follow-ups. Submit a minimal, focused code snippet with explicit, multi-part instructions in a single query to reduce back-and-forth.
```bash
# Example .claudeignore
node_modules/
vendor/
*.pyc
__pycache__/
dist/
*.log
.DS_Store
```
For larger refactors, it's more efficient to work offline using local tools (linters, formatters, `sed`) and only use Claude Code for targeted, high-value reviews on the final diff. The latency cost is only paid once.
I'm a security lead at a fully remote fintech startup of about 80 people, and my team manages our ISO 27001 and SOC 2 Type II compliance. We've been using Claude Code heavily for the past six months to review security-related code changes, audit scripts, and Terraform configurations before deployment.
If your primary constraint is a slow or high-latency connection, the "best" approach isn't a different tool, but a fundamental change in how you interact with any AI coding assistant. The core issue is the iterative prompting loop, so you have to engineer your process to minimize round trips.
1. **Context pruning is non-negotiable.** Your `.claudeignore` example is a good start, but you need to go further. In my environment, I also explicitly limit the total number of files sent per query using command-line tooling. A quick script counts lines in the proposed context payload and rejects it if it exceeds a threshold (I use 4000 lines as my hard cap). This forces surgical precision in file selection.
2. **Batch your thinking into a single prompt.** This is the most critical tactic. Write your prompt as a standalone work order. Include the specific files, the exact change you want, the rationale, and ask for the output in a single, complete diff format. For example, "Given the following two files, modify the authentication function to add rate limiting using the token bucket algorithm. Output only the unified diff. Here is File A and File B." This often requires you to do the design work upfront, offline.
3. **Shift left to local tooling for iterative work.** For refactoring or exploring patterns, I use `rg` (ripgrep), `sed`, and AST-based linters locally to get 80% of the way there. I then use Claude Code only for the final review of that diff, asking for security or logic flaws. This turns Claude into a high-value, one-time validator instead of a pair-programmer, which drastically cuts the number of slow requests.
4. **Understand the actual latency cost.** In my last shop with a high-latency satellite link (around 600ms RTT), each round trip with Claude Code added about 3-5 seconds of pure waiting, not counting processing. Submitting three back-and-forth prompts for a single task could waste 15-20 seconds. Structuring work into one-shot prompts saved literal hours per week.
My pick is to stick with Claude Code but adopt a strict "single-shot" prompting discipline. It wins on code understanding quality for security review, which is my primary use case. If your use case is exploratory debugging or open-ended design, the latency will be frustrating. To make a clean call, tell us whether you need it mostly for writing new code or for auditing existing code, and what your typical round-trip latency actually measures in milliseconds.
—at
Agree on limiting context, but I'd add you need to explicitly select files per session, not just rely on `.claudeignore`. Dragging an entire project folder, even filtered, can still send too much over a slow line.
For Terraform work, I paste just the specific module or resource block I'm troubleshooting. The surrounding config rarely matters for the immediate problem.
Your offline point is key. Do the heavy lifting locally, use Claude for the logic review once.
—cp
Your `.claudeignore` strategy is sound, but it's often not enough for monorepos or projects with deeply nested artifacts. I'd argue you need to combine it with a pre-submission script.
For a Jenkins pipeline, you could stage a step that tars only the relevant source paths before the assistant session, excluding patterns dynamically based on the task. This enforces the filter at the filesystem level, preventing any accidental drag-and-drop of the full context.
```groovy
stage('Prepare Context') {
steps {
sh '''
tar -czf context_for_review.tar.gz
--exclude='node_modules'
--exclude='vendor'
--exclude='*.pyc'
--exclude='dist/'
src/ config/
'''
// Then only upload or reference the tarball
}
}
```
It's a more deterministic approach than relying on the UI's file picker.
Commit early, deploy often, but always rollback-ready.
That Jenkins stage is a solid automation approach for CI contexts, especially to prevent human error. I've used a similar pattern in GitHub Actions to prune context before a review step.
One caveat: the tarball itself can become large if you're not careful with the included paths. For a monorepo, I'd add a step to first list the filtered files and count them (or check total size) before creating the archive. It adds a bit of safety.
I'd also consider using `rsync` with an exclude file for more complex patterns, as it can be easier to maintain than a long `tar` command line.
```bash
rsync -av --exclude-from='.claudeignore' --prune-empty-dirs src/ config/ ./temp_context/
tar -czf context.tar.gz -C ./temp_context .
```
This keeps the exclusion logic centralized.
Pipeline Pilot
Rsync with a central exclude file is a cleaner approach for sure. But you're just moving the bottleneck. Now your slow connection is chewing through an archive creation step before it even starts the upload to Claude. Ever timed a `rsync -av` on a huge codebase over a high-latency link? It's its own special kind of pain.
And maintaining that `.claudeignore` file? It becomes another piece of config drift. Someone adds a new `dist/` folder somewhere and forgets the pattern, your tarball balloons again. 😒
Honestly, the whole CI automation angle feels like over-engineering for a simple problem. If your connection is that bad, maybe just... don't use an AI assistant that needs the whole kitchen sink for every query?
been there, migrated that
Agree completely on the offline-first strategy. It's the only sane way when each round trip feels like mailing a letter.
But that "self-contained prompt" advice is the real gold, and it's harder than it sounds. You're basically asking people to write a mini-spec before they even start chatting. Most devs (myself included) want to think out loud *with* the tool. Breaking that habit on a bad connection is painful but necessary. It forces a kind of clarity that's probably good for you, like eating your vegetables.
The .claudeignore is a good crutch, but I've seen it create a false sense of security. You prune the obvious junk, then absentmindedly paste 800 lines of a monolithic service class because "it's all relevant." The bandwidth gods weep.
Demos are just theater. Show me the real workflow.
You nailed the core habit shift. Thinking out loud with the tool is the default, and fighting it feels wrong.
But that's exactly where CI discipline applies. I treat prompt crafting like writing a Jenkinsfile: define the inputs, stages, and expected output before hitting "build". Saves time overall, even if it feels slower upfront.
The false security of .claudeignore is real. It's like having a good .gitignore but still git adding everything manually. The filter works, but you still have to be smart about what you stage.
Totally feel that CI discipline analogy. It's like setting up a Zapier zap - you map the triggers and actions upfront, even though clicking "test" is tempting.
But I've found the "define output" part is where people still get stuck. They'll write a clear prompt for "refactor this function," but forget to specify the exact formatting or test cases they want included. So Claude gives a perfect refactor... in a style that doesn't match the rest of the codebase, triggering another round trip.
The .claudeignore comparison to git staging is spot on. Maybe we need a "claude add -p" equivalent - a way to interactively review what snippets we're about to send before we commit to the upload.
Automate everything.
The vegetable analogy cuts deep because I've been there. That forced clarity is valuable, but it also highlights why so many teams bounce off these tools when the network's against them. You're suddenly asking for waterfall-style planning in a tool built for agile conversations.
The real false security isn't just in the .claudeignore. It's in believing the "self-contained prompt" is a single skill. It's actually two: knowing what you want, and knowing how much context Claude actually needs to get there. Most devs fail at the second part. They write a great spec, then attach the whole monolithic service class "just in case," because they don't trust the AI to work with less.
Maybe we're solving the wrong problem. If your connection makes thinking out loud impractical, are you even getting the core benefit of the assistant anymore? You're just using a very expensive, slow code generator.
You've pinpointed the critical tension. The "knowing how much context is needed" skill is largely about understanding the assistant's operational boundaries. It's a form of architectural contract design. You wouldn't pass an entire database to a microservice, you'd define a precise API. The same principle applies.
Many developers attach the monolithic class because they lack a mental model of what constitutes a sufficient interface for the task. Is it the function signature and its immediate callers? Is it the data schema of the involved objects? This uncertainty breeds over-provisioning. The solution isn't just better discipline, it's developing a heuristic for context scoping, similar to defining service boundaries in a distributed system.
Your final question is the most pertinent. If the network necessitates a waterfall prompt, you've lost the conversational, exploratory core of the tool. You're then better off with a static analysis linter or a local code generator, which are designed for that exact workflow. The tool's fundamental value proposition is degraded.
—BJ
Your point about "forced clarity" being good for you resonates. The pain of a slow connection does enforce a stricter pre-planning phase that can improve the quality of the interaction overall. It transforms the process from conversational debugging to a form of documented specification, which often yields better, more maintainable outcomes.
The comparison to .gitignore is useful. The real parallel is the discipline of `git add -p` - the interactive staging. A .claudeignore automates the exclusion of noise, but doesn't guide the positive selection of what's essential. The failure mode you describe, pasting the monolithic class, is akin to `git add .` after you've set up a perfect .gitignore; you've avoided the junk folders, but you're still committing far too much.
Developing that skill for "knowing how much context is needed" is the crux. It's less about the tool and more about learning to define a precise cognitive interface for the task at hand.
Migrate slow, validate fast.
Aggressively limiting context sounds great on paper, but let's be honest: you're just optimizing the wrong layer. The real issue is that the "chat with code" workflow is fundamentally broken for high-latency environments, no matter how many dotfiles you sprinkle on it.
Your offline-first suggestion is the only part that holds water. Using local tools for the grunt work is just admitting the AI isn't the right tool for the job under those conditions. Why are we bending over backwards to prune tarballs for a service that's supposed to make us faster? If you need a linter and `sed` anyway, you've already lost the plot.
And that final line about paying the latency cost only once for a review is pure fantasy. Anyone who's done a real refactor knows there's never just "one final diff." There's always that one edge case, that one formatting nit, that one last question. You'll be right back in chat prison waiting for the next round trip.
Trust but verify
The CI analogy is clever, but I think Jenkinsfiles are a perfect example of why this discipline fails in practice. You write a perfect, staged pipeline, then someone triggers it with a 200GB workspace because "the job might need it." The spec is pristine, but the execution cost is still insane.
Your git staging comparison is where the real cost lives, though. You can `git add -p` all day, but the overhead of manually reviewing every hunk for a large change is the same bottleneck. The time you spend meticulously crafting that perfect, minimal prompt on a slow link could have been spent just... fixing the code locally.
Maybe the habit shift isn't towards CI discipline, but towards accepting that some tools aren't cost-effective under certain constraints, no matter how well you optimize their use.
Cloud costs are not destiny.
Your point about using offline tools for the bulk work and reserving Claude for a review of the final diff is pragmatically sound. However, that approach hinges entirely on the quality and stability of your local changes. In a complex refactor, the "final diff" is often an iterative discovery process itself.
The `.claudeignore` patterns you listed are essential, but they only solve the noise problem. The harder part is the signal. The strategy breaks down when the targeted review reveals a fundamental architectural issue embedded in a module you didn't include for context. Then you're forced into another high-latency cycle of "here's the new relevant code," defeating the single-review premise.
This pushes the discipline further upstream: you must be confident your local refactor is not just syntactically correct, but architecturally coherent before you pay the latency cost for that review. That's a very high bar. It often means simulating the AI's "context-aware" analysis mentally, which is the very cognitive load the tool is meant to reduce.