Low Level Design: Mention and @Tagging Service

Mention service content

{
“@context”: “https://schema.org”,
“@type”: “FAQPage”,
“mainEntity”: [
{
“@type”: “Question”,
“name”: “What is a mention service and how does @tagging work?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “A mention service detects @username or @entity tokens in user-generated content and resolves them to canonical entity records (users, teams, channels). When content is submitted, a parser extracts all @tokens, resolves each to an entity ID via a lookup service, stores mention records linking (content_id, entity_id, position), and triggers notifications for each mentioned entity. The rendered content replaces raw tokens with hyperlinks pointing to the entity’s profile page.”
}
},
{
“@type”: “Question”,
“name”: “How is real-time typeahead implemented for @mention lookup?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “As the user types ‘@’ followed by characters, the client sends incremental prefix queries to a typeahead API. The API queries a low-latency store—typically a Redis sorted set with lexicographic ranging or an Elasticsearch prefix query—scoped to the entities visible to that user (contacts, org members, public profiles). Results are ranked by recency of interaction, mutual connections, and relevance score. Response p99 latency must stay under ~100 ms; this is achieved by in-memory indexes and connection pooling, not by hitting the primary database.”
}
},
{
“@type”: “Question”,
“name”: “How does a mention service parse mentions from submitted text?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “Parsing happens server-side after content submission. A regex or state-machine lexer scans for @-prefixed tokens bounded by whitespace or punctuation. Each candidate token is looked up in the entity index; unknown tokens are ignored or stored as unresolved. The parser must handle edge cases: email addresses (exclude ‘@’), mid-word occurrences, and Unicode display names. Resolved mention spans are stored with byte offsets so downstream renderers can reliably replace them without re-parsing. Rich-text editors (Draft.js, ProseMirror) typically encode mentions as atomic nodes rather than raw @text, which eliminates ambiguity entirely.”
}
},
{
“@type”: “Question”,
“name”: “How are mention notifications delivered and made idempotent?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “After parsing, a notification job is enqueued for each (content_id, mentioned_entity_id) pair. Idempotency is enforced with a unique constraint on (content_id, mentioned_entity_id) in the mention_notifications table; duplicate inserts are ignored. The job fan-out sends push, email, or in-app notifications depending on user preferences fetched from the preference service. Edit events re-diff the mention list: new mentions trigger notifications, removed mentions may trigger retraction messages. All notification jobs carry an idempotency key so retries after transient failures do not double-notify.”
}
}
]
}

See also: Meta Interview Guide 2026: Facebook, Instagram, WhatsApp Engineering

See also: Netflix Interview Guide 2026: Streaming Architecture, Recommendation Systems, and Engineering Excellence

See also: Atlassian Interview Guide

Scroll to Top