System Design Arena
System Design: GitHub
Host git repos, enable collaboration, run CI/CD (Actions), and deliver enterprise controls.
Case Study
Code Hosting Platform
Same conversation, diagrams, and wrap-up you expectβnow framed with clearer scaffolding and iconography.
Prompt
Design GitHub. Provide git hosting, pull requests, issues, Actions, package registry, and enterprise security for millions of developers.
Interview snapshot
- β’ Topic: Code Hosting Platform
- β’ Expected depth: 45 - 60 minutes
- β’ Focus areas: APIs, scale estimation, resilient architecture
- β’ Wrap-up: risk, monitoring, disaster recovery
Key takeaways
- β’ Git hosting over HTTPS/SSH with permissions.
- β’ Durability: never lose repo data.
- β’ POST /api/repos/{repo}/pulls - create PR.
ποΈ Interview mode
Practice this like a real interview
Don't read the answer first. Work the framework against the bare prompt, then compare against what the interviewer expected at each step.
Scorecard
What the interviewer is evaluating
Staff-level signal
Does the candidate realize git hosting is a stateful storage problem (repos pinned to servers) that resists the stateless-service pattern everything else uses?
π§ Staff engineer judgment
Do not force git into object storage because "files belong in S3." Gitβs performance model assumes local disk; fighting that is fighting the product.
Calibration
The common (bad) answer
Client β LB β API servers (stateless) β S3 for repos
β Why this scores poorly: Git operations are not stateless HTTP calls β a clone streams gigabytes computed from packfiles, and object storage latencies make every git operation crawl.
β What a strong answer adds
- Route git traffic by repo to the fileserver holding it β sticky, not round-robin.
- Replicate each repo (3Γ) with a consensus on which replica is writable.
- Separate git wire protocol (SSH/HTTPS smart protocol) from the web/API plane.
- Pull requests, issues, actions are ordinary CRUD β keep them off the git path.
- Hot-repo problem: a trending repo needs read replicas and pack caching.
Build it up
Step-by-Step Walkthrough
GitHub is two systems sharing a login: a distributed file store that must never lose a byte of git data, and a metadata product (PRs, issues, Actions) that must feel instant. Conflating them is the classic mistake β split them in your first minute.
Naive: bare repos on one big server
One beefy machine, bare git repositories on disk, nginx fronting git over HTTPS and sshd for git over SSH, users table for auth. This is literally how self-hosted git starts, and for a small org it is the right answer.
At ~200M repos averaging ~50 MB, you are staring at ~10 PB (dedupe helps β forks share objects) that cannot fit one machine and, more importantly, must never be lost. A dead disk here is not degraded service; it is someone's company history gone. Durability, not throughput, forces the first real architecture.
Replicated repo storage behind a routing tier
The fix is a fleet of storage servers, each repo living as three replicas on different hosts (Spokes/DGit-style). A push streams through the git front end to the primary replica and reaches quorum before the client sees success; reads are served by any replica. A routing layer maps repo β replica set, and rebalancing moves repos off hot or dying hosts.
Two flavors of bytes get split out: large binary assets (LFS, release artifacts) go to a blob store rather than bloating git object databases, and traffic is asymmetric β on the order of ~1M pushes/day but ~10M fetches/day (CI is most of it), so front ends autoscale on the fetch side and cache pack computations for hot repos.
?Why not just NFS or object storage?
Git operations are chatty, random-access, and compute-heavy (pack negotiation). Replicated local disk with the git logic co-located beats a network filesystem; object storage alone can't serve a clone's pack computation. Explaining that trade-off is the storage question's real answer.
The metadata product: PRs, issues, and the merge queue
Everything that is not git objects β repos, PRs, issues, reviews, permissions β lives in sharded SQL (sharded by repo/org so one hot monorepo cannot brown out a shard of strangers). The PR lifecycle is a state machine: opened β reviews requested β checks pending β approved β merged, with webhooks firing at each transition.
The senior talking point is the merge queue: on a busy repo, two green PRs can conflict semantically, so instead of merging directly, PRs enter a queue that creates speculative merge commits, runs CI against the combined result, and lands them in order β rolling back queue entries behind a failure. It converts 'merge then break main' into 'break the candidate, main stays green.'
Actions: a CI cloud bolted to every push
Every push can trigger workflows β on the order of ~2M runs/day, wanting ~50K concurrent runners. A scheduler consumes webhook events, resolves workflow YAML, and dispatches jobs to runner pools of ephemeral VMs: created for one job, destroyed after, because runners execute arbitrary user code and must never be shared or reused across trust boundaries.
Secrets are injected at job start from an encrypted store, scoped per repo/environment, and never written to the (persisted, streamable) logs β which, with artifacts, land in the blob store. The queue also absorbs the thundering herd after an incident: backlogged workflows drain by priority instead of stampeding the scheduler.
!Runners are a security boundary, not a fleet
Interviewers will probe: what stops a malicious PR from stealing secrets? Answer: fork PRs get no secrets by default, runners are single-use VMs, and workflow approval gates exist for first-time contributors. CI that runs stranger's code is an attack surface first, infrastructure second.
Notifications, security scanning, and enterprise polish
Around ~100M notification events/day (~1.1K/s) fan out through a notification service to websocket sessions and email workers β classic async fan-out, nothing exotic, which is exactly why you mention it briefly and move on. Search over code and issues runs on separate indexes fed by the same event stream.
The security pipeline earns its own lane: secret scanning on every push (revoking leaked credentials with partner providers), a dependency graph powering vulnerability alerts, and code signing. Enterprise wraps it with SSO, org-wide policy enforcement, and exportable audit logs β the SOC2/GDPR/FedRAMP checklist that turns a developer tool into something procurement approves.
Blueprint
Architecture Diagram
The narrated components above, laid out as an actual flow β so you can see how a request moves through the system, not just read a list of pieces.
Git front end
Git front end
repo storage
blob store
Metadata service (sharded
Metadata service (sharded SQL) tracks repos
Metadata service (sharded SQL) tracks repos, PRs, issues
Actions scheduler
Actions scheduler
runner pools
logs/artifacts
Notification service
Notification service
websocket/email workers
Security pipeline
secret scanning
secret scanning, dependency graph, code signing
Flow Diagram
How the API maps to this flow
- 1
POST /api/repos/{repo}/pullsβ create PR. - 2
POST /api/repos/{repo}/actions/workflows/{id}/dispatchβ trigger workflow. - 3
GET /api/repos/{repo}/commitsβ list commits. - 4
POST /api/repos/{repo}/issuesβ create issue. - 5
GET /api/orgs/{org}/auditβ log - audit export.
?But why does this actually hold up at scale?
200M repos * 50 MB avg -> 10 PB storage (dedupe reduces).
Video walkthrough
System Design of GitHub Code Search
Gaurav Sen Β· 37 min
Indexing billions of files β the search side of a code-hosting platform, which is where the depth is.
Work the prompt yourself first β guided practice grades your own answer step by step. Watching someone else design it feels like progress and teaches you far less.
Interview flow
Dialogue timeline
Interviewer
What are the core services?
Candidate
Git storage, metadata/PR service, code review, Actions runners, notifications, security scanning.
Interviewer
How do you store repos reliably?
Candidate
Sharded blob storage for pack files, metadata DB for refs. Smart HTTP/SSH front ends talk to storage. Multi-region replicas + backups.
Interviewer
Explain CI (Actions).
Candidate
Workflow definitions trigger runners (VMs). Scheduler enforces concurrency, secrets injected securely, logs/artifacts stored in object storage.
Scoping
Requirements & trade-offs
Functional Requirements
- βGit hosting over HTTPS/SSH with permissions.
- βPull requests, code reviews, comments, merge queue.
- βIssues/discussions, notifications, project boards.
- βActions CI/CD with runners, secrets, artifacts.
- βPackage registry (npm, Maven, Docker).
- βEnterprise SSO, audit logs, policy enforcement.
Non-Functional Requirements
- βDurability: never lose repo data.
- βPerformance: git fetch/push limited by client bandwidth, metadata ops low latency.
- βSecurity: secret scanning, dependency alerts, code signing.
- βCompliance: SOC2, GDPR, FedRAMP options.
Blueprint
Architecture modules
Module 1
API Endpoints
- β’POST /api/repos/{repo}/pulls - create PR.
- β’POST /api/repos/{repo}/actions/workflows/{id}/dispatch - trigger workflow.
- β’GET /api/repos/{repo}/commits - list commits.
- β’POST /api/repos/{repo}/issues - create issue.
- β’GET /api/orgs/{org}/audit-log - audit export.
Module 2
Back-of-the-Envelope
- β’200M repos * 50 MB avg -> 10 PB storage (dedupe reduces).
- β’Git traffic: 1M pushes/day, 10M fetches/day. Need autoscaled front ends.
- β’Actions: 2M workflow runs/day; assume 50K concurrent runners.
- β’Notifications: 100M events/day -> 1.1K/s (websocket + email).
Module 3
System Diagram Notes
- β’Git front end -> repo storage -> blob store.
- β’Metadata service (sharded SQL) tracks repos, PRs, issues.
- β’Actions scheduler -> runner pools -> logs/artifacts.
- β’Notification service -> websocket/email workers.
- β’Security pipeline: secret scanning, dependency graph, code signing.
Module 4
Design Playbook
- β’Clarify git storage + replication.
- β’Explain PR lifecycle, review, merge queue.
- β’Discuss Actions architecture, scaling runners, secrets.
- β’Cover search (code/issues) + caching.
- β’Address enterprise features: policy, SSO, audit.