Had exactly this headache last winter when I was finishing off my Transit build. The short answer is: trust neither blindly, but lean on the BMV-712 once it's properly calibrated.
Here's the thing — your BMS is typically working off cell voltages and making educated guesses about capacity. It's reactive. The Victron BMV is doing proper coulomb counting, tracking every amp flowing in and out, which over time gives you a far more accurate picture of actual state of charge.
The catch is that the BMV needs a synchronisation point to anchor itself. That's usually a full charge cycle where the battery genuinely hits absorption and the tail current drops low enough that the BMV registers it as 100%. If you've not set your charge parameters correctly in the BMV settings — particularly the charged voltage, tail current, and charged detection time — it'll drift and you'll see exactly the discrepancy you're describing.
My setup runs a 280Ah Fogstar Drift LiFePO4, and I had a solid 8% difference between the two when I first wired everything up. After tweaking the synchronisation settings and letting it run through a couple of proper full cycles, they came within 2-3% of each other. That's about as close as you'll realistically get.
Worth double-checking:
- Peukert exponent (set to 1.05 for LiFePO4, not the lead-acid default)
- Charge efficiency factor (98-99% for lithium)
- All loads running through the shunt, nothing bypassed
What BMS are you running? Some of them are genuinely terrible at SOC reporting — JBD units in particular can be wildly optimistic.