The behavior you describe is when the HD is created from within a logic block and the logic block is not part of a NATE container (is ‘live’).
HD Structures are the logic block construct in question. HD structure’s original intent was to
- obscure the platform’s technique to associate a header record to the details it contains
- make the persistence of the details automatic - if logic alters a detail record after creation/insertion that detail automatically persists without a need of an Update Record action.
While HD structures accomplish those goals, the second has a significant performance penalty - which your observations underline. This is especially true when interacting with HD-related tables that have triggers and are running live.
Option 1 - run the logic within a NATE container. All triggers related to interaction are deferred until the container commit. This is how the UI works with HDs.
Separate from logic block’s HD structure construct, HDs also have behaviors associated with common fields and have post-triggers. If your use case involves either of those, you do need to interact with the HD as an HD - not as the header table and the detail table(s). That forces you into option 1. You need the HD structure to get the associated HD behaviors.
Option 2 - do not use HD structures. This is my personal favorite because it avoids all implicit updates, which are often more than you want/need. It puts you in the driver’s seat. If you do not use HD structures, you are responsible for associating the detail to the header by assigning the nwHeaderId correctly and any intermediate updates are also your responsibility. In the case you described this would execute the insert triggers on the header as it was inserted and the insert triggers on each detail as they are inserted. The logic becomes independent mutations to the header and the detail, not mutations to the HD, which is why the triggers re-run as you described things - you are touching the HD, which involves both header and detail(s).
Regardless of which you choose, you do not need the Save HD action, which your words imply you have done unless this is part of an action block, which I assume it is not since there does not seem to be a NATE container in play. As stated above, the HD is automatically updating itself. The only time you need a Save HD action is when an HD structure in an action block or when a Temp HD structure is used and you must tell the system you mean for the HD to “become permanent”.