I've narrowed this down to what I think are is the problem in countCurrentEC2Slaves:
First, it is only looping through the reservations and calling describeInstances : https://github.com/jenkinsci/ec2-plugin/blob/master/src/main/java/hudson/plugins/ec2/EC2Cloud.java#L232-232
This will only count spot requests that have been fulfilled, not pending spot requests as they have not yet become an instance.
What is probably needed is a call to describeSpotInstanceRequests() to get the spot instances, and additionally increment n if there are pending spot requests. Either that or there needs to be an entirely separate set of checks for the maximum number of spot requests.
We have a cron that can sometimes send as many as 100 jobs at once, and we end up with spikes of 100 machines provisioned even though we set our limit to 20. It would be ideal if we could use spot instances + limits on the number running + pending.
This keeps biting us. We had global instance cap of 30, and a per cloud cap of 30, as well as cc28xl caps at aws. Turns out that our aws caps only applied to on demand instances, and so did jenkins. i.e. we had 90 machines running at once.