I thought surely an integer could be inlined into the interface, I thought Go used to do that. But I tried it on the playground, and it heap allocates it:
Basically, anything that isn't a thin pointer (*T, chan, map) gets boxed nowadays. The end result is that both words of an interface value are always pointers [1], which is very friendly to the garbage collector (setting aside the extra allocations when escape analysis fails). I've seen some tricks in the standard library to avoid boxing, e.g. how strings and times are handled by log/slog [2].
https://go.dev/play/p/zHfnQfJ9OGc