On Middlecoin, our 280x rigs are usually ~1-3%, and our 290 rig is ~5-8%.
The 280xs run 2 threads at lower intensity, so I think it helps with the rejects. Any scenario where you're running one thread at high intensity will inherently have higher rejects, but usually the difference is tiny.
The problem is more pronounced with Middlecoin, because of the fact that you're switching coins so often. Many times, you may require new work every couple of seconds. You can tweak how often s/cgminer checks for new work with the "scan-time", "expiry", and "queue" configs.
See Con's original explanation for those settings:
--expiry|-E <arg> Upper bound on how many seconds after getting work we consider a share from it stale (default: 120)
--scan-time|-s <arg> Upper bound on time spent scanning current work, in seconds (default: 60)
--queue|-Q <arg> Minimum number of work items to have queued (0 - 10) (default: 1)
So your miner gets work from your pool. CGMiner thinks that work is valid for another 120 seconds (2 minutes), but will only spend 60 seconds working on it. After that, it moves onto a new set of work. The queue says we'll keep one extra set of work on backup, at all times.
Remember that these 120/60/1 defaults are for Bitcoin, which has a 10 minute block period, and the difficulty recalculates every ~12-14 days. Many alt-coins will have MUCH shorter block times, and recalculate the diff VERY quickly. If cgminer is working on a block for 60 seconds, and thinks that those shares are valid for 120 seconds, when in reality the new alt-coin network is finding a new block every 10 seconds, a lot of what you do is going to be invalid.
We can use this info to edit those parameters. We can set a lower value for all of those, so it's getting newer, valid work more often, and you're not wasting time hashing a block that's already been found. We use -E 30 -s 15 -Q 0, which works well on our 280x rigs, but not on our 290 rigs. I haven't gotten around to changing our 290 rig, but for you, I would try -E 10 -s 5 -Q 0, and see if that lowers your rejects.
TL:DR use this newer config:
"intensity" : "19",
"vectors" : "1",
"worksize" : "256",
"kernel" : "scrypt",
"lookup-gap" : "2",
"auto-fan" : true,
"temp-cutoff" : "85",
"temp-overheat" : "80",
"temp-target" : "70",
"thread-concurrency" : "10239, 21568, 21568, 21568, 10239, 10239",
"api-port" : "4028",
"gpu-dyninterval" : "7",
"gpu-platform" : "0",
"gpu-threads" : "1",
"gpu-engine" : "1120, 1025, 1100, 1100, 1120, 1125",
"gpu-memclock" : "1440, 1250, 1250, 1250, 1440, 1450",
"gpu-powertune" : "20",
"log" : "5",
"no-pool-disable" : true,
"queue" : "0",
"scan-time" : "5",
"expiry" : "10",
"scrypt" : true,
"kernel-path" : "/usr/local/bin"
}