new routes

This commit is contained in:
Harivansh Rathi 2026-01-06 23:52:49 +05:30
parent f0fee8e40b
commit e7e87a3519
30 changed files with 2132 additions and 0 deletions

View file

@ -0,0 +1,54 @@
<script lang="ts">
import * as Icons from 'lucide-svelte';
import { navigationItems, type NavItem } from '$lib/stores/navigation';
type IconComponent = typeof Icons.Box;
function getIcon(iconName: string): IconComponent {
const iconMap = Icons as unknown as Record<string, IconComponent>;
return iconMap[iconName] || Icons.Box;
}
const section = navigationItems.find((i) => i.id === 'compare') as NavItem | undefined;
</script>
<svelte:head>
<title>Compare - System Design Explorer</title>
</svelte:head>
<div class="max-w-6xl mx-auto space-y-8">
<div>
<div class="flex items-center gap-2 text-surface-500 text-sm mb-2">
<a href="/" class="hover:text-surface-300">Overview</a>
<Icons.ChevronRight class="w-4 h-4" />
<span class="text-surface-300">Compare</span>
</div>
<h1 class="text-3xl font-bold text-surface-100">Compare</h1>
<p class="text-surface-400 mt-2">
Side-by-side analysis with quick “when to use” guidance.
</p>
</div>
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
{#each section?.children ?? [] as child}
{@const Icon = getIcon(child.icon)}
<a href={child.href} class="card-hover group">
<div class="flex items-start gap-4">
<div class="w-12 h-12 rounded-xl bg-surface-800 border border-surface-700 flex items-center justify-center flex-shrink-0 group-hover:border-surface-600 transition-colors duration-200">
<Icon class="w-6 h-6 text-surface-200" />
</div>
<div>
<h3 class="font-semibold text-surface-100 group-hover:text-white transition-colors">
{child.label}
</h3>
<p class="text-sm text-surface-400 mt-1">Comparison guide</p>
</div>
</div>
<div class="mt-4 flex items-center text-sm text-surface-400 group-hover:text-surface-200">
<span>Open</span>
<Icons.ArrowRight class="w-4 h-4 ml-1 group-hover:translate-x-1 transition-transform" />
</div>
</a>
{/each}
</div>
</div>

View file

@ -0,0 +1,155 @@
<script lang="ts">
import * as Icons from 'lucide-svelte';
import ComparisonTable from '$lib/components/diagrams/ComparisonTable.svelte';
const options = [
{
id: 'rest',
name: 'REST',
description: 'Resource-oriented HTTP APIs with caching-friendly semantics',
color: '#3B82F6',
icon: 'Globe',
whenToUse: [
'Public APIs with broad client support',
'Simple CRUD over resources',
'Strong HTTP caching semantics',
'Teams that want predictable operational simplicity'
],
whenNotToUse: [
'Highly nested/graph queries causing over/under-fetching',
'Strict low-latency internal RPC at high QPS',
'Many client-specific response shapes'
]
},
{
id: 'graphql',
name: 'GraphQL',
description: 'Client-driven query language for APIs (typed schema)',
color: '#A855F7',
icon: 'Binary',
whenToUse: [
'Multiple clients with different data needs',
'You want a single endpoint with typed schema',
'You can invest in schema governance and resolvers',
'Rapid product iteration with changing UI requirements'
],
whenNotToUse: [
'You need simple caching at the HTTP layer',
'You cannot commit to strict schema discipline',
'Complex authorization per field without good tooling'
]
},
{
id: 'grpc',
name: 'gRPC',
description: 'High-performance RPC over HTTP/2 with protobuf contracts',
color: '#22C55E',
icon: 'Zap',
whenToUse: [
'Internal service-to-service communication',
'Low latency and high throughput are priorities',
'Strong contracts and code generation help correctness',
'Streaming (client/server/bidi) is valuable'
],
whenNotToUse: [
'Browser-first clients without a gateway layer',
'Human-readable payloads are required',
'You need “just curl it” simplicity'
]
}
];
const features = [
{
feature: 'Contract',
description: 'How requests/responses are described',
values: {
rest: 'OpenAPI (optional)',
graphql: 'Schema (required)',
grpc: 'Protobuf (required)'
}
},
{
feature: 'Transport',
description: 'What runs on the wire',
values: {
rest: 'HTTP/1.1+',
graphql: 'HTTP',
grpc: 'HTTP/2'
}
},
{
feature: 'Caching',
description: 'Where caching is easiest',
values: {
rest: 'HTTP caching',
graphql: 'App/gateway caching',
grpc: 'App/gateway caching'
}
},
{
feature: 'Streaming',
description: 'Real-time / incremental responses',
values: {
rest: 'Limited (varies)',
graphql: 'Subscriptions (varies)',
grpc: 'Built-in (streams)'
}
},
{
feature: 'Best fit',
description: 'Typical sweet spot',
values: {
rest: 'Public APIs',
graphql: 'Product UIs',
grpc: 'Internal services'
}
}
];
const references = [
{ label: 'MDN: REST', href: 'https://developer.mozilla.org/en-US/docs/Glossary/REST' },
{ label: 'GraphQL Specification', href: 'https://spec.graphql.org/' },
{ label: 'gRPC Documentation', href: 'https://grpc.io/docs/' }
];
</script>
<svelte:head>
<title>REST vs GraphQL vs gRPC - System Design Explorer</title>
</svelte:head>
<div class="max-w-6xl mx-auto space-y-8">
<div>
<div class="flex items-center gap-2 text-surface-500 text-sm mb-2">
<a href="/compare" class="hover:text-surface-300">Compare</a>
<Icons.ChevronRight class="w-4 h-4" />
<span class="text-surface-300">REST vs GraphQL vs gRPC</span>
</div>
<h1 class="text-3xl font-bold text-surface-100">REST vs GraphQL vs gRPC</h1>
<p class="text-surface-400">
API style is a product and operational decision: clients, latency, caching, and contracts all matter.
</p>
</div>
<div class="card">
<ComparisonTable
title="Pick the right API style"
subtitle="Click a column header for “when to use” guidance"
{options}
{features}
/>
</div>
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">References</h2>
<ul class="space-y-2">
{#each references as ref}
<li>
<a class="text-surface-200 hover:text-white underline underline-offset-4" href={ref.href} target="_blank" rel="noreferrer">
{ref.label}
</a>
</li>
{/each}
</ul>
</div>
</div>

View file

@ -0,0 +1,54 @@
<script lang="ts">
import * as Icons from 'lucide-svelte';
import { navigationItems, type NavItem } from '$lib/stores/navigation';
type IconComponent = typeof Icons.Box;
function getIcon(iconName: string): IconComponent {
const iconMap = Icons as unknown as Record<string, IconComponent>;
return iconMap[iconName] || Icons.Box;
}
const section = navigationItems.find((i) => i.id === 'compute') as NavItem | undefined;
</script>
<svelte:head>
<title>Compute - System Design Explorer</title>
</svelte:head>
<div class="max-w-6xl mx-auto space-y-8">
<div>
<div class="flex items-center gap-2 text-surface-500 text-sm mb-2">
<a href="/" class="hover:text-surface-300">Overview</a>
<Icons.ChevronRight class="w-4 h-4" />
<span class="text-surface-300">Compute</span>
</div>
<h1 class="text-3xl font-bold text-surface-100">Compute</h1>
<p class="text-surface-400 mt-2">
How your code runs: VMs, containers, Kubernetes, and serverless execution models.
</p>
</div>
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
{#each section?.children ?? [] as child}
{@const Icon = getIcon(child.icon)}
<a href={child.href} class="card-hover group">
<div class="flex items-start gap-4">
<div class="w-12 h-12 rounded-xl bg-surface-800 border border-surface-700 flex items-center justify-center flex-shrink-0 group-hover:border-surface-600 transition-colors duration-200">
<Icon class="w-6 h-6 text-surface-200" />
</div>
<div>
<h3 class="font-semibold text-surface-100 group-hover:text-white transition-colors">
{child.label}
</h3>
<p class="text-sm text-surface-400 mt-1">Concepts + trade-offs</p>
</div>
</div>
<div class="mt-4 flex items-center text-sm text-surface-400 group-hover:text-surface-200">
<span>Open</span>
<Icons.ArrowRight class="w-4 h-4 ml-1 group-hover:translate-x-1 transition-transform" />
</div>
</a>
{/each}
</div>
</div>

View file

@ -0,0 +1,75 @@
<script lang="ts">
import * as Icons from 'lucide-svelte';
const highlights = [
{ title: 'Packaging', desc: 'Bundle app + dependencies into an image; run consistently across environments.' },
{ title: 'Isolation', desc: 'Process-level isolation using OS primitives (namespaces/cgroups), not a full guest OS.' },
{ title: 'Fast deploys', desc: 'Start/stop quickly; good for CI/CD and autoscaling.' },
{ title: 'Standard interface', desc: 'Images + registries + runtime API make shipping software predictable.' }
] as const;
const references = [
{ label: 'Docker Documentation', href: 'https://docs.docker.com/' },
{ label: 'Kubernetes (containers & workloads)', href: 'https://kubernetes.io/docs/concepts/workloads/pods/' }
];
</script>
<svelte:head>
<title>Containers - System Design Explorer</title>
</svelte:head>
<div class="max-w-5xl mx-auto space-y-8">
<div>
<div class="flex items-center gap-2 text-surface-500 text-sm mb-2">
<a href="/compute" class="hover:text-surface-300">Compute</a>
<Icons.ChevronRight class="w-4 h-4" />
<span class="text-surface-300">Containers</span>
</div>
<h1 class="text-3xl font-bold text-surface-100">Containers</h1>
<p class="text-surface-400 mt-2">
Lightweight deployment units: ship code as images and run them with predictable runtime boundaries.
</p>
</div>
<div class="grid md:grid-cols-2 gap-6">
{#each highlights as h}
<div class="card">
<h2 class="text-lg font-semibold text-surface-100">{h.title}</h2>
<p class="text-sm text-surface-400 mt-2">{h.desc}</p>
</div>
{/each}
</div>
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">Operational Notes</h2>
<ul class="space-y-2 text-surface-300">
<li class="flex gap-2"><Icons.Check class="w-4 h-4 mt-0.5 text-surface-400" />Use immutable images; avoid “ssh and fix” in running containers.</li>
<li class="flex gap-2"><Icons.Check class="w-4 h-4 mt-0.5 text-surface-400" />Prefer one process per container; scale via replicas.</li>
<li class="flex gap-2"><Icons.Check class="w-4 h-4 mt-0.5 text-surface-400" />Log to stdout/stderr; let the platform aggregate.</li>
<li class="flex gap-2"><Icons.Check class="w-4 h-4 mt-0.5 text-surface-400" />Define CPU/memory limits to prevent noisy neighbors.</li>
</ul>
</div>
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">References</h2>
<ul class="space-y-2">
{#each references as ref}
<li>
<a class="text-surface-200 hover:text-white underline underline-offset-4" href={ref.href} target="_blank" rel="noreferrer">
{ref.label}
</a>
</li>
{/each}
</ul>
</div>
<div class="flex justify-between">
<a href="/compute/virtual-machines" class="btn-secondary flex items-center gap-2">
<Icons.ArrowLeft class="w-4 h-4" /> Virtual Machines
</a>
<a href="/compute/kubernetes" class="btn-primary flex items-center gap-2">
Kubernetes <Icons.ArrowRight class="w-4 h-4" />
</a>
</div>
</div>

View file

@ -0,0 +1,107 @@
<script lang="ts">
import * as Icons from 'lucide-svelte';
import GuidedWalkthrough from '$lib/components/diagrams/GuidedWalkthrough.svelte';
const steps = [
{
id: 'provision',
title: 'Provision a VM',
description: 'Allocate a virtual machine with CPU/RAM/disk from a cloud or hypervisor.',
icon: 'Server',
details: 'You manage the OS, patches, package installs, and runtime configuration.',
tip: 'Bake an image (AMI) and use autoscaling groups for repeatability.'
},
{
id: 'deploy',
title: 'Deploy your app',
description: 'Install your service, configure env vars, and run a process manager (systemd, supervisord).',
icon: 'Upload',
details: 'Youre responsible for rollouts, health checks, and restarts.'
},
{
id: 'scale',
title: 'Scale with replicas',
description: 'Add more VMs and put them behind a load balancer.',
icon: 'Layers',
details: 'Stateful components (DB, disks, sessions) often become the scaling bottleneck.',
tip: 'Prefer stateless services + externalized state (DB/cache/object storage).'
},
{
id: 'operate',
title: 'Operate & secure',
description: 'Monitoring, patching, hardening, backups, and incident response are on you.',
icon: 'Shield',
details: 'You own the OS and network surface area.'
}
];
const references = [
{ label: 'AWS EC2 Instances', href: 'https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Instances.html' },
{ label: 'Kubernetes (for comparison)', href: 'https://kubernetes.io/docs/concepts/' }
];
</script>
<svelte:head>
<title>Virtual Machines - System Design Explorer</title>
</svelte:head>
<div class="max-w-6xl mx-auto space-y-8">
<div>
<div class="flex items-center gap-2 text-surface-500 text-sm mb-2">
<a href="/compute" class="hover:text-surface-300">Compute</a>
<Icons.ChevronRight class="w-4 h-4" />
<span class="text-surface-300">Virtual Machines</span>
</div>
<h1 class="text-3xl font-bold text-surface-100">Virtual Machines</h1>
<p class="text-surface-400 mt-2">
A VM gives you an isolated OS environment—max control, max operational responsibility.
</p>
</div>
<GuidedWalkthrough
title="How VM-based deployment typically works"
subtitle="A pragmatic mental model for system design interviews and real systems"
{steps}
/>
<div class="grid md:grid-cols-2 gap-6">
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">When VMs shine</h2>
<ul class="space-y-2 text-surface-300">
<li class="flex gap-2"><Icons.Check class="w-4 h-4 mt-0.5 text-surface-400" />Legacy apps that expect full OS control</li>
<li class="flex gap-2"><Icons.Check class="w-4 h-4 mt-0.5 text-surface-400" />Specialized kernel / drivers / networking</li>
<li class="flex gap-2"><Icons.Check class="w-4 h-4 mt-0.5 text-surface-400" />Long-running services with predictable load</li>
</ul>
</div>
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">Common pitfalls</h2>
<ul class="space-y-2 text-surface-300">
<li class="flex gap-2"><Icons.AlertTriangle class="w-4 h-4 mt-0.5 text-surface-400" />Config drift without automation (IaC + images)</li>
<li class="flex gap-2"><Icons.AlertTriangle class="w-4 h-4 mt-0.5 text-surface-400" />Snowflake servers (manual fixes)</li>
<li class="flex gap-2"><Icons.AlertTriangle class="w-4 h-4 mt-0.5 text-surface-400" />Slow patching and inconsistent security posture</li>
</ul>
</div>
</div>
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">References</h2>
<ul class="space-y-2">
{#each references as ref}
<li>
<a class="text-surface-200 hover:text-white underline underline-offset-4" href={ref.href} target="_blank" rel="noreferrer">
{ref.label}
</a>
</li>
{/each}
</ul>
</div>
<div class="flex justify-between">
<a href="/compute" class="btn-secondary flex items-center gap-2">
<Icons.ArrowLeft class="w-4 h-4" /> Compute
</a>
<a href="/compute/containers" class="btn-primary flex items-center gap-2">
Containers <Icons.ArrowRight class="w-4 h-4" />
</a>
</div>
</div>

View file

@ -0,0 +1,54 @@
<script lang="ts">
import * as Icons from 'lucide-svelte';
import { navigationItems, type NavItem } from '$lib/stores/navigation';
type IconComponent = typeof Icons.Box;
function getIcon(iconName: string): IconComponent {
const iconMap = Icons as unknown as Record<string, IconComponent>;
return iconMap[iconName] || Icons.Box;
}
const section = navigationItems.find((i) => i.id === 'databases') as NavItem | undefined;
</script>
<svelte:head>
<title>Databases - System Design Explorer</title>
</svelte:head>
<div class="max-w-6xl mx-auto space-y-8">
<div>
<div class="flex items-center gap-2 text-surface-500 text-sm mb-2">
<a href="/" class="hover:text-surface-300">Overview</a>
<Icons.ChevronRight class="w-4 h-4" />
<span class="text-surface-300">Databases</span>
</div>
<h1 class="text-3xl font-bold text-surface-100">Databases</h1>
<p class="text-surface-400 mt-2">
Choose the right data model and scaling strategy: SQL, NoSQL, caching, and replication.
</p>
</div>
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
{#each section?.children ?? [] as child}
{@const Icon = getIcon(child.icon)}
<a href={child.href} class="card-hover group">
<div class="flex items-start gap-4">
<div class="w-12 h-12 rounded-xl bg-surface-800 border border-surface-700 flex items-center justify-center flex-shrink-0 group-hover:border-surface-600 transition-colors duration-200">
<Icon class="w-6 h-6 text-surface-200" />
</div>
<div>
<h3 class="font-semibold text-surface-100 group-hover:text-white transition-colors">
{child.label}
</h3>
<p class="text-sm text-surface-400 mt-1">Concepts + patterns</p>
</div>
</div>
<div class="mt-4 flex items-center text-sm text-surface-400 group-hover:text-surface-200">
<span>Open</span>
<Icons.ArrowRight class="w-4 h-4 ml-1 group-hover:translate-x-1 transition-transform" />
</div>
</a>
{/each}
</div>
</div>

View file

@ -0,0 +1,62 @@
<script lang="ts">
import * as Icons from 'lucide-svelte';
const models = [
{ title: 'Document', desc: 'JSON-like documents; flexible schema; easy to evolve.' },
{ title: 'Key-value', desc: 'Fast lookups by key; simple operations; often used for sessions/caching.' },
{ title: 'Wide-column', desc: 'High write throughput and horizontal scale; good for time-series/event data.' },
{ title: 'Graph', desc: 'Relationships are first-class; great for traversals (social graphs, recommendations).' }
] as const;
const references = [
{ label: 'Compare: SQL vs NoSQL', href: '/compare/sql-vs-nosql' },
{ label: 'MongoDB Manual', href: 'https://www.mongodb.com/docs/manual/' },
{ label: 'DynamoDB Developer Guide', href: 'https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Introduction.html' }
];
</script>
<svelte:head>
<title>NoSQL Databases - System Design Explorer</title>
</svelte:head>
<div class="max-w-5xl mx-auto space-y-8">
<div>
<div class="flex items-center gap-2 text-surface-500 text-sm mb-2">
<a href="/databases" class="hover:text-surface-300">Databases</a>
<Icons.ChevronRight class="w-4 h-4" />
<span class="text-surface-300">NoSQL Databases</span>
</div>
<h1 class="text-3xl font-bold text-surface-100">NoSQL Databases</h1>
<p class="text-surface-400 mt-2">
A family of models optimized for scale, availability, and flexible schemas—at the cost of uniform query power.
</p>
</div>
<div class="grid md:grid-cols-2 gap-6">
{#each models as m}
<div class="card">
<h2 class="text-lg font-semibold text-surface-100">{m.title}</h2>
<p class="text-sm text-surface-400 mt-2">{m.desc}</p>
</div>
{/each}
</div>
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">Design note</h2>
<p class="text-surface-300">
With NoSQL, model around access patterns: define the queries first, then shape the data to serve them cheaply.
</p>
<div class="mt-4 flex flex-wrap gap-3">
{#each references as ref}
<a
class="btn-primary"
href={ref.href}
target={ref.href.startsWith('http') ? '_blank' : undefined}
rel={ref.href.startsWith('http') ? 'noreferrer' : undefined}
>
{ref.label}
</a>
{/each}
</div>
</div>
</div>

View file

@ -0,0 +1,59 @@
<script lang="ts">
import * as Icons from 'lucide-svelte';
const traits = [
{ title: 'Relational model', desc: 'Tables, rows, and relations; great for multi-entity queries and constraints.' },
{ title: 'ACID transactions', desc: 'Strong correctness guarantees for critical business invariants.' },
{ title: 'Indexes', desc: 'Fast point/range lookups; cost extra writes and storage.' },
{ title: 'Scaling pattern', desc: 'Scale reads via replicas; scale writes via sharding/partitioning or specialized systems.' }
] as const;
const references = [
{ label: 'Which Database? (decision tree)', href: '/decisions/which-database' },
{ label: 'PostgreSQL Documentation', href: 'https://www.postgresql.org/docs/' }
];
</script>
<svelte:head>
<title>SQL Databases - System Design Explorer</title>
</svelte:head>
<div class="max-w-5xl mx-auto space-y-8">
<div>
<div class="flex items-center gap-2 text-surface-500 text-sm mb-2">
<a href="/databases" class="hover:text-surface-300">Databases</a>
<Icons.ChevronRight class="w-4 h-4" />
<span class="text-surface-300">SQL Databases</span>
</div>
<h1 class="text-3xl font-bold text-surface-100">SQL Databases</h1>
<p class="text-surface-400 mt-2">
The default choice for many products: strong correctness, powerful querying, and mature tooling.
</p>
</div>
<div class="grid md:grid-cols-2 gap-6">
{#each traits as t}
<div class="card">
<h2 class="text-lg font-semibold text-surface-100">{t.title}</h2>
<p class="text-sm text-surface-400 mt-2">{t.desc}</p>
</div>
{/each}
</div>
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">Next steps</h2>
<div class="flex flex-wrap gap-3">
{#each references as ref}
<a
class="btn-secondary"
href={ref.href}
target={ref.href.startsWith('http') ? '_blank' : undefined}
rel={ref.href.startsWith('http') ? 'noreferrer' : undefined}
>
{ref.label}
</a>
{/each}
<a class="btn-primary" href="/compare/sql-vs-nosql">SQL vs NoSQL</a>
</div>
</div>
</div>

View file

@ -0,0 +1,54 @@
<script lang="ts">
import * as Icons from 'lucide-svelte';
import { navigationItems, type NavItem } from '$lib/stores/navigation';
type IconComponent = typeof Icons.Box;
function getIcon(iconName: string): IconComponent {
const iconMap = Icons as unknown as Record<string, IconComponent>;
return iconMap[iconName] || Icons.Box;
}
const section = navigationItems.find((i) => i.id === 'decisions') as NavItem | undefined;
</script>
<svelte:head>
<title>Decision Trees - System Design Explorer</title>
</svelte:head>
<div class="max-w-6xl mx-auto space-y-8">
<div>
<div class="flex items-center gap-2 text-surface-500 text-sm mb-2">
<a href="/" class="hover:text-surface-300">Overview</a>
<Icons.ChevronRight class="w-4 h-4" />
<span class="text-surface-300">Decision Trees</span>
</div>
<h1 class="text-3xl font-bold text-surface-100">Decision Trees</h1>
<p class="text-surface-400 mt-2">
Interactive guides that turn requirements into an architecture choice.
</p>
</div>
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
{#each section?.children ?? [] as child}
{@const Icon = getIcon(child.icon)}
<a href={child.href} class="card-hover group">
<div class="flex items-start gap-4">
<div class="w-12 h-12 rounded-xl bg-surface-800 border border-surface-700 flex items-center justify-center flex-shrink-0 group-hover:border-surface-600 transition-colors duration-200">
<Icon class="w-6 h-6 text-surface-200" />
</div>
<div>
<h3 class="font-semibold text-surface-100 group-hover:text-white transition-colors">
{child.label}
</h3>
<p class="text-sm text-surface-400 mt-1">Decision walkthrough</p>
</div>
</div>
<div class="mt-4 flex items-center text-sm text-surface-400 group-hover:text-surface-200">
<span>Open</span>
<Icons.ArrowRight class="w-4 h-4 ml-1 group-hover:translate-x-1 transition-transform" />
</div>
</a>
{/each}
</div>
</div>

View file

@ -0,0 +1,109 @@
<script lang="ts">
import * as Icons from 'lucide-svelte';
import DecisionTree from '$lib/components/diagrams/DecisionTree.svelte';
const nodes = [
{
id: 'start',
type: 'question' as const,
text: 'Is your workload event-driven or spiky (bursts, unpredictable traffic)?',
description: 'Examples: webhooks, queues, cron jobs, variable API traffic.',
yes: 'cold-start-ok',
no: 'steady-load'
},
{
id: 'steady-load',
type: 'question' as const,
text: 'Is the workload steady and long-running (always-on)?',
description: 'Example: low-latency APIs with predictable throughput.',
yes: 'containers-or-vms',
no: 'cold-start-ok'
},
{
id: 'cold-start-ok',
type: 'question' as const,
text: 'Can you tolerate occasional cold starts (extra latency)?',
description: 'Some serverless platforms add startup latency when scaling from zero.',
yes: 'serverless-answer',
no: 'containers-answer'
},
{
id: 'serverless-answer',
type: 'answer' as const,
text: 'Serverless Functions',
icon: 'Zap',
reasoning: 'Great for bursty/event-driven workloads: automatic scaling, pay-per-use, minimal ops. Watch limits, execution time, and cold-start latency.',
alternatives: [
'Managed containers (Cloud Run / Fargate) for more control',
'Kubernetes for complex multi-service platforms'
]
},
{
id: 'containers-answer',
type: 'answer' as const,
text: 'Containers (Managed or Orchestrated)',
icon: 'Box',
reasoning: 'If you need consistent low latency and more runtime control, containers are often the sweet spot. Use a managed platform to reduce operational load.',
alternatives: [
'Kubernetes for advanced scheduling and ecosystem',
'VMs for full OS control / legacy workloads'
]
},
{
id: 'containers-or-vms',
type: 'answer' as const,
text: 'Containers or VMs',
icon: 'Server',
reasoning: 'Always-on services are often cheaper and simpler on containers/VMs than pure serverless. Use autoscaling + load balancing for resilience.',
alternatives: [
'Serverless for async jobs and event handlers',
'Kubernetes if you need multi-tenant orchestration'
]
}
];
const references = [
{ label: 'AWS Lambda Developer Guide', href: 'https://docs.aws.amazon.com/lambda/latest/dg/welcome.html' },
{ label: 'Kubernetes Concepts', href: 'https://kubernetes.io/docs/concepts/' }
];
</script>
<svelte:head>
<title>Serverless or Not? - System Design Explorer</title>
</svelte:head>
<div class="max-w-6xl mx-auto space-y-8">
<div>
<div class="flex items-center gap-2 text-surface-500 text-sm mb-2">
<a href="/decisions" class="hover:text-surface-300">Decision Trees</a>
<Icons.ChevronRight class="w-4 h-4" />
<span class="text-surface-300">Serverless or Not?</span>
</div>
<h1 class="text-3xl font-bold text-surface-100">Serverless or Not?</h1>
<p class="text-surface-400 mt-2">
Use this quick decision tree to pick between serverless functions and always-on compute.
</p>
</div>
<div class="card">
<DecisionTree
title=""
subtitle=""
{nodes}
startNode="start"
/>
</div>
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">References</h2>
<ul class="space-y-2">
{#each references as ref}
<li>
<a class="text-surface-200 hover:text-white underline underline-offset-4" href={ref.href} target="_blank" rel="noreferrer">
{ref.label}
</a>
</li>
{/each}
</ul>
</div>
</div>

View file

@ -0,0 +1,124 @@
<script lang="ts">
import * as Icons from 'lucide-svelte';
import DecisionTree from '$lib/components/diagrams/DecisionTree.svelte';
const nodes = [
{
id: 'start',
type: 'question' as const,
text: 'Do you need to broadcast one message to many consumers?',
description: 'Fanout: many subscribers get the same event.',
yes: 'pubsub-answer',
no: 'queue-work'
},
{
id: 'queue-work',
type: 'question' as const,
text: 'Is the goal background work (tasks) handled by one worker?',
description: 'Job queues: resize images, send emails, run async processing.',
yes: 'simple-queue',
no: 'streaming'
},
{
id: 'simple-queue',
type: 'answer' as const,
text: 'Simple Managed Queue (e.g., SQS)',
icon: 'ListOrdered',
reasoning: 'Great default for task queues: reliable, easy ops, DLQs, and autoscaling consumers. Assume at-least-once delivery and handle duplicates.',
alternatives: [
'RabbitMQ if you need complex routing/patterns',
'Kafka if you need replay and long retention'
]
},
{
id: 'streaming',
type: 'question' as const,
text: 'Do you need to replay events or retain them for days/weeks?',
description: 'If you need audit trails, reprocessing, or event sourcing, retention matters.',
yes: 'kafka-answer',
no: 'broker-answer'
},
{
id: 'kafka-answer',
type: 'answer' as const,
text: 'Event Streaming (Kafka-like)',
icon: 'Activity',
reasoning: 'Use a log-based streaming platform when replay, ordering per partition, and high throughput are key requirements.',
alternatives: [
'Managed Kafka',
'Kinesis / Pub/Sub equivalents (cloud-native)',
'RabbitMQ for classic broker patterns'
]
},
{
id: 'broker-answer',
type: 'answer' as const,
text: 'Message Broker (RabbitMQ-like)',
icon: 'MessageSquare',
reasoning: 'Use a broker when you need flexible routing, per-message acknowledgments, and classic messaging patterns.',
alternatives: [
'Managed queue for simpler operations',
'Kafka for retention and reprocessing'
]
},
{
id: 'pubsub-answer',
type: 'answer' as const,
text: 'Pub/Sub Topic (e.g., SNS)',
icon: 'Bell',
reasoning: 'Best for fanout: publish once; subscribers (queues, webhooks, workers) each handle their copy independently.',
alternatives: [
'Kafka if you need retention/replay',
'Event bus products for schema governance'
]
}
];
const references = [
{ label: 'AWS SQS Developer Guide', href: 'https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/welcome.html' },
{ label: 'AWS SNS Developer Guide', href: 'https://docs.aws.amazon.com/sns/latest/dg/welcome.html' }
];
</script>
<svelte:head>
<title>Which Message Queue? - System Design Explorer</title>
</svelte:head>
<div class="max-w-6xl mx-auto space-y-8">
<div>
<div class="flex items-center gap-2 text-surface-500 text-sm mb-2">
<a href="/decisions" class="hover:text-surface-300">Decision Trees</a>
<Icons.ChevronRight class="w-4 h-4" />
<span class="text-surface-300">Which Message Queue?</span>
</div>
<h1 class="text-3xl font-bold text-surface-100">Which Message Queue?</h1>
<p class="text-surface-400 mt-2">
Decide between queue, pub/sub, broker, and event streaming based on your requirements.
</p>
</div>
<div class="card">
<DecisionTree
title=""
subtitle=""
{nodes}
startNode="start"
/>
</div>
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">References</h2>
<ul class="space-y-2">
{#each references as ref}
<li>
<a class="text-surface-200 hover:text-white underline underline-offset-4" href={ref.href} target="_blank" rel="noreferrer">
{ref.label}
</a>
</li>
{/each}
</ul>
<div class="mt-4 flex flex-wrap gap-3">
<a href="/compare/kafka-vs-rabbitmq" class="btn-primary">Kafka vs RabbitMQ</a>
</div>
</div>
</div>

View file

@ -0,0 +1,54 @@
<script lang="ts">
import * as Icons from 'lucide-svelte';
import { navigationItems, type NavItem } from '$lib/stores/navigation';
type IconComponent = typeof Icons.Box;
function getIcon(iconName: string): IconComponent {
const iconMap = Icons as unknown as Record<string, IconComponent>;
return iconMap[iconName] || Icons.Box;
}
const section = navigationItems.find((i) => i.id === 'fundamentals') as NavItem | undefined;
</script>
<svelte:head>
<title>Fundamentals - System Design Explorer</title>
</svelte:head>
<div class="max-w-6xl mx-auto space-y-8">
<div>
<div class="flex items-center gap-2 text-surface-500 text-sm mb-2">
<a href="/" class="hover:text-surface-300">Overview</a>
<Icons.ChevronRight class="w-4 h-4" />
<span class="text-surface-300">Fundamentals</span>
</div>
<h1 class="text-3xl font-bold text-surface-100">Fundamentals</h1>
<p class="text-surface-400 mt-2">
Core distributed systems concepts: consistency, scaling, and performance trade-offs.
</p>
</div>
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
{#each section?.children ?? [] as child}
{@const Icon = getIcon(child.icon)}
<a href={child.href} class="card-hover group">
<div class="flex items-start gap-4">
<div class="w-12 h-12 rounded-xl bg-surface-800 border border-surface-700 flex items-center justify-center flex-shrink-0 group-hover:border-surface-600 transition-colors duration-200">
<Icon class="w-6 h-6 text-surface-200" />
</div>
<div>
<h3 class="font-semibold text-surface-100 group-hover:text-white transition-colors">
{child.label}
</h3>
<p class="text-sm text-surface-400 mt-1">Interactive explainer</p>
</div>
</div>
<div class="mt-4 flex items-center text-sm text-surface-400 group-hover:text-surface-200">
<span>Open</span>
<Icons.ArrowRight class="w-4 h-4 ml-1 group-hover:translate-x-1 transition-transform" />
</div>
</a>
{/each}
</div>
</div>

View file

@ -0,0 +1,97 @@
<script lang="ts">
import * as Icons from 'lucide-svelte';
const references = [
{ label: 'CAP Theorem (in-app)', href: '/fundamentals/cap-theorem' },
{ label: 'DynamoDB Read Consistency', href: 'https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.ReadConsistency.html' },
{ label: 'Cloud Spanner: TrueTime & External Consistency', href: 'https://cloud.google.com/spanner/docs/true-time-external-consistency' }
];
</script>
<svelte:head>
<title>Consistency Models - System Design Explorer</title>
</svelte:head>
<div class="max-w-5xl mx-auto space-y-8">
<div>
<div class="flex items-center gap-2 text-surface-500 text-sm mb-2">
<a href="/fundamentals" class="hover:text-surface-300">Fundamentals</a>
<Icons.ChevronRight class="w-4 h-4" />
<span class="text-surface-300">Consistency Models</span>
</div>
<h1 class="text-3xl font-bold text-surface-100">Consistency Models</h1>
<p class="text-surface-400 mt-2">
How quickly reads reflect writes in a distributed system (and what you trade for it).
</p>
</div>
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">Common Models</h2>
<div class="grid md:grid-cols-2 gap-4">
<div class="p-4 rounded-lg bg-surface-800/50 border border-surface-700">
<h3 class="font-medium text-surface-200">Strong consistency</h3>
<p class="text-sm text-surface-400 mt-1">
Reads always see the latest successful write. Simple mental model; can cost availability/latency under partitions.
</p>
</div>
<div class="p-4 rounded-lg bg-surface-800/50 border border-surface-700">
<h3 class="font-medium text-surface-200">Eventual consistency</h3>
<p class="text-sm text-surface-400 mt-1">
Replicas converge over time. Higher availability and lower latency; clients may observe stale data temporarily.
</p>
</div>
<div class="p-4 rounded-lg bg-surface-800/50 border border-surface-700">
<h3 class="font-medium text-surface-200">Read-your-writes</h3>
<p class="text-sm text-surface-400 mt-1">
After a client writes, they will see their own write on subsequent reads (session guarantees).
</p>
</div>
<div class="p-4 rounded-lg bg-surface-800/50 border border-surface-700">
<h3 class="font-medium text-surface-200">Causal consistency</h3>
<p class="text-sm text-surface-400 mt-1">
Preserves cause→effect ordering (if A influenced B, everyone sees A before B) without full strong consistency.
</p>
</div>
</div>
</div>
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">Design Checklist</h2>
<ul class="space-y-2 text-surface-300">
<li class="flex gap-2"><Icons.Check class="w-4 h-4 mt-0.5 text-surface-400" />What user-visible anomalies are acceptable (stale reads, reordering, duplicates)?</li>
<li class="flex gap-2"><Icons.Check class="w-4 h-4 mt-0.5 text-surface-400" />Do you need monotonic reads (no going “back in time”)?</li>
<li class="flex gap-2"><Icons.Check class="w-4 h-4 mt-0.5 text-surface-400" />What happens during partitions: fail (CP) or serve stale (AP)?</li>
<li class="flex gap-2"><Icons.Check class="w-4 h-4 mt-0.5 text-surface-400" />Can clients handle retries/idempotency to compensate?</li>
</ul>
</div>
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">References</h2>
<ul class="space-y-2">
{#each references as ref}
<li>
<a
class="text-surface-200 hover:text-white underline underline-offset-4"
href={ref.href}
target={ref.href.startsWith('http') ? '_blank' : undefined}
rel={ref.href.startsWith('http') ? 'noreferrer' : undefined}
>
{ref.label}
</a>
</li>
{/each}
</ul>
<p class="text-xs text-surface-500 mt-4">
References are external; open in a new tab.
</p>
</div>
<div class="flex justify-between">
<a href="/fundamentals/cap-theorem" class="btn-secondary flex items-center gap-2">
<Icons.ArrowLeft class="w-4 h-4" /> CAP Theorem
</a>
<a href="/fundamentals/scaling" class="btn-primary flex items-center gap-2">
Scaling <Icons.ArrowRight class="w-4 h-4" />
</a>
</div>
</div>

View file

@ -0,0 +1,105 @@
<script lang="ts">
import * as Icons from 'lucide-svelte';
const concepts = [
{
title: 'Latency',
desc: 'Time for a single request to complete (p50/p95/p99). Users feel tail latency most.',
icon: 'Clock'
},
{
title: 'Throughput',
desc: 'Work completed per unit time (requests/sec, bytes/sec). Often limited by CPU, IO, or contention.',
icon: 'Gauge'
},
{
title: 'Queueing',
desc: 'As utilization approaches 100%, queues build and latency spikes. Keep headroom for bursts.',
icon: 'ListOrdered'
},
{
title: 'Backpressure',
desc: 'Push back on producers (shed load, rate limit, bounded queues) to protect downstream systems.',
icon: 'ArrowDownToLine'
}
] as const;
type IconComponent = typeof Icons.Box;
function getIcon(iconName: string): IconComponent {
const iconMap = Icons as unknown as Record<string, IconComponent>;
return iconMap[iconName] || Icons.Box;
}
const references = [
{ label: 'Kubernetes (resource requests/limits)', href: 'https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' },
{ label: 'AWS Lambda (performance & behavior)', href: 'https://docs.aws.amazon.com/lambda/latest/dg/welcome.html' }
];
</script>
<svelte:head>
<title>Latency vs Throughput - System Design Explorer</title>
</svelte:head>
<div class="max-w-5xl mx-auto space-y-8">
<div>
<div class="flex items-center gap-2 text-surface-500 text-sm mb-2">
<a href="/fundamentals" class="hover:text-surface-300">Fundamentals</a>
<Icons.ChevronRight class="w-4 h-4" />
<span class="text-surface-300">Latency vs Throughput</span>
</div>
<h1 class="text-3xl font-bold text-surface-100">Latency vs Throughput</h1>
<p class="text-surface-400 mt-2">
Fast single requests and high volume are related—but optimizing one can hurt the other.
</p>
</div>
<div class="grid md:grid-cols-2 gap-6">
{#each concepts as c}
{@const Icon = getIcon(c.icon)}
<div class="card">
<div class="flex items-start gap-3">
<div class="w-10 h-10 rounded-lg bg-surface-800 border border-surface-700 flex items-center justify-center">
<Icon class="w-5 h-5 text-surface-300" />
</div>
<div>
<h2 class="font-semibold text-surface-100">{c.title}</h2>
<p class="text-sm text-surface-400 mt-1">{c.desc}</p>
</div>
</div>
</div>
{/each}
</div>
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">Practical Tips</h2>
<ul class="space-y-2 text-surface-300">
<li class="flex gap-2"><Icons.Check class="w-4 h-4 mt-0.5 text-surface-400" />Track p50/p95/p99; p99 drives user experience and incident pain.</li>
<li class="flex gap-2"><Icons.Check class="w-4 h-4 mt-0.5 text-surface-400" />Bound queues and add timeouts; unbounded retries create latency collapse.</li>
<li class="flex gap-2"><Icons.Check class="w-4 h-4 mt-0.5 text-surface-400" />Use load shedding when overloaded to keep the system responsive for some users.</li>
<li class="flex gap-2"><Icons.Check class="w-4 h-4 mt-0.5 text-surface-400" />Prefer idempotent operations so retries dont amplify failures.</li>
</ul>
</div>
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">References</h2>
<ul class="space-y-2">
{#each references as ref}
<li>
<a class="text-surface-200 hover:text-white underline underline-offset-4" href={ref.href} target="_blank" rel="noreferrer">
{ref.label}
</a>
</li>
{/each}
</ul>
</div>
<div class="flex justify-between">
<a href="/fundamentals/scaling" class="btn-secondary flex items-center gap-2">
<Icons.ArrowLeft class="w-4 h-4" /> Scaling
</a>
<a href="/compute" class="btn-primary flex items-center gap-2">
Compute <Icons.ArrowRight class="w-4 h-4" />
</a>
</div>
</div>

View file

@ -0,0 +1,109 @@
<script lang="ts">
import * as Icons from 'lucide-svelte';
const strategies = [
{
title: 'Vertical scaling (scale up)',
desc: 'Bigger machine: more CPU/RAM/IO. Simple, but hard limits and single-node failures.',
icon: 'ArrowUp'
},
{
title: 'Horizontal scaling (scale out)',
desc: 'More machines behind a load balancer. Adds complexity: coordination, partitions, consistency.',
icon: 'Layers'
},
{
title: 'Caching',
desc: 'Reduce repeated work. Fast reads, but you must manage invalidation and staleness.',
icon: 'Zap'
},
{
title: 'Partitioning/sharding',
desc: 'Split data by key to distribute load. Requires careful key design, rebalancing, and cross-shard queries.',
icon: 'Split'
}
] as const;
type IconComponent = typeof Icons.Box;
function getIcon(iconName: string): IconComponent {
const iconMap = Icons as unknown as Record<string, IconComponent>;
return iconMap[iconName] || Icons.Box;
}
const references = [
{ label: 'AWS EC2 Instances (concepts)', href: 'https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Instances.html' },
{ label: 'Kubernetes (scaling concepts)', href: 'https://kubernetes.io/docs/concepts/workloads/controllers/deployment/' }
];
</script>
<svelte:head>
<title>Scaling - System Design Explorer</title>
</svelte:head>
<div class="max-w-5xl mx-auto space-y-8">
<div>
<div class="flex items-center gap-2 text-surface-500 text-sm mb-2">
<a href="/fundamentals" class="hover:text-surface-300">Fundamentals</a>
<Icons.ChevronRight class="w-4 h-4" />
<span class="text-surface-300">Scaling</span>
</div>
<h1 class="text-3xl font-bold text-surface-100">Scaling</h1>
<p class="text-surface-400 mt-2">
Techniques to handle more traffic and data while keeping reliability, latency, and cost under control.
</p>
</div>
<div class="grid md:grid-cols-2 gap-6">
{#each strategies as s}
{@const Icon = getIcon(s.icon)}
<div class="card">
<div class="flex items-start gap-3">
<div class="w-10 h-10 rounded-lg bg-surface-800 border border-surface-700 flex items-center justify-center">
<Icon class="w-5 h-5 text-surface-300" />
</div>
<div>
<h2 class="font-semibold text-surface-100">{s.title}</h2>
<p class="text-sm text-surface-400 mt-1">{s.desc}</p>
</div>
</div>
</div>
{/each}
</div>
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">Rule of Thumb</h2>
<div class="grid md:grid-cols-2 gap-4 text-surface-300">
<div class="p-4 rounded-lg bg-surface-800/50 border border-surface-700">
<h3 class="font-medium text-surface-200">Start simple</h3>
<p class="text-sm text-surface-400 mt-1">Scale up first when you can; introduce distributed complexity only when needed.</p>
</div>
<div class="p-4 rounded-lg bg-surface-800/50 border border-surface-700">
<h3 class="font-medium text-surface-200">Measure, then optimize</h3>
<p class="text-sm text-surface-400 mt-1">Use SLOs and profiling to find the real bottleneck: CPU, DB, network, locks, or tail latency.</p>
</div>
</div>
</div>
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">References</h2>
<ul class="space-y-2">
{#each references as ref}
<li>
<a class="text-surface-200 hover:text-white underline underline-offset-4" href={ref.href} target="_blank" rel="noreferrer">
{ref.label}
</a>
</li>
{/each}
</ul>
</div>
<div class="flex justify-between">
<a href="/fundamentals/consistency" class="btn-secondary flex items-center gap-2">
<Icons.ArrowLeft class="w-4 h-4" /> Consistency Models
</a>
<a href="/fundamentals/latency" class="btn-primary flex items-center gap-2">
Latency vs Throughput <Icons.ArrowRight class="w-4 h-4" />
</a>
</div>
</div>

View file

@ -0,0 +1,54 @@
<script lang="ts">
import * as Icons from 'lucide-svelte';
import { navigationItems, type NavItem } from '$lib/stores/navigation';
type IconComponent = typeof Icons.Box;
function getIcon(iconName: string): IconComponent {
const iconMap = Icons as unknown as Record<string, IconComponent>;
return iconMap[iconName] || Icons.Box;
}
const section = navigationItems.find((i) => i.id === 'messaging') as NavItem | undefined;
</script>
<svelte:head>
<title>Messaging - System Design Explorer</title>
</svelte:head>
<div class="max-w-6xl mx-auto space-y-8">
<div>
<div class="flex items-center gap-2 text-surface-500 text-sm mb-2">
<a href="/" class="hover:text-surface-300">Overview</a>
<Icons.ChevronRight class="w-4 h-4" />
<span class="text-surface-300">Messaging</span>
</div>
<h1 class="text-3xl font-bold text-surface-100">Messaging</h1>
<p class="text-surface-400 mt-2">
Decouple services with asynchronous communication: queues, pub/sub, and event-driven patterns.
</p>
</div>
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
{#each section?.children ?? [] as child}
{@const Icon = getIcon(child.icon)}
<a href={child.href} class="card-hover group">
<div class="flex items-start gap-4">
<div class="w-12 h-12 rounded-xl bg-surface-800 border border-surface-700 flex items-center justify-center flex-shrink-0 group-hover:border-surface-600 transition-colors duration-200">
<Icon class="w-6 h-6 text-surface-200" />
</div>
<div>
<h3 class="font-semibold text-surface-100 group-hover:text-white transition-colors">
{child.label}
</h3>
<p class="text-sm text-surface-400 mt-1">Concepts + trade-offs</p>
</div>
</div>
<div class="mt-4 flex items-center text-sm text-surface-400 group-hover:text-surface-200">
<span>Open</span>
<Icons.ArrowRight class="w-4 h-4 ml-1 group-hover:translate-x-1 transition-transform" />
</div>
</a>
{/each}
</div>
</div>

View file

@ -0,0 +1,51 @@
<script lang="ts">
import * as Icons from 'lucide-svelte';
const principles = [
{ title: 'Events are facts', desc: 'Model immutable “what happened” records; derive state from events when useful.' },
{ title: 'Loose coupling', desc: 'Producers dont know consumers; schemas and contracts become critical.' },
{ title: 'Async boundaries', desc: 'Failures become retries, DLQs, and compensations—not simple rollbacks.' },
{ title: 'Observability', desc: 'Trace IDs, idempotency keys, and event lineage make debugging possible.' }
] as const;
const references = [
{ label: 'Kafka (for event streaming)', href: '/compare/kafka-vs-rabbitmq' }
];
</script>
<svelte:head>
<title>Event-Driven Architecture - System Design Explorer</title>
</svelte:head>
<div class="max-w-5xl mx-auto space-y-8">
<div>
<div class="flex items-center gap-2 text-surface-500 text-sm mb-2">
<a href="/messaging" class="hover:text-surface-300">Messaging</a>
<Icons.ChevronRight class="w-4 h-4" />
<span class="text-surface-300">Event-Driven</span>
</div>
<h1 class="text-3xl font-bold text-surface-100">Event-Driven Architecture</h1>
<p class="text-surface-400 mt-2">
Systems communicate by emitting and reacting to events, enabling fanout, resilience, and evolution over time.
</p>
</div>
<div class="grid md:grid-cols-2 gap-6">
{#each principles as p}
<div class="card">
<h2 class="text-lg font-semibold text-surface-100">{p.title}</h2>
<p class="text-sm text-surface-400 mt-2">{p.desc}</p>
</div>
{/each}
</div>
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">Next steps</h2>
<div class="flex flex-wrap gap-3">
{#each references as ref}
<a class="btn-primary" href={ref.href}>{ref.label}</a>
{/each}
</div>
</div>
</div>

View file

@ -0,0 +1,58 @@
<script lang="ts">
import * as Icons from 'lucide-svelte';
const references = [
{ label: 'AWS SNS Developer Guide', href: 'https://docs.aws.amazon.com/sns/latest/dg/welcome.html' }
];
</script>
<svelte:head>
<title>Pub/Sub - System Design Explorer</title>
</svelte:head>
<div class="max-w-5xl mx-auto space-y-8">
<div>
<div class="flex items-center gap-2 text-surface-500 text-sm mb-2">
<a href="/messaging" class="hover:text-surface-300">Messaging</a>
<Icons.ChevronRight class="w-4 h-4" />
<span class="text-surface-300">Pub/Sub</span>
</div>
<h1 class="text-3xl font-bold text-surface-100">Pub/Sub</h1>
<p class="text-surface-400 mt-2">
Publish events once; multiple subscribers consume independently. Great for fanout and integrations.
</p>
</div>
<div class="grid md:grid-cols-2 gap-6">
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">When to use</h2>
<ul class="space-y-2 text-surface-300">
<li class="flex gap-2"><Icons.Check class="w-4 h-4 mt-0.5 text-surface-400" />One event triggers multiple side effects</li>
<li class="flex gap-2"><Icons.Check class="w-4 h-4 mt-0.5 text-surface-400" />You want to add consumers without changing producers</li>
<li class="flex gap-2"><Icons.Check class="w-4 h-4 mt-0.5 text-surface-400" />Integrations with email/SMS/webhooks/queues</li>
</ul>
</div>
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">Trade-offs</h2>
<ul class="space-y-2 text-surface-300">
<li class="flex gap-2"><Icons.AlertTriangle class="w-4 h-4 mt-0.5 text-surface-400" />Harder to reason about end-to-end flows</li>
<li class="flex gap-2"><Icons.AlertTriangle class="w-4 h-4 mt-0.5 text-surface-400" />Delivery semantics vary by system and subscription type</li>
<li class="flex gap-2"><Icons.AlertTriangle class="w-4 h-4 mt-0.5 text-surface-400" />You still need idempotent handlers</li>
</ul>
</div>
</div>
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">References</h2>
<ul class="space-y-2">
{#each references as ref}
<li>
<a class="text-surface-200 hover:text-white underline underline-offset-4" href={ref.href} target="_blank" rel="noreferrer">
{ref.label}
</a>
</li>
{/each}
</ul>
</div>
</div>

View file

@ -0,0 +1,61 @@
<script lang="ts">
import * as Icons from 'lucide-svelte';
const references = [
{ label: 'AWS SQS Developer Guide', href: 'https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/welcome.html' }
];
</script>
<svelte:head>
<title>Message Queues - System Design Explorer</title>
</svelte:head>
<div class="max-w-5xl mx-auto space-y-8">
<div>
<div class="flex items-center gap-2 text-surface-500 text-sm mb-2">
<a href="/messaging" class="hover:text-surface-300">Messaging</a>
<Icons.ChevronRight class="w-4 h-4" />
<span class="text-surface-300">Message Queues</span>
</div>
<h1 class="text-3xl font-bold text-surface-100">Message Queues</h1>
<p class="text-surface-400 mt-2">
Queue-based messaging for background work: one message is typically handled by one consumer.
</p>
</div>
<div class="grid md:grid-cols-2 gap-6">
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">What you get</h2>
<ul class="space-y-2 text-surface-300">
<li class="flex gap-2"><Icons.Check class="w-4 h-4 mt-0.5 text-surface-400" />Decoupling between producers and workers</li>
<li class="flex gap-2"><Icons.Check class="w-4 h-4 mt-0.5 text-surface-400" />Smoothing bursty load (buffering)</li>
<li class="flex gap-2"><Icons.Check class="w-4 h-4 mt-0.5 text-surface-400" />Retry + DLQ patterns for failures</li>
</ul>
</div>
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">Design gotchas</h2>
<ul class="space-y-2 text-surface-300">
<li class="flex gap-2"><Icons.AlertTriangle class="w-4 h-4 mt-0.5 text-surface-400" />At-least-once delivery means duplicates; consumers must be idempotent.</li>
<li class="flex gap-2"><Icons.AlertTriangle class="w-4 h-4 mt-0.5 text-surface-400" />Visibility timeouts and retries can amplify load if misconfigured.</li>
<li class="flex gap-2"><Icons.AlertTriangle class="w-4 h-4 mt-0.5 text-surface-400" />Ordering is rarely global; assume partial ordering at best.</li>
</ul>
</div>
</div>
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">References</h2>
<ul class="space-y-2">
{#each references as ref}
<li>
<a class="text-surface-200 hover:text-white underline underline-offset-4" href={ref.href} target="_blank" rel="noreferrer">
{ref.label}
</a>
</li>
{/each}
</ul>
<div class="mt-4">
<a href="/decisions/which-queue" class="btn-primary">Which Message Queue?</a>
</div>
</div>
</div>

View file

@ -0,0 +1,54 @@
<script lang="ts">
import * as Icons from 'lucide-svelte';
import { navigationItems, type NavItem } from '$lib/stores/navigation';
type IconComponent = typeof Icons.Box;
function getIcon(iconName: string): IconComponent {
const iconMap = Icons as unknown as Record<string, IconComponent>;
return iconMap[iconName] || Icons.Box;
}
const section = navigationItems.find((i) => i.id === 'networking') as NavItem | undefined;
</script>
<svelte:head>
<title>Networking - System Design Explorer</title>
</svelte:head>
<div class="max-w-6xl mx-auto space-y-8">
<div>
<div class="flex items-center gap-2 text-surface-500 text-sm mb-2">
<a href="/" class="hover:text-surface-300">Overview</a>
<Icons.ChevronRight class="w-4 h-4" />
<span class="text-surface-300">Networking</span>
</div>
<h1 class="text-3xl font-bold text-surface-100">Networking</h1>
<p class="text-surface-400 mt-2">
How traffic reaches your system: VPCs, DNS, load balancing, and CDNs.
</p>
</div>
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
{#each section?.children ?? [] as child}
{@const Icon = getIcon(child.icon)}
<a href={child.href} class="card-hover group">
<div class="flex items-start gap-4">
<div class="w-12 h-12 rounded-xl bg-surface-800 border border-surface-700 flex items-center justify-center flex-shrink-0 group-hover:border-surface-600 transition-colors duration-200">
<Icon class="w-6 h-6 text-surface-200" />
</div>
<div>
<h3 class="font-semibold text-surface-100 group-hover:text-white transition-colors">
{child.label}
</h3>
<p class="text-sm text-surface-400 mt-1">Concepts + trade-offs</p>
</div>
</div>
<div class="mt-4 flex items-center text-sm text-surface-400 group-hover:text-surface-200">
<span>Open</span>
<Icons.ArrowRight class="w-4 h-4 ml-1 group-hover:translate-x-1 transition-transform" />
</div>
</a>
{/each}
</div>
</div>

View file

@ -0,0 +1,55 @@
<script lang="ts">
import * as Icons from 'lucide-svelte';
const benefits = [
{ title: 'Lower latency', desc: 'Serve content from edge locations closer to users.' },
{ title: 'Offload origin', desc: 'Cache static content and reduce traffic to your core services.' },
{ title: 'DDoS absorption', desc: 'Edge networks can absorb and filter abuse before it reaches your origin.' },
{ title: 'TLS at the edge', desc: 'Terminate TLS close to users and centralize cert management.' }
] as const;
const references = [
{ label: 'Amazon CloudFront Developer Guide', href: 'https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Introduction.html' }
];
</script>
<svelte:head>
<title>CDN - System Design Explorer</title>
</svelte:head>
<div class="max-w-5xl mx-auto space-y-8">
<div>
<div class="flex items-center gap-2 text-surface-500 text-sm mb-2">
<a href="/networking" class="hover:text-surface-300">Networking</a>
<Icons.ChevronRight class="w-4 h-4" />
<span class="text-surface-300">CDN</span>
</div>
<h1 class="text-3xl font-bold text-surface-100">CDN (Content Delivery Network)</h1>
<p class="text-surface-400 mt-2">
A globally distributed caching layer that accelerates content delivery and protects your origin.
</p>
</div>
<div class="grid md:grid-cols-2 gap-6">
{#each benefits as b}
<div class="card">
<h2 class="text-lg font-semibold text-surface-100">{b.title}</h2>
<p class="text-sm text-surface-400 mt-2">{b.desc}</p>
</div>
{/each}
</div>
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">References</h2>
<ul class="space-y-2">
{#each references as ref}
<li>
<a class="text-surface-200 hover:text-white underline underline-offset-4" href={ref.href} target="_blank" rel="noreferrer">
{ref.label}
</a>
</li>
{/each}
</ul>
</div>
</div>

View file

@ -0,0 +1,77 @@
<script lang="ts">
import * as Icons from 'lucide-svelte';
import GuidedWalkthrough from '$lib/components/diagrams/GuidedWalkthrough.svelte';
const steps = [
{
id: 'cidr',
title: 'Pick a CIDR range',
description: 'Choose an IP space large enough for future growth (and to avoid overlaps).',
icon: 'Map'
},
{
id: 'subnets',
title: 'Create subnets',
description: 'Split the VPC into subnets (often per availability zone). Use public for edge, private for services.',
icon: 'Grid'
},
{
id: 'routing',
title: 'Add routing',
description: 'Route tables decide where traffic goes: to an internet gateway, NAT, VPN, or internal targets.',
icon: 'Route'
},
{
id: 'security',
title: 'Apply security controls',
description: 'Use security groups / network ACLs to restrict traffic; expose only whats needed.',
icon: 'Shield'
}
];
const references = [
{ label: 'AWS VPC User Guide', href: 'https://docs.aws.amazon.com/vpc/latest/userguide/what-is-amazon-vpc.html' }
];
</script>
<svelte:head>
<title>VPC & Subnets - System Design Explorer</title>
</svelte:head>
<div class="max-w-6xl mx-auto space-y-8">
<div>
<div class="flex items-center gap-2 text-surface-500 text-sm mb-2">
<a href="/networking" class="hover:text-surface-300">Networking</a>
<Icons.ChevronRight class="w-4 h-4" />
<span class="text-surface-300">VPC & Subnets</span>
</div>
<h1 class="text-3xl font-bold text-surface-100">VPC & Subnets</h1>
<p class="text-surface-400 mt-2">
A private network boundary for your workloads: address space, segmentation, and routing.
</p>
</div>
<GuidedWalkthrough title="A simple VPC mental model" subtitle="The minimum you should be able to explain in an interview" {steps} />
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">References</h2>
<ul class="space-y-2">
{#each references as ref}
<li>
<a class="text-surface-200 hover:text-white underline underline-offset-4" href={ref.href} target="_blank" rel="noreferrer">
{ref.label}
</a>
</li>
{/each}
</ul>
</div>
<div class="flex justify-between">
<a href="/networking" class="btn-secondary flex items-center gap-2">
<Icons.ArrowLeft class="w-4 h-4" /> Networking
</a>
<a href="/networking/dns" class="btn-primary flex items-center gap-2">
DNS <Icons.ArrowRight class="w-4 h-4" />
</a>
</div>
</div>

View file

@ -0,0 +1,54 @@
<script lang="ts">
import * as Icons from 'lucide-svelte';
import { navigationItems, type NavItem } from '$lib/stores/navigation';
type IconComponent = typeof Icons.Box;
function getIcon(iconName: string): IconComponent {
const iconMap = Icons as unknown as Record<string, IconComponent>;
return iconMap[iconName] || Icons.Box;
}
const section = navigationItems.find((i) => i.id === 'security') as NavItem | undefined;
</script>
<svelte:head>
<title>Security - System Design Explorer</title>
</svelte:head>
<div class="max-w-6xl mx-auto space-y-8">
<div>
<div class="flex items-center gap-2 text-surface-500 text-sm mb-2">
<a href="/" class="hover:text-surface-300">Overview</a>
<Icons.ChevronRight class="w-4 h-4" />
<span class="text-surface-300">Security</span>
</div>
<h1 class="text-3xl font-bold text-surface-100">Security</h1>
<p class="text-surface-400 mt-2">
Identity, encryption, and secrets: the baseline controls behind most reliable systems.
</p>
</div>
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
{#each section?.children ?? [] as child}
{@const Icon = getIcon(child.icon)}
<a href={child.href} class="card-hover group">
<div class="flex items-start gap-4">
<div class="w-12 h-12 rounded-xl bg-surface-800 border border-surface-700 flex items-center justify-center flex-shrink-0 group-hover:border-surface-600 transition-colors duration-200">
<Icon class="w-6 h-6 text-surface-200" />
</div>
<div>
<h3 class="font-semibold text-surface-100 group-hover:text-white transition-colors">
{child.label}
</h3>
<p class="text-sm text-surface-400 mt-1">Core concepts</p>
</div>
</div>
<div class="mt-4 flex items-center text-sm text-surface-400 group-hover:text-surface-200">
<span>Open</span>
<Icons.ArrowRight class="w-4 h-4 ml-1 group-hover:translate-x-1 transition-transform" />
</div>
</a>
{/each}
</div>
</div>

View file

@ -0,0 +1,54 @@
<script lang="ts">
import * as Icons from 'lucide-svelte';
const references = [
{ label: 'AWS KMS Developer Guide', href: 'https://docs.aws.amazon.com/kms/latest/developerguide/overview.html' }
];
</script>
<svelte:head>
<title>Encryption - System Design Explorer</title>
</svelte:head>
<div class="max-w-5xl mx-auto space-y-8">
<div>
<div class="flex items-center gap-2 text-surface-500 text-sm mb-2">
<a href="/security" class="hover:text-surface-300">Security</a>
<Icons.ChevronRight class="w-4 h-4" />
<span class="text-surface-300">Encryption</span>
</div>
<h1 class="text-3xl font-bold text-surface-100">Encryption</h1>
<p class="text-surface-400 mt-2">
Protect data in transit and at rest. The hard part is key management and access control—not the cipher.
</p>
</div>
<div class="grid md:grid-cols-2 gap-6">
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">In transit</h2>
<p class="text-surface-300 text-sm">
Use TLS everywhere (client→edge, edge→service, service→service). Rotate certificates and enforce modern ciphers.
</p>
</div>
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">At rest</h2>
<p class="text-surface-300 text-sm">
Encrypt disks, databases, and object storage. Centralize keys, control access, and log usage.
</p>
</div>
</div>
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">References</h2>
<ul class="space-y-2">
{#each references as ref}
<li>
<a class="text-surface-200 hover:text-white underline underline-offset-4" href={ref.href} target="_blank" rel="noreferrer">
{ref.label}
</a>
</li>
{/each}
</ul>
</div>
</div>

View file

@ -0,0 +1,59 @@
<script lang="ts">
import * as Icons from 'lucide-svelte';
const references = [
{ label: 'AWS IAM User Guide', href: 'https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction.html' }
];
</script>
<svelte:head>
<title>IAM - System Design Explorer</title>
</svelte:head>
<div class="max-w-5xl mx-auto space-y-8">
<div>
<div class="flex items-center gap-2 text-surface-500 text-sm mb-2">
<a href="/security" class="hover:text-surface-300">Security</a>
<Icons.ChevronRight class="w-4 h-4" />
<span class="text-surface-300">IAM</span>
</div>
<h1 class="text-3xl font-bold text-surface-100">IAM (Identity & Access Management)</h1>
<p class="text-surface-400 mt-2">
Define who can do what on which resources. Start with least privilege and strong auditability.
</p>
</div>
<div class="grid md:grid-cols-2 gap-6">
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">Core building blocks</h2>
<ul class="space-y-2 text-surface-300">
<li class="flex gap-2"><Icons.Check class="w-4 h-4 mt-0.5 text-surface-400" />Identities: users, roles, workloads</li>
<li class="flex gap-2"><Icons.Check class="w-4 h-4 mt-0.5 text-surface-400" />Policies: allow/deny rules</li>
<li class="flex gap-2"><Icons.Check class="w-4 h-4 mt-0.5 text-surface-400" />Authentication vs authorization</li>
<li class="flex gap-2"><Icons.Check class="w-4 h-4 mt-0.5 text-surface-400" />Audit logs and rotation</li>
</ul>
</div>
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">Pitfalls to avoid</h2>
<ul class="space-y-2 text-surface-300">
<li class="flex gap-2"><Icons.AlertTriangle class="w-4 h-4 mt-0.5 text-surface-400" />Over-broad permissions (“*:*”)</li>
<li class="flex gap-2"><Icons.AlertTriangle class="w-4 h-4 mt-0.5 text-surface-400" />Long-lived secrets instead of short-lived tokens</li>
<li class="flex gap-2"><Icons.AlertTriangle class="w-4 h-4 mt-0.5 text-surface-400" />No separation between prod and non-prod</li>
</ul>
</div>
</div>
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">References</h2>
<ul class="space-y-2">
{#each references as ref}
<li>
<a class="text-surface-200 hover:text-white underline underline-offset-4" href={ref.href} target="_blank" rel="noreferrer">
{ref.label}
</a>
</li>
{/each}
</ul>
</div>
</div>

View file

@ -0,0 +1,58 @@
<script lang="ts">
import * as Icons from 'lucide-svelte';
const references = [
{ label: 'AWS Secrets Manager User Guide', href: 'https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html' }
];
</script>
<svelte:head>
<title>Secrets Management - System Design Explorer</title>
</svelte:head>
<div class="max-w-5xl mx-auto space-y-8">
<div>
<div class="flex items-center gap-2 text-surface-500 text-sm mb-2">
<a href="/security" class="hover:text-surface-300">Security</a>
<Icons.ChevronRight class="w-4 h-4" />
<span class="text-surface-300">Secrets Management</span>
</div>
<h1 class="text-3xl font-bold text-surface-100">Secrets Management</h1>
<p class="text-surface-400 mt-2">
Store and rotate credentials safely. Prefer short-lived credentials and least privilege over static keys.
</p>
</div>
<div class="grid md:grid-cols-2 gap-6">
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">Do</h2>
<ul class="space-y-2 text-surface-300">
<li class="flex gap-2"><Icons.Check class="w-4 h-4 mt-0.5 text-surface-400" />Centralize secrets and audit access</li>
<li class="flex gap-2"><Icons.Check class="w-4 h-4 mt-0.5 text-surface-400" />Rotate automatically and regularly</li>
<li class="flex gap-2"><Icons.Check class="w-4 h-4 mt-0.5 text-surface-400" />Use workload identity where possible</li>
</ul>
</div>
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">Avoid</h2>
<ul class="space-y-2 text-surface-300">
<li class="flex gap-2"><Icons.AlertTriangle class="w-4 h-4 mt-0.5 text-surface-400" />Hardcoding secrets in code or images</li>
<li class="flex gap-2"><Icons.AlertTriangle class="w-4 h-4 mt-0.5 text-surface-400" />Long-lived access keys with broad permissions</li>
<li class="flex gap-2"><Icons.AlertTriangle class="w-4 h-4 mt-0.5 text-surface-400" />Sharing credentials across environments</li>
</ul>
</div>
</div>
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">References</h2>
<ul class="space-y-2">
{#each references as ref}
<li>
<a class="text-surface-200 hover:text-white underline underline-offset-4" href={ref.href} target="_blank" rel="noreferrer">
{ref.label}
</a>
</li>
{/each}
</ul>
</div>
</div>

View file

@ -0,0 +1,54 @@
<script lang="ts">
import * as Icons from 'lucide-svelte';
import { navigationItems, type NavItem } from '$lib/stores/navigation';
type IconComponent = typeof Icons.Box;
function getIcon(iconName: string): IconComponent {
const iconMap = Icons as unknown as Record<string, IconComponent>;
return iconMap[iconName] || Icons.Box;
}
const section = navigationItems.find((i) => i.id === 'storage') as NavItem | undefined;
</script>
<svelte:head>
<title>Storage - System Design Explorer</title>
</svelte:head>
<div class="max-w-6xl mx-auto space-y-8">
<div>
<div class="flex items-center gap-2 text-surface-500 text-sm mb-2">
<a href="/" class="hover:text-surface-300">Overview</a>
<Icons.ChevronRight class="w-4 h-4" />
<span class="text-surface-300">Storage</span>
</div>
<h1 class="text-3xl font-bold text-surface-100">Storage</h1>
<p class="text-surface-400 mt-2">
Pick the right storage interface: object, block, or file—each fits a different access pattern.
</p>
</div>
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
{#each section?.children ?? [] as child}
{@const Icon = getIcon(child.icon)}
<a href={child.href} class="card-hover group">
<div class="flex items-start gap-4">
<div class="w-12 h-12 rounded-xl bg-surface-800 border border-surface-700 flex items-center justify-center flex-shrink-0 group-hover:border-surface-600 transition-colors duration-200">
<Icon class="w-6 h-6 text-surface-200" />
</div>
<div>
<h3 class="font-semibold text-surface-100 group-hover:text-white transition-colors">
{child.label}
</h3>
<p class="text-sm text-surface-400 mt-1">Concepts + trade-offs</p>
</div>
</div>
<div class="mt-4 flex items-center text-sm text-surface-400 group-hover:text-surface-200">
<span>Open</span>
<Icons.ArrowRight class="w-4 h-4 ml-1 group-hover:translate-x-1 transition-transform" />
</div>
</a>
{/each}
</div>
</div>

View file

@ -0,0 +1,56 @@
<script lang="ts">
import * as Icons from 'lucide-svelte';
const references = [
{ label: 'Amazon EBS User Guide', href: 'https://docs.aws.amazon.com/ebs/latest/userguide/what-is-ebs.html' }
];
</script>
<svelte:head>
<title>Block Storage - System Design Explorer</title>
</svelte:head>
<div class="max-w-5xl mx-auto space-y-8">
<div>
<div class="flex items-center gap-2 text-surface-500 text-sm mb-2">
<a href="/storage" class="hover:text-surface-300">Storage</a>
<Icons.ChevronRight class="w-4 h-4" />
<span class="text-surface-300">Block Storage</span>
</div>
<h1 class="text-3xl font-bold text-surface-100">Block Storage</h1>
<p class="text-surface-400 mt-2">
A virtual disk you attach to a machine. Low-latency random reads/writes; typically single-writer.
</p>
</div>
<div class="grid md:grid-cols-2 gap-6">
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">Best for</h2>
<ul class="space-y-2 text-surface-300">
<li class="flex gap-2"><Icons.Check class="w-4 h-4 mt-0.5 text-surface-400" />Databases and workloads needing random IO</li>
<li class="flex gap-2"><Icons.Check class="w-4 h-4 mt-0.5 text-surface-400" />Boot volumes and durable VM state</li>
</ul>
</div>
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">Trade-offs</h2>
<ul class="space-y-2 text-surface-300">
<li class="flex gap-2"><Icons.AlertTriangle class="w-4 h-4 mt-0.5 text-surface-400" />Often attached to one host/zone at a time</li>
<li class="flex gap-2"><Icons.AlertTriangle class="w-4 h-4 mt-0.5 text-surface-400" />Scaling is vertical; sharding/replication required for horizontal scale</li>
</ul>
</div>
</div>
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">References</h2>
<ul class="space-y-2">
{#each references as ref}
<li>
<a class="text-surface-200 hover:text-white underline underline-offset-4" href={ref.href} target="_blank" rel="noreferrer">
{ref.label}
</a>
</li>
{/each}
</ul>
</div>
</div>

View file

@ -0,0 +1,57 @@
<script lang="ts">
import * as Icons from 'lucide-svelte';
const references = [
{ label: 'Amazon EFS User Guide', href: 'https://docs.aws.amazon.com/efs/latest/ug/whatisefs.html' }
];
</script>
<svelte:head>
<title>File Storage - System Design Explorer</title>
</svelte:head>
<div class="max-w-5xl mx-auto space-y-8">
<div>
<div class="flex items-center gap-2 text-surface-500 text-sm mb-2">
<a href="/storage" class="hover:text-surface-300">Storage</a>
<Icons.ChevronRight class="w-4 h-4" />
<span class="text-surface-300">File Storage</span>
</div>
<h1 class="text-3xl font-bold text-surface-100">File Storage</h1>
<p class="text-surface-400 mt-2">
Shared filesystem semantics (often POSIX-like) over the network. Multiple clients can mount and read/write.
</p>
</div>
<div class="grid md:grid-cols-2 gap-6">
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">Best for</h2>
<ul class="space-y-2 text-surface-300">
<li class="flex gap-2"><Icons.Check class="w-4 h-4 mt-0.5 text-surface-400" />Shared assets (media processing, ML models)</li>
<li class="flex gap-2"><Icons.Check class="w-4 h-4 mt-0.5 text-surface-400" />Legacy apps expecting a filesystem</li>
<li class="flex gap-2"><Icons.Check class="w-4 h-4 mt-0.5 text-surface-400" />Multiple compute nodes reading the same data</li>
</ul>
</div>
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">Trade-offs</h2>
<ul class="space-y-2 text-surface-300">
<li class="flex gap-2"><Icons.AlertTriangle class="w-4 h-4 mt-0.5 text-surface-400" />Network latency and throughput constraints</li>
<li class="flex gap-2"><Icons.AlertTriangle class="w-4 h-4 mt-0.5 text-surface-400" />Locking/coordination can limit scale for heavy writes</li>
</ul>
</div>
</div>
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">References</h2>
<ul class="space-y-2">
{#each references as ref}
<li>
<a class="text-surface-200 hover:text-white underline underline-offset-4" href={ref.href} target="_blank" rel="noreferrer">
{ref.label}
</a>
</li>
{/each}
</ul>
</div>
</div>

View file

@ -0,0 +1,58 @@
<script lang="ts">
import * as Icons from 'lucide-svelte';
const references = [
{ label: 'Amazon S3 User Guide', href: 'https://docs.aws.amazon.com/AmazonS3/latest/userguide/Welcome.html' }
];
</script>
<svelte:head>
<title>Object Storage - System Design Explorer</title>
</svelte:head>
<div class="max-w-5xl mx-auto space-y-8">
<div>
<div class="flex items-center gap-2 text-surface-500 text-sm mb-2">
<a href="/storage" class="hover:text-surface-300">Storage</a>
<Icons.ChevronRight class="w-4 h-4" />
<span class="text-surface-300">Object Storage</span>
</div>
<h1 class="text-3xl font-bold text-surface-100">Object Storage</h1>
<p class="text-surface-400 mt-2">
Store blobs (objects) addressed by key, typically accessed via an HTTP API. Great durability and scale.
</p>
</div>
<div class="grid md:grid-cols-2 gap-6">
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">Best for</h2>
<ul class="space-y-2 text-surface-300">
<li class="flex gap-2"><Icons.Check class="w-4 h-4 mt-0.5 text-surface-400" />Images, video, backups, logs, data lakes</li>
<li class="flex gap-2"><Icons.Check class="w-4 h-4 mt-0.5 text-surface-400" />Static web assets + CDN</li>
<li class="flex gap-2"><Icons.Check class="w-4 h-4 mt-0.5 text-surface-400" />Immutable or append-like workflows</li>
</ul>
</div>
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">Trade-offs</h2>
<ul class="space-y-2 text-surface-300">
<li class="flex gap-2"><Icons.AlertTriangle class="w-4 h-4 mt-0.5 text-surface-400" />Not a POSIX filesystem (no in-place edits like a disk)</li>
<li class="flex gap-2"><Icons.AlertTriangle class="w-4 h-4 mt-0.5 text-surface-400" />Higher per-operation latency than local disk</li>
<li class="flex gap-2"><Icons.AlertTriangle class="w-4 h-4 mt-0.5 text-surface-400" />Consistency semantics depend on provider/features</li>
</ul>
</div>
</div>
<div class="card">
<h2 class="text-lg font-semibold text-surface-100 mb-3">References</h2>
<ul class="space-y-2">
{#each references as ref}
<li>
<a class="text-surface-200 hover:text-white underline underline-offset-4" href={ref.href} target="_blank" rel="noreferrer">
{ref.label}
</a>
</li>
{/each}
</ul>
</div>
</div>