Why does fstrim not seem to be thorough?

This may be because dirty data is still being flushed back to the device or because background processes (such as logging daemons) etc are writing to the device. A good experiment would be to force dirty data to be sync'd back to the device before trying the trim using sync.