Why Offshore Development Quality Is So Bad (It’s the Contract)

The pull request is 1,400 lines. It adds a class called OrderHelperService that duplicates about 60% of a service you already have, special-cases a customer ID in a conditional, and ships zero tests. The commit message is “fix as per ticket #4821”. You leave four comments. Two days later the same PR comes back with the comments marked resolved and nothing meaningfully changed, and the delivery manager asks whether the milestone can be signed off because it is holding an invoice.

You have now had a version of this conversation at three companies. And the private thought you have not said out loud in a retro is: why is the quality of outsourced offshore development work so consistently bad?

Here is the answer, and it is not the one the thread usually gives. The code you are reviewing is an accurate, rational output of the commercial contract you signed. Offshore development quality is set mainly by the delivery model you bought, not by where the developers live. Fixed-bid scope, pyramid staffing, utilisation targets, ticket-shaped requirements and a 12-hour question latency will produce that exact pull request whether the team is in Pune, Kraków, Manila or Milwaukee. Change those variables and the same engineers produce different code. That is a testable claim, and there is decent evidence for it, which I will get to.

The contract is the architecture

Start with fixed bid, because most bad offshore code traces back to it.

In a fixed-price engagement the vendor’s margin is the gap between the agreed price and the hours actually burned. That single fact does more to shape your codebase than any tech lead. Every hour spent on work that is not in the acceptance criteria is margin the vendor destroys voluntarily. Refactoring has no invoice line. Neither does deleting dead code, tightening an interface, writing a migration you will need in six months, or telling you that the ticket you wrote is a bad idea.

Watch how that plays out in the specific PR above. The right move is to extract the shared logic out of the existing service and have both callers use it. That touches code another squad signed off in a milestone that is already closed, which means regression risk on scope the vendor has been paid for, which means a QA cycle nobody budgeted. Copy-pasting 400 lines carries none of that risk and takes an afternoon. Duplication is the locally optimal choice for the person doing it. They are not lazy. They are responding correctly to the incentive you handed them.

The same logic explains the change-request economy. Ambiguity in a fixed-bid statement of work is an asset for the seller, so specs get written narrow on purpose. When your requirement says “export the report as CSV” and says nothing about 100,000 rows, the streaming implementation is not in scope, and the vendor is commercially correct to load it all into memory and raise a CR when it falls over in production. You will be angry. They will point at the document. Both of you will be right.

Fixed bid is not evil. It is the right instrument when scope is genuinely knowable in advance: a data migration, an integration with a documented API, a rebuild of something that already exists. It is the wrong instrument for product development, because it converts every act of engineering judgement into an unfunded liability.

The pyramid is the product

In the sales call you met a principal engineer who asked sharp questions about your event model and made you feel good about the decision. She exists. She is on the account. She is also allocated at roughly ten percent across six accounts, and the SOW lists her as “Solution Architect (part-time)” in an annex you skimmed.

The people writing your code are four engineers with one to three years of experience and a team lead with five. This is not a bait and switch, it is arithmetic. IT services firms price a blended rate built from a deliberate mix of junior, mid and senior staff. If a senior costs three times a junior, the blended rate you negotiated hard for mechanically determines the ratio. You optimised the rate. The rate chose the pyramid. Those are the same decision.

Then there is the bench. A services P&L lives on utilisation, and an unbilled engineer is a pure cost. So when a large deal closes and needs plausible CVs on day one, your strongest person is the obvious candidate to move, and the seat on your account gets filled by whoever just rolled off something else. Nobody is punishing you. Somebody hit a staffing constraint on a Tuesday.

This is invisible in every metric you are shown, because internal redeployment is not attrition. The person did not leave the company. They left your codebase, which for you is the same event.

What the attrition numbers actually say

TCS reported last-twelve-months attrition in IT Services of 13.6% for the quarter ended 30 June 2026, on a workforce of 593,798. Wipro reported voluntary attrition of 13.9% on a trailing twelve-month basis for the same quarter. Infosys was widely reported at around 13% in that period. Those are the calm years. In FY2022, during the post-pandemic hiring frenzy, The Register’s summary of the big four’s own published results put the average at 22.7%, with Infosys at 27.7%, Wipro at 23.8%, HCL at 21.9% and TCS at 17.4%.

