Interview concept

LinkedIn Member Graph Service

Asked of: Software Engineer

Last updated

Architecture for a highly available member relationship service, showing idempotent APIs, strong relationship writes, bidirectional adjacency indexes, partitioning, caching, and asynchronous events.

What's being tested

This topic tests whether you can design a highly available, low-latency service for storing and querying relationships among hundreds of millions of members. The interviewer is probing API boundaries, graph-oriented data modeling, partitioning, consistency, idempotent mutations, and failure handling—not graph theory alone. LinkedIn cares because connection, follow, blocking, and recommendation-adjacent features all depend on correct relationship state under heavy read and write load.

Core knowledge

  • Relationship modeling should represent an edge as (sourceMemberId, targetMemberId, type, state, createdAt, version). Keep direction explicit: connections are logically symmetric, while follows, blocks, and pending invitations are directed or stateful.

  • Separate edge types and lifecycle states: PENDING, ACCEPTED, REJECTED, WITHDRAWN, and BLOCKED. A connection request should not become visible as a connection until both sides’ authorization and state transition are recorded correctly.

  • Design APIs around explicit commands and queries: POST /invitations, POST /connections/{id}/accept, DELETE /connections/{id}, GET /members/{id}/connections, and GET /members/{id}/relationship/{otherId}. Return stable error semantics and idempotency behavior.

  • Use idempotency keys for invitation creation and retries. A request identified by (requesterId, recipientId, clientRequestId) should produce one logical mutation even when clients retry after timeouts.

  • A relational store such as Postgres or a distributed wide-column store can support adjacency lists. Index both (sourceMemberId, type, state) and (targetMemberId, type, state); bidirectional lookup is essential for symmetric connections and inbound requests.

  • Avoid naïve graph traversal in the request path. “Connections of connections” can explode to O(dk)O(d^k) candidates; prefer bounded breadth-first search, precomputed summaries, or a separate service when the product explicitly requires second-degree results.

  • Partitioning should distribute by member ID while handling celebrity or highly connected accounts. Consistent hashing, virtual shards, request fan-out limits, and hot-key mitigation matter more than choosing a graph database by name.

  • Choose consistency per operation. Relationship writes need strong or carefully controlled consistency for authorization-sensitive checks; list reads may tolerate eventual replicas. State that a read immediately after an accepted invitation may be temporarily stale if using asynchronous replication.

  • Make multi-record updates safe. For a symmetric connection, either store one canonical edge and derive both directions, or write two adjacency records with a transaction/outbox protocol and repair jobs; document how partial failure is detected and healed.

  • Caching can serve relationship checks and popular adjacency pages, but invalidation must follow successful writes. Use versioned cache entries or short TTLs, and never let stale cache data bypass block, privacy, or authorization checks.

  • Pagination must be stable under concurrent mutations. Prefer cursor pagination using (createdAt, edgeId) rather than offsets; define ordering, duplicate prevention, deleted-edge behavior, and a maximum page size to prevent expensive scans.

  • Protect the service with authentication, authorization, abuse controls, and privacy enforcement. A member may query only permitted relationship data, while blocks should hide or suppress edges consistently across reads, search-like APIs, and notifications.

Worked example

Design a LinkedIn Member Graph Service: I would first clarify supported relationship types, expected read/write QPS, latency targets, privacy rules, pagination requirements, and whether second-degree traversal is in scope. I would declare an initial assumption of hundreds of millions of members, mostly read-heavy traffic, and a requirement for idempotent invitation and acceptance operations. I would organize the design around four pillars: APIs and state transitions, adjacency-list storage and indexes, partitioning and cache strategy, and consistency plus failure recovery. I would model invitations and accepted connections separately or as explicit states, then define the invariant that an accepted connection is visible from both members’ perspectives. A key tradeoff is canonical single-edge storage versus duplicated directional records: canonical storage simplifies consistency, while duplicated records makes neighbor reads faster but requires transactional repair or an outbox. I would explain how cursor pagination, bounded fan-out, and hot-member protection keep reads predictable. I would close by saying that, with more time, I would quantify capacity, design reconciliation metrics, and walk through failover during a partially completed acceptance.

A second angle

A related framing is serving a member’s connection list at scale, where the primary constraint is predictable read latency rather than mutation correctness. The design would emphasize adjacency indexes, cursor pagination, replica routing, cache behavior, and protection against very high-degree members. The same graph model applies, but the tradeoff shifts toward denormalized read paths and bounded fan-out, provided privacy and block-state checks remain authoritative. I would also clarify whether the product needs a point-in-time snapshot or accepts changes appearing between pages.

Common pitfalls

Pitfall: Treating the graph as a generic graph-database problem and proposing unrestricted traversal for every request. Connection lists and relationship checks usually need indexed adjacency lookups; bounded traversal or offline computation is safer for multi-hop features.

Pitfall: Saying “eventual consistency is fine” without identifying which operations require stronger guarantees. A stale list may be acceptable briefly, but stale block or authorization state can expose private relationship data.

Pitfall: Describing storage and APIs without failure semantics. A strong answer explains retries, duplicate requests, partial writes, cache invalidation, reconciliation, and what the client observes when an operation times out after the server commits.

Connections

An interviewer may pivot to distributed transactions, outbox patterns, consistent hashing, or rate limiting. They may also ask how to design privacy enforcement, abuse prevention, or a notification pipeline without coupling those systems tightly to the graph’s write path.

Further reading

Related concepts