This can be a complex issue because there are a lot of variables in play. From a planning perspective I would identify what the maximum indexing rate is that you want the system to be able to handle without delay. Then in a dev environment independently test each component in the system to make sure that it can handle that load. For example if you are using Elasticsearch then test to make sure it can handle X events per second. Do the same for Logstash (use the stdout output with dots codec and measure events per second with
bin/logstash --quiet -f myconfig.conf | pv -Wbart > /dev/null).
If you find that a component cannot handle the load (and you cannot tolerate a processing delay) then scale up horizontally. Add more Logstash instances or more Elasticsearch instances as required.
With your current setup, you can check to see if any of the Logstash worker threads are maxing out the CPU. If this is the case then it could be an issue with your Logstash config, in which case you would want to get a stack trace of Logstash to see what's going on.
If it's not an issue with Logstash, then I would look at your outputs. If you are using Elasticsearch, then use Marvel to look at the percentage of documents being rejected. It is perfectly fine to have some documents rejected but anything higher then 10-15% on a regular basis is a good indication the cluster is overloaded.