Based on your post, I'm not sure you understand the TCP protocol and the OSI model.
TCP is a stream-based protocol and both ends have buffers. The writer lives at the a higher level, usually at the application level, and can write whatever they want and it gets buffered. The Transport layer (TCP) sends the messages across the Network layer (typically IP) as fast as it can. TCP does its magic of acknowledging the packets are all correct, and it comes out the other side as a stream when the data has arrived. TCP will control the flow automatically.
I had several clients sending messages to the server and at the server the code simply dumps all recv() bytes into a buffer--a stack basically in which a thread worker would pop() an element off the queue. Basically eliminating the surge effect brought about by a slow reader.
I'm not sure where your "surge" comes in.
The transport layer of TCP will buffer the incoming stream. That happens behind your back automatically. The size of the buffer is up to the system. (On Windows you can adjust the computed buffer sizes and maximum buffer sizes in registry values, but it is dangerous to do so without a deep understanding of how and what it affects.) Generally the read buffer on the receiving side is on the order of 8 kilobytes to 64 kilobytes which the system will manage automatically. If the program is "slow" and doesn't read from that buffer, once that buffer fills up TCP will tell the sender side to stop sending data. TCP will resume the transfer when there is space in the buffer. The data will still flow from one side to the other, reading it out as a stream of bytes in the same order it was sent.
It is typical to accumulate from the system's buffer into your own application buffer which can be whatever size you want. Once enough data has streamed through the pipe into your accumulator, you read that block into your program, remove it from the accumulator, and process it.
And if clients have different rates, I could simply adjust the tick() and go forward from there.
Connections always have different rates, and the flow rates are constantly changing over time.