I once worked with a holding company running eleven operating subsidiaries. Four were on NetSuite, three were on an old Sage 300 install nobody wanted to touch, two had migrated to Dynamics 365, and the remaining two were still closing books in Excel because the acquisition that brought them into the group happened eight months earlier and nobody had gotten around to onboarding them. Every month end, the corporate controller's team spent nine to eleven days chasing intercompany eliminations by hand.
That is the reality of intercompany reconciliation at most holding companies. The org chart looks clean in a PowerPoint slide. The general ledger reality is a patchwork of systems that were never designed to talk to each other, inherited through M&A rather than built on purpose.
Intercompany transactions have to net to zero across the consolidated entity. Subsidiary A sells inventory to Subsidiary B. Subsidiary B books a payable. Subsidiary A books a receivable. In theory those two entries match. In practice they rarely do, for reasons that have nothing to do with accounting error:
Every one of these is a small thing individually. Multiply it across eleven entities doing intercompany transactions with each other in a many-to-many pattern, and you get a reconciliation problem with a combinatorial number of pairings to check. At eleven entities, that's up to 55 unique intercompany relationships to tie out, assuming every entity trades with every other entity, which in a holding company with shared services, it usually does.
The instinct is to buy a big consolidation platform and force everyone onto one chart of accounts. That's the right long-term answer, and it's also an eighteen-month project that the CFO doesn't have time for right now. What works in the interim, and often ends up being the permanent solution because it's cheaper than a full ERP consolidation, is a reconciliation layer that sits above the individual ledgers.
The approach I've used: pull a standardized extract from each subsidiary's system, whatever that system is, into a common staging table. This means building a connector for each source, which for NetSuite is a SuiteQL pull, for Dynamics is an OData query against the Finance and Operations API, and for the Excel-based entities is a templated upload with validation rules that reject the file if required columns are missing or the intercompany account codes don't map to the master list.
Once everything lands in the same schema, you run matching logic on transaction pairs: same intercompany trading partner, same period, amount within tolerance after currency conversion at the agreed rate. Matches within tolerance auto-close. Everything outside tolerance gets flagged with the specific dollar variance and routed to the accountant responsible for that entity pair, not a generic exceptions queue that nobody owns.
The tolerance logic matters more than people expect. If you set it too tight, you generate hundreds of false-positive exceptions from rounding on FX conversion. Too loose, and real errors slip through as false matches. I typically start with a tolerance of the lesser of $250 or 0.5% of transaction value, then tune it against three months of historical data before going live, because every holding company's error distribution looks different depending on transaction volume and currency mix.
The time savings get the headline, going from nine days to two or three. But the bigger win is what happens to the exceptions that remain. Before automation, every variance got equal attention because the team didn't have visibility into which ones mattered. After automation, the accountant sees a ranked list: a $40,000 variance between two entities that trade heavily with each other sits at the top, a $12 rounding difference sits at the bottom and often gets auto-written off under a materiality threshold the controller sets in advance.
I also build in a running audit trail on every auto-matched transaction pair, not just the exceptions. When the external auditors come in during year-end, they want to see the matching logic and tolerance rules that were applied, not just the final tie-out number. Storing that trail from day one saves weeks during the audit versus trying to reconstruct it after the fact.
Don't build the matching engine before you've fixed your intercompany chart of accounts mapping. I made this mistake on an early project: I built a solid matching engine, then discovered that three of the entities were using different account codes for the same type of intercompany transaction, which meant the engine couldn't even identify which transactions to compare against each other. Fixing the mapping took longer than building the automation. Do the mapping exercise first, even though it's tedious and involves a lot of meetings with people who don't want to be in them.
Holding companies that get this right treat intercompany reconciliation as infrastructure, not a monthly fire drill. It's not glamorous work, but it's the difference between a controller's team that spends its time on analysis and one that spends its time chasing spreadsheets.