You can estimate doc size in the shell using the command, Object.bsonsize(doc), which will give you a way to estimate how large your array can grow before it approaches the max document size.
The important part of the conditional $push is the query portion of the update command. {doc.array:{$ne:NEWVALUE}} ensures that you only $inc the counter field when new values are added to the array.
> db.collection.update({doc.array:{$ne:NEWVALUE}}, {$push:{array:NEWVALUE},$inc:{counter:1}})
won't find the document if NEWVALUE is already in the array, so it won't update the the document by $inc'ing the counter field.
> db.collection.update({doc.array:{$ne:NEWVALUE}}, {$addToSet:{array:NEWVALUE},$inc:{counter:1}})
will have the same result
To help provide schema design advice, could you show us a sample document, your most common queries, and/or common commands?