Pedantically, the default on both versions of Rocky is no tables.
It is the firewalld.service that on start creates (some) tables.
If you do start without FirewallD and run iptables -L to “read”, you also get tables – the tables/chains that mimic the builtin chains that the legacy iptables had in RHEL 7.
Rocky 8 had the familiar chains to ease transition, particularly for services that did still inject rules themselves, with iptables.
A feature of nf_tables in the kernel that FirewallD started to use. In a point update, not on original RHEL 9.0.
Each table has owner. A process that owns the table. In addition to limiting writes to the table, the table can also be auto-removed when the owning process quits.
The tables are most likely created by libvirt service, not the guest. It is totally possible that you start an another guest a bit later, so erasure of the tables could be wasted effort. Furthermore, libvirt might not set auto-removal.
Besides, a mere table should not use many cycles. It is the chains bound to hooks that force packets to visit those chains.
OK, so it makes sense that RHEL8 wants to stay close to iptables. The point update where they got rid of the RHEL7 tables, I must have missed it. I can see why libvirt would want to keep tables around, but I just don’t like things that fail to do clean up. Actually, I have not worked out which part of libvirt creates the tables; it’s using modular daemons now,
With firewalld, it’s easy to put everything back to “normal” by reloading, but I don’t know how to do it with with nft; e.g. if I create a table, chain, rule using nft, and it goes wrong, how can I reset it? I think ‘flush’ empties the whole thing?
So looking at this again, in the context of the changes from RHEL8 to RHEL9, it seems it would be much harder to use ‘nft’ on RHEL9. In the RHEL8 example above, I was able to use a single ‘nft’ command to add a rule. (It worked because firewalld had set up all the tables for me). But on RHEL9, I would have to create my own nftables (probably getting it wrong), and even then it might conflict with firewalld?