Online multiplayer bandwidth timeout no free events issue

Looking for advice from someone experienced with online networking optimization in Unity.

My friend and I have been building a multiplayer game for the past year, which we have gotten Greenlit and we are now very close to release on Steam. The game is a 2d shooter that supports up to 4 players, who fight waves of enemies, buy weapons, blow stuff up, etc. It means there is a lot of on-screen action all the time, much of which is using Network Transform syncvar updates, sending Commands and ClientRpcs, etc.
We initially designed it to work only on LAN, but recently decided to go for online play using Unity’s matchmaking service. This has opened up a can of worms, as we found that we needed to totally re-optimize the game to account for the slower bandwidth. I have systematically made everything I can client-based: bullets, explosions and even the enemies now operate only on the clients, with only key pieces of data being sent over the network to keep things in sync. When running with the profiler on network operations and messages tend to peak at around 60 (it used to go up to over 300, which is when we would get timeouts).

However, despite all the optimization we are still faced with timeout disconnects when playing online via Unity’s multiplayer service. The error is usually a classic network timeout. In response to this I have changed the advanced settings in the Network Manager, increasing the disconnect thresholds. This resolved the timeout issue, BUT replaces it with another:
“no free events for long message in the event queue”

From what I have found online I think that this means I have created too much of a buffer for messages to pile up before being sent. The advanced settings I am currently using in the Network Manager, which are the best I can get to minimize (but not elminate) timeouts and the ‘no free event’ error, are:

Min Update Timeout: 30 milliseconds
Connection Timeout: 2000 milliseconds
Disconnect Timout: 6000 milliseconds
Ping Timeout: 2000 milliseconds

Reactor Max Rec Messages: 8192
Reactor Max Sent Messages: 8192

If these settings are set lower I generally get disconnect timeouts on clients when there’s a lot of action. If they are set higher I get no free events errors on the host, with eventual timeouts for the clients, normally after a few minutes.
I have only a rudimentary understanding of what these settings mean, and I have found very limited resources online. I would hugely appreciate it if somebody with a better understanding of what these settings mean could help explain what I might be doing wrong.

The only other thing I have considered is that maybe we simply need more bandwidth than Unity’s free multiplayer service provides. We have looked into Going Live, at which point we will be paying for bandwidth. However I was shocked to find that at 4.5kbps per user (the standard recommended by Unity, and only 0.5kbps more than we currently get for free), we could be paying anything from $200-$2,600 a month for 500 users! We are not intending on selling the game for much so this looks totally unfeasible. I cant believe that our relatively simple indie game could be using that much bandwidth… so I am hoping that it is to do with the above mentioned settings issues that we are getting disconnects, not because we actually need that much traffic.

Thanks in advance to anyone who might be able to offer some advice!

FYI for anybody who gets this issue in the future. I managed to eventually fix it with the help of Unity guru aabramychev. He gave me some improved settings for how I was setting up the network topography (which I had never been able to find elsewhere in the documentation). These are the initialization settings that worked for us:

void InitializeNetwork(){
myConfig.AddChannel(QosType.Reliable);
myConfig.AddChannel(QosType.Unreliable);
myConfig.AddChannel(QosType.StateUpdate);
myConfig.AddChannel(QosType.AllCostDelivery);
myConfig.NetworkDropThreshold = 95; //95% packets that need to be dropped before connection is dropped
myConfig.OverflowDropThreshold = 30; //30% packets that need to be dropped before sendupdate timeout is increased
myConfig.InitialBandwidth = 0;
myConfig.MinUpdateTimeout = 10;
myConfig.ConnectTimeout = 2000; // timeout before re-connect attempt will be made
myConfig.PingTimeout = 1500; // should have more than 3 pings per disconnect timeout, and more than 5 messages per ping
myConfig.DisconnectTimeout = 6000; // with a ping of 500 a disconnectimeout of 2000 is supposed to work well
myConfig.PacketSize = 1470;
myConfig.SendDelay = 2;
myConfig.FragmentSize = 1300;
myConfig.AcksType = ConnectionAcksType.Acks128;
myConfig.MaxSentMessageQueueSize = 256;
myConfig.AckDelay = 1;
HostTopology myTopology = new HostTopology(myConfig, 4); //up to 4 connection allowed
NetworkServer.Configure(myTopology);
}

Try a higher port number on Ubuntu. 17000 works but 1700 does not.