The IMAP spec gives great hopes that the UID value may be used for this:
The unique identifier of a message MUST NOT change during the session, and SHOULD NOT change between sessions. Any change of unique identifiers between sessions MUST be detectable using the UIDVALIDITY mechanism discussed below.
But alas, at least for Microsoft Exchange server, my experience shows that the UID of a message does occasionally/often change between sessions, even though it should not, and this is not detectable using UIDVALIDITY (which always stays the same).
As an example of what actually may happen. I say to the server, got any mail? And the server says, sure, here they are, with ids 4, 5, 7, 8 and 11. (Incrementing but not necessesarily contiguous, so far so well.)
So, next time, I say, got any mail newer than 11? And the server says sure, and gives me 14, 15, 16 and 18, but what has actually happened is that it has reassigned the id of the message previously known as e.g. 5 to e.g. 16! So what looks like a new mail, is actually an old mail with a new id!
This means that 1) "should not" bears no value, 2) Exchange is actually following the spec if we interpret "should not" as "it's up to you" and 3) it may be violating the spec on the UIDVALIDITY part (not quite sure as the spec is a bit vague).
It also means that the UID cannot be trusted as a way to identify messages on the server. If I download message 5, store some information on it in the database, and the server renames it to 16 without my knowing, how can I later find it on the server? And how can I know that 16 is a duplicate of what I have stored as 5?