Translate 13.6% into your world. A six-person pod loses roughly one person a year at that rate, and that is before rotation, promotion moves and project reassignment, none of which appear in the attrition line. At 2022 rates you were losing someone about every five months. Now ask what leaves with them.

Not the code. The code is in git. What leaves is the reason the retry loop has a three-second delay instead of one, the memory of the incident in March that caused it, the knowledge that the finance team’s CSV import silently fails on a BOM, and the understanding that your biggest customer has a contractual SLA that makes one endpoint different from all the others. None of that is in a ticket. In a product team it lives in people who have been there four years. In a project team with annual turnover it evaporates, and the replacement engineer, given no context and a deadline, writes a defensive special case. That is where OrderHelperService comes from.

Tickets without the why, and review as theatre

Most offshore arrangements sever the engineer from the customer completely. Requirements arrive as tickets, written by a business analyst who talked to a product owner who talked to you. Three lossy hops, and what gets lost at every hop is the reason. A developer who knows this export goes to an auditor who will open it in Excel 2016 writes different code than one who knows only that the ticket says CSV.

Layer a missing definition of done on top. If nobody wrote one, “done” defaults to the cheapest defensible interpretation: the acceptance criterion was demonstrated on a screen share. Not tested. Not instrumented. Not documented. Not verified at production data volumes. Not safe to deploy on a Friday. Every one of those properties is unpaid work unless it is written into the contract as a condition of payment, and if you have not written it down you have silently agreed to buy the cheap version.

Which brings up internal code review, and I want to be blunt here. Vendor-side review is frequently theatre, and the reason is structural rather than moral. The reviewer reports to the same delivery manager as the author, and that manager is measured on milestone dates and margin. A review that blocks a merge costs the reviewer’s own team days and makes them the person who missed the date. Approval is the path of least resistance, and three LGTMs in a row is what you get. Any review chain where every participant shares one P&L will converge on this. Yours would too.

The 24-hour question

The most expensive thing about a 10.5-hour time difference is not the meeting scheduling. It is that a question which would take 90 seconds across a desk takes a full working day to resolve, and a follow-up question takes another.

There is real research on this rather than just vibes. Herbsleb and Mockus studied change requests in two departments of a large telecoms software organisation and published the results in IEEE Transactions on Software Engineering in 2003. Across 2,227 modification requests in one department and 4,974 in the other, work that was distributed across sites took about two and a half times longer to complete than comparable same-site work: roughly 5 days versus 12.7 in the first department, 7 versus 18 in the second. Their explanation was mechanical rather than cultural. Distributed changes pull in more people, and more people means more delay.

The second-order effect is the one that damages your codebase. An engineer who has learned that asking a question costs 24 hours of visibly blocked time, on a milestone their lead is tracking, stops asking questions. They guess. They pick the interpretation that is easiest to implement and defensible against the ticket text. Every strange piece of offshore code you have ever read is, somewhere underneath, a guess that nobody could afford to check.

The inconvenient counter-evidence

If offshore engineering were inherently poor, distributed development would show up as a quality defect in large codebases. It largely does not.

Microsoft Research ran the obvious study. Bird and colleagues examined post-release failures across more than 3,000 binaries in Windows Vista, built by nearly 3,000 developers spread across sites, and published it at ICSE 2009. Their finding was that distributed development had little to no effect on post-release quality; the raw difference shrank to about 4.6% and was not statistically significant once team size was controlled for. Their explanation is the line that should be printed on the wall of every procurement department: organisational differences are much stronger indicators of quality than geography. A geographically distributed but organisationally unified team outperforms a colocated but organisationally fragmented one.

That matches what I have seen, and probably what you have seen. There is superb engineering happening in Bengaluru, Hyderabad, Chennai, Kraków, Lisbon and Ho Chi Minh City right now, in setups that share a short list of traits:

  • They are product teams, not project teams. The team owns a service, not a milestone, and is still there when it breaks at 2am.
  • Engineers talk to actual stakeholders, without a business analyst acting as a lossy relay.
  • There is end-to-end ownership: they design, build, deploy, monitor and get paged. The feedback loop from bad decision to personal consequence is closed.
  • Retention is measured in years, so institutional memory accumulates instead of resetting.
  • They are on the same definition of done, same repo, same on-call rotation as everyone else, with no separate vendor quality bar.

