According to user Otto, who provides a good explanatory answer to a similar question, you can safely call wp_get_post_terms() a number of times because Wordpress's internal query caching system is primed before the loop begins, and subsequent calls to wp_get_post_terms() will hit the cache rather than the query:
Post meta information is automatically cached in memory for a standard
WP_Query (and the main query), unless you specifically tell it not to
do so by using the update_post_meta_cache parameter.
Therefore, you should not be writing your own queries for this.
How the meta caching works for normal queries:
If the update_post_meta_cache parameter to the WP_Query is not set to
false, then after the posts are retrieved from the DB, then the
update_post_caches function will be called, which in turn calls
The update_postmeta_cache function is a wrapper for update_meta_cache,
and it essentially calls a simple SELECT with all the ID's of the
posts retrieved. This will have it get all the postmeta, for all the
posts in the query, and save that data in the object cache (using
However, his explanation didn't provide much by way of code to prove it, nor any actual query analysis of a page. So, just to be sure, I fired up the Query Monitor plugin and ran some tests on my own archive pages. It is showing that I am calling wp_get_object_terms() (always fired by wp_get_post_terms() and the actual query caller) 85 times, which might seem like a high number. However, each call takes ~.0005 seconds. So all told they total to about .05 seconds. My total query time for all 400-500 queries on the page (I am using the somewhat bloated Themify Magazine theme) is 0.36 seconds.
So I guess the lesson is (assuming my bloated theme didn't do something crazy like interrupt WP's internal caching): simple queries run by wp_get_post_terms() are so inconsequential that if you're only firing them off a handful of times, they show scant degradation in performance. However, if you are hungry to optimize, it looks like Wordpress is not priming any cache for this data up front as user Otto has indicated.