Collect all record IDs from Trigger.new into a Set<Id> before making any SOQL queries, then issue a single query with a WHERE Id IN :idSet clause outside any loop
Build Map<Id, SObject> lookups from query results so you can access related data per record in O(1) without nested queries
Accumulate all records requiring DML into a List<SObject> or List<SObject> update list inside the loop, then perform a single DML statement after the loop completes
For cross-object field updates initiated by a trigger, query parent or child records in a single batch query before the processing loop begins
Use Limits.getQueries() and Limits.getLimitQueries() for diagnostic logging during development to catch limit approach early
Test with a data factory that inserts 200 records in a single DML call to verify the trigger stays within limits at maximum batch size
Known gotchas
Each @future callout or queueable job launched from a trigger counts toward the async job governor; launching one per record in Trigger.new will hit the per-transaction limit immediately
Aggregate queries (SELECT COUNT() or GROUP BY) each count as a SOQL query against the 100-query limit, so avoid them inside trigger context loops
DML on records in Trigger.new within an after trigger context requires a separate list — you cannot directly DML the trigger records themselves in an after context without re-querying
Give your agent this knowledge — and 200+ more routes
One MCP install gives any agent live access to the full route map, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp