For what I understand, the balance of a Bitcoin address is the total sum of UTXOs of that address in the entire blockchain. The current size of the blockchain is around 350GB. How is the total sum of UTXOs for a specific address calculated quickly? I imagine looping over every transaction in the entire blockchain and comparing the UTXO with the given address takes a lot of time. Does the calculation of the balance of a Bitcoin address work like that? And do miners repeat this process for every transaction to check if the available balance of that address enough?
At the protocol level, Bitcoin has no concept of "balances" or "addresses", and their common interpretation isn't relevant during verification.
Every transaction spends "coins" and reforges them into new "coins" (called UTXOs). Every UTXO has a value (in number of satoshis) and an locking script. UTXOs are always spent in their entirety. If you only have a 1 BTC UTXO and want to send 0.1 BTC to someone, your wallet will under the hood create a transaction that has one input (your 1 BTC UTXO) and two outputs (one 0.1 BTC UTXO with an locking script created from the receiver's address, and one 0.9 BTC UTXO with an locking script you can unlock yourself). From a protocol perspective, there is nothing special about this UTXO that goes back to yourself (called a "change output") - it's just another UTXO.
Transaction explicitly identify which previous coins they're spending, based on the txid that created them, not based on the locking script. So it doesn't matter what the sum of the values of UTXOs with a particular locking script is; coins are spent when they're mentioned as an input in another transaction. That means the only thing that matters is:
- Do the input UTXOs exist?
- Is the sum of the input UTXO values (whether they have the same locking script or not) not less than the sum of the values of the newly created UTXOs.
Now, sites like blockexplorers do show balances. They're a higher-level - and misleading - abstraction. They do this by simply maintaining an index per address of all transactions that have the script corresponding to that address as locking script, and all transactions that spends such outputs.
Wallets for privacy reasons construct new addresses all the time (typically one per incoming transaction), as there is no cost to creating more addresses. Looking at it from a per-address perspective is therefore misleading, and has caused people to lose money (when they think "X is my address, I only need its private key" - you need the keys to all addresses, even change addresses, your wallet uses).