O problema potencial é o desempenho e você ainda não tem um problema de desempenho. Há muitas coisas que você pode fazer, dependendo do banco de dados de escolha, para lidar com isso na solução nº 1: indexação, hardware, cache etc. Isso tudo depende da frequência com que o usuário precisa obter uma contagem atual de mensagens não lidas. Muitas dessas opções não exigem codificação personalizada no lado do aplicativo, para que você possa implementá-las com uma alteração de código ou muito pouco. Facilita o crescimento com o aplicativo.
Depois que um usuário se conecta / efetua login, obter a contagem do banco de dados uma vez não é tão ruim. Seu aplicativo manterá uma lista constantemente atualizada de mensagens como e-mail? Obter uma contagem não lida a partir daqui não requer outra viagem ao banco de dados e receber novas mensagens fará uma viagem de banco de dados de qualquer maneira.
Viajando para o banco de dados toda vez que uma mensagem é lida para sinalizar o IsRead? campo é suficiente sem um recálculo de outro campo.
Com a solução 2 (mantendo uma contagem em um campo / em disco), você precisará de uma rotina para reconstruir / recalcular periodicamente esse campo quando houver um problema? E sempre há problemas. Você vai agrupar tudo isso em uma transação? Sempre que alguém envia uma mensagem a outra pessoa, ela pode falhar porque não pode atualizar o UnreadCount do usuário receptor devido a um bloqueio da tabela Usuário? Ou você criará uma tabela separada para esse campo?