mirror of
https://github.com/harivansh-afk/system-design.git
synced 2026-04-15 03:00:48 +00:00
new routes
This commit is contained in:
parent
f0fee8e40b
commit
e7e87a3519
30 changed files with 2132 additions and 0 deletions
54
src/routes/compare/+page.svelte
Normal file
54
src/routes/compare/+page.svelte
Normal 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>
|
||||
|
||||
155
src/routes/compare/api-design/+page.svelte
Normal file
155
src/routes/compare/api-design/+page.svelte
Normal 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>
|
||||
54
src/routes/compute/+page.svelte
Normal file
54
src/routes/compute/+page.svelte
Normal 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>
|
||||
|
||||
75
src/routes/compute/containers/+page.svelte
Normal file
75
src/routes/compute/containers/+page.svelte
Normal 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>
|
||||
|
||||
107
src/routes/compute/virtual-machines/+page.svelte
Normal file
107
src/routes/compute/virtual-machines/+page.svelte
Normal 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: 'You’re 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>
|
||||
54
src/routes/databases/+page.svelte
Normal file
54
src/routes/databases/+page.svelte
Normal 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>
|
||||
|
||||
62
src/routes/databases/nosql/+page.svelte
Normal file
62
src/routes/databases/nosql/+page.svelte
Normal 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>
|
||||
59
src/routes/databases/sql/+page.svelte
Normal file
59
src/routes/databases/sql/+page.svelte
Normal 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>
|
||||
54
src/routes/decisions/+page.svelte
Normal file
54
src/routes/decisions/+page.svelte
Normal 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>
|
||||
|
||||
109
src/routes/decisions/serverless/+page.svelte
Normal file
109
src/routes/decisions/serverless/+page.svelte
Normal 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>
|
||||
124
src/routes/decisions/which-queue/+page.svelte
Normal file
124
src/routes/decisions/which-queue/+page.svelte
Normal 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>
|
||||
54
src/routes/fundamentals/+page.svelte
Normal file
54
src/routes/fundamentals/+page.svelte
Normal 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>
|
||||
|
||||
97
src/routes/fundamentals/consistency/+page.svelte
Normal file
97
src/routes/fundamentals/consistency/+page.svelte
Normal 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>
|
||||
105
src/routes/fundamentals/latency/+page.svelte
Normal file
105
src/routes/fundamentals/latency/+page.svelte
Normal 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 don’t 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>
|
||||
|
||||
109
src/routes/fundamentals/scaling/+page.svelte
Normal file
109
src/routes/fundamentals/scaling/+page.svelte
Normal 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>
|
||||
|
||||
54
src/routes/messaging/+page.svelte
Normal file
54
src/routes/messaging/+page.svelte
Normal 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>
|
||||
|
||||
51
src/routes/messaging/event-driven/+page.svelte
Normal file
51
src/routes/messaging/event-driven/+page.svelte
Normal 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 don’t 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>
|
||||
|
||||
58
src/routes/messaging/pubsub/+page.svelte
Normal file
58
src/routes/messaging/pubsub/+page.svelte
Normal 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>
|
||||
|
||||
61
src/routes/messaging/queues/+page.svelte
Normal file
61
src/routes/messaging/queues/+page.svelte
Normal 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>
|
||||
|
||||
54
src/routes/networking/+page.svelte
Normal file
54
src/routes/networking/+page.svelte
Normal 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>
|
||||
|
||||
55
src/routes/networking/cdn/+page.svelte
Normal file
55
src/routes/networking/cdn/+page.svelte
Normal 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>
|
||||
|
||||
77
src/routes/networking/vpc/+page.svelte
Normal file
77
src/routes/networking/vpc/+page.svelte
Normal 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 what’s 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>
|
||||
54
src/routes/security/+page.svelte
Normal file
54
src/routes/security/+page.svelte
Normal 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>
|
||||
|
||||
54
src/routes/security/encryption/+page.svelte
Normal file
54
src/routes/security/encryption/+page.svelte
Normal 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>
|
||||
|
||||
59
src/routes/security/iam/+page.svelte
Normal file
59
src/routes/security/iam/+page.svelte
Normal 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>
|
||||
|
||||
58
src/routes/security/secrets/+page.svelte
Normal file
58
src/routes/security/secrets/+page.svelte
Normal 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>
|
||||
|
||||
54
src/routes/storage/+page.svelte
Normal file
54
src/routes/storage/+page.svelte
Normal 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>
|
||||
|
||||
56
src/routes/storage/block/+page.svelte
Normal file
56
src/routes/storage/block/+page.svelte
Normal 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>
|
||||
|
||||
57
src/routes/storage/file/+page.svelte
Normal file
57
src/routes/storage/file/+page.svelte
Normal 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>
|
||||
|
||||
58
src/routes/storage/object/+page.svelte
Normal file
58
src/routes/storage/object/+page.svelte
Normal 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>
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue