@yosu: Yeah, as I mentioned I didn’t expect 100% delivery and I knew there was no guarantees. My problem was something specific and I did determine what it was.
@Christopher Bishop: It works fine with an ad-hoc provisioning profile also, without requiring the app to be live. It appears most people use that most of the time anyhow. I had just been using development for so long and switched to ad-hoc to do final testing before live.
Thank you both for replying, I figured my post was buried and was not going to get any responses. I did solve my problem and I will explain the situation for anyone who may find this post in the future.
As mentioned I started with a development provisioning profile and Apple’s test push server. I am also using Parse as my backend. When I register a device with Parse it saves the registration token to their database.
Tokens for an app that are using Apple’s test server and ones using Apple’s production server, are completely different. Which I knew. So as soon as I switched over, my app got a new token and it was updated to Parse. However I had 4 of my test devices all registered to the same Parse account, so there were 3 old tokens and the one new token. Apple will stop processing a push if it encounters a mismatched token. So my provisioning profile said ad-hoc and 3 of the tokens were still development.
So I would send a push from my game and Parse would see ok, there are 4 devices, send the push to all 4. Depending on the order Parse put them in, I had a small chance it would process the new token first, thus my 5% success rate. Otherwise it would hit one of the old ones and Apple would reject the rest of the push payload. I have no idea why Parse varied on the order of the tokens, but that is how it appeared to be happening.
In the end I went into Parse and cleared all old tokens, leaving only the new ones. Then it instantly was back to 99% success rate and has been since.