Notice that none of those five is about nationality, English fluency, education or time zone. All five are about how the work was bought.

What you can actually change on Monday

Change the contract shape first. Move from fixed-bid deliverables to a dedicated team on a time-and-materials or capacity basis, where you direct the backlog. This single change removes the incentive against refactoring, removes the change-request fight, and makes questions free instead of expensive. Everything else on this list is easier afterwards.

Interview the humans, not the company. Run your normal technical interview loop on every named engineer, and reject people. A vendor that refuses this is telling you the roster is fungible, which is the whole problem in one answer. Ask for CVs with names, allocation percentages and the notice period in their employment contract.

Insist on named, long-term staff and price the churn. Put minimum engagement terms in the agreement: twelve months per named engineer, 30 to 60 days’ notice before any rotation, a two to four week paid overlap for handover, and your right to interview the replacement. If a vendor cannot commit to that, you are buying capacity, not a team, and you should price accordingly.

Own the definition of done yourself. Write it, make it a condition of payment, and keep it short enough that nobody can plead confusion: tests at the level you specify, passing CI, documentation in the repo, instrumented, reviewed by one of your engineers, deployed to staging by the author. The last two items dismantle the review-theatre problem, because a reviewer outside the vendor’s P&L has no reason to wave anything through.

Buy overlap hours explicitly. Four hours of genuine overlap is the difference between a 10-minute clarification and a 24-hour block. Pay for it, staff it as part of the working day on both sides rather than as an imposition on one, and accept that both sides give up something.

Give them the why, every time. Stakeholder access, incident history, the customer calls, the reason this endpoint is different. Free, unglamorous, and the highest-leverage item on this page.

Treat them as team members. Same standup, same repo, same Slack, same on-call, same retro, named in the same team channel. If your internal engineers say “us” and “the vendor”, you have a fragmented organisation, and Bird’s data says that predicts your defect rate better than a map does.

Questions worth answering before the next contract

Is time and materials always better than fixed bid? No. Fixed bid works well where scope really is knowable: a migration, a well-specified integration, a port. It fails on product work, where the requirement changes as you learn, and where every improvement to the design is money out of the vendor’s pocket.

Would paying a higher rate fix this? Only partly. A higher blended rate buys a better pyramid mix, which is real. It does not change fixed-bid incentives, rotation off your account, ticket-shaped requirements or review conflicts. Model first, then rate.

How do I detect the pyramid during a sales process? Ask three questions and watch the reaction. Which named individuals will write code, and at what allocation? What was this team’s turnover in the last 12 months? Can I interview each of them and decline? Vendors selling a dedicated team answer all three flatly. Project shops get uncomfortable at the second one.

Is nearshore the answer instead? Nearshore buys overlap hours, which genuinely helps. It does not buy a different commercial model. A fixed-bid project shop three time zones away produces the same pull request, just earlier in your day.

If you want the other model

AB7 Solutions works on the staff-augmentation side of this rather than the project-delivery side: named, retained engineers who join your standups, your repo and your definition of done, interviewed by you before they start, with the notice periods and handover overlap written into the agreement so a rotation is never a surprise. If you want to talk through what your current contract is actually incentivising before you renew it, call +1 321 341 7733, email ab@ab7solutions.com or director@ab7solutions.com, or read more at www.ab7solutions.com. If the honest answer is that your scope really is fixed and a project shop is fine, we will say so.

Sources: TCS Q1 FY2027 results (LTM IT Services attrition 13.6%, headcount 593,798); Wipro results, quarter ended 30 June 2026 (voluntary attrition 13.9% TTM); The Register summary of FY2022 attrition across TCS, Infosys, Wipro and HCL; J. D. Herbsleb and A. Mockus, “An Empirical Study of Speed and Communication in Globally Distributed Software Development”, IEEE Transactions on Software Engineering 29(9), 2003; C. Bird et al., “Does Distributed Development Affect Software Quality? An Empirical Case Study of Windows Vista”, ICSE 2009.

Leave a Comment

Your email address will not be published. Required fields are marked *