When load testing which ever system you are using, it is not enough to open many tabs or browsers on the same machine. These requests are recognized as coming from the same user, so they will be routed to the same R process, and you will see a message indicating that there's no more capacity for connections when that one process is full (since the system won't route new connections from the same user to another process). For this reason, this is not an effective way to run a load test against the system.
Instead, we recommend that you simulate actual user behavior. You can do that with a variety of tools, but some options are:
Server load test and concurrency
A simple script using phantomJS to drive load and concurrency on the server: https://github.com/rstudio/shiny-server/blob/master/manual.test/phantomjs/loadtest.js. This might work for certain scenarios, or at least be used as the base for more complicated test scenarios.
The problem with this script is that you really want to test user interactions - not just page load - during high concurrent use. This would suggest using phantomJS to load the page and interact with the app (phantomJS supports JQuery, so you should be able to identify buttons and click on them). phantomJS is headless so it should be lighter weight than running Selenium tests with traditional browsers. (You can use Selenium and RSelenium to drive phantomJS as well).
Testing various user interactions
Try Selenium (or RSelenium) to create the interactions. The scripts could be run as "headless". This article provides a nice overview: https://cran.r-project.org/web/packages/RSelenium/vignettes/shinytesting.html.
Other tools like Gatling or other load-testing software may also work, as long as they simulate actual user connections.
Finally, while testing and iterating on your applications and settings, we'd recommend reading through the following articles on tuning your settings: