Digging into the source code it seems like Akka allocates a fixed buffer if the size is "small enough" (n <128 || n < ActorMaterializerSettings.maxFixedBufferSize), otherwise it first allocates a fixed buffer with 128 slots, but then falls back on a linked list if the actually used size grows beyond that.
However, ActorMaterializerSettings.maxFixedBufferSize = 1000000000 by default, so a fixed size buffer of the size specified will "always" be created.
Reading the documentation, that value can be configured with akka.stream.materializer.max-fixed-buffer-size but it's used for many different streams, so it's unclear how safe it is to change that value.
I guess I'll stick with over-allocating buffers. One question still remains:
is there a risk of incoming messages getting dropped?