diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9289a50 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +node_modules +.svelte-kit +build +package-lock.json +yarn.lock +.env +.env.* +!.env.example +vite.config.js.timestamp-* +vite.config.ts.timestamp-* diff --git a/package.json b/package.json new file mode 100644 index 0000000..3226c8a --- /dev/null +++ b/package.json @@ -0,0 +1,32 @@ +{ + "name": "system-design-explorer", + "version": "0.0.1", + "private": true, + "scripts": { + "dev": "vite dev", + "build": "vite build", + "preview": "vite preview", + "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", + "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch" + }, + "devDependencies": { + "@sveltejs/adapter-auto": "^6.0.0", + "@sveltejs/kit": "^2.21.0", + "@sveltejs/vite-plugin-svelte": "^5.0.0", + "@types/d3": "^7.4.3", + "autoprefixer": "^10.4.20", + "postcss": "^8.5.1", + "svelte": "^5.17.4", + "svelte-check": "^4.0.0", + "tailwindcss": "^3.4.17", + "typescript": "^5.0.0", + "vite": "^6.0.0" + }, + "dependencies": { + "@xyflow/svelte": "^0.1.26", + "d3": "^7.9.0", + "gsap": "^3.12.7", + "lucide-svelte": "^0.469.0" + }, + "type": "module" +} diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000..ba80730 --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,6 @@ +export default { + plugins: { + tailwindcss: {}, + autoprefixer: {} + } +}; diff --git a/src/app.css b/src/app.css new file mode 100644 index 0000000..24ccbf3 --- /dev/null +++ b/src/app.css @@ -0,0 +1,111 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +@layer base { + * { + @apply border-surface-700; + } + + body { + @apply antialiased; + } + + ::-webkit-scrollbar { + @apply w-2 h-2; + } + + ::-webkit-scrollbar-track { + @apply bg-surface-900; + } + + ::-webkit-scrollbar-thumb { + @apply bg-surface-700 rounded-full; + } + + ::-webkit-scrollbar-thumb:hover { + @apply bg-surface-600; + } +} + +@layer components { + .card { + @apply bg-surface-900 border border-surface-800 rounded-xl p-6; + } + + .card-hover { + @apply card hover:border-surface-600 hover:bg-surface-800/50 transition-all duration-200 cursor-pointer; + } + + .btn { + @apply px-4 py-2 rounded-lg font-medium transition-all duration-200; + } + + .btn-primary { + @apply btn bg-blue-600 hover:bg-blue-500 text-white; + } + + .btn-secondary { + @apply btn bg-surface-800 hover:bg-surface-700 text-surface-200; + } + + .section-title { + @apply text-2xl font-bold text-surface-100 mb-4; + } + + .section-subtitle { + @apply text-surface-400 mb-6; + } + + .tag { + @apply inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium; + } + + .tag-aws { + @apply tag bg-aws-orange/20 text-aws-orange; + } + + .tag-gcp { + @apply tag bg-gcp-blue/20 text-gcp-blue; + } + + .tag-concept { + @apply tag bg-purple-500/20 text-purple-400; + } + + /* Animated flow lines for diagrams */ + .flow-line { + stroke-dasharray: 5 5; + animation: flowAnimation 1s linear infinite; + } + + @keyframes flowAnimation { + to { + stroke-dashoffset: -10; + } + } + + /* Node styles for diagrams */ + .diagram-node { + @apply bg-surface-800 border-2 border-surface-600 rounded-xl p-4 shadow-lg; + @apply hover:border-blue-500 hover:shadow-blue-500/20 transition-all duration-200; + } + + .diagram-node-aws { + @apply diagram-node border-aws-orange/50 hover:border-aws-orange; + } + + .diagram-node-gcp { + @apply diagram-node border-gcp-blue/50 hover:border-gcp-blue; + } +} + +@layer utilities { + .text-gradient { + @apply bg-clip-text text-transparent bg-gradient-to-r from-blue-400 to-purple-400; + } + + .glass { + @apply bg-surface-900/80 backdrop-blur-lg; + } +} diff --git a/src/app.html b/src/app.html new file mode 100644 index 0000000..760c18e --- /dev/null +++ b/src/app.html @@ -0,0 +1,15 @@ + + + + + + + + + + %sveltekit.head% + + +
%sveltekit.body%
+ + diff --git a/src/lib/components/diagrams/ComparisonTable.svelte b/src/lib/components/diagrams/ComparisonTable.svelte new file mode 100644 index 0000000..dd89f13 --- /dev/null +++ b/src/lib/components/diagrams/ComparisonTable.svelte @@ -0,0 +1,163 @@ + + +
+ +
+

{title}

+ {#if subtitle} +

{subtitle}

+ {/if} +
+ + +
+ + + + + {#each options as option} + {@const Icon = getIcon(option.icon)} + + {/each} + + + + {#each features as feature, i} + + + {#each options as option} + {@const cell = getCellContent(feature.values[option.id])} + + {/each} + + {/each} + +
+ Feature + selectedOption = selectedOption === option.id ? null : option.id} + > +
+
+ +
+ {option.name} +
+
+
{feature.feature}
+ {#if feature.description} +
{feature.description}
+ {/if} +
+ {#if cell.type === 'check'} + + {:else if cell.type === 'x'} + + {:else} + {cell.value} + {/if} +
+
+ + + {#if selectedOption} + {@const selected = options.find(o => o.id === selectedOption)} + {#if selected} +
+ +
+
+ +

When to Use {selected.name}

+
+
    + {#each selected.whenToUse as reason} +
  • + + {reason} +
  • + {/each} +
+
+ + +
+
+ +

When NOT to Use {selected.name}

+
+
    + {#each selected.whenNotToUse as reason} +
  • + + {reason} +
  • + {/each} +
+
+ + + {#if selected.realWorldExample} +
+
+ +

Real World Example

+
+

{selected.realWorldExample}

+
+ {/if} +
+ {/if} + {:else} +
+ +

Click on a column header to see when to use each option

+
+ {/if} +
diff --git a/src/lib/components/diagrams/DecisionTree.svelte b/src/lib/components/diagrams/DecisionTree.svelte new file mode 100644 index 0000000..c20ff4c --- /dev/null +++ b/src/lib/components/diagrams/DecisionTree.svelte @@ -0,0 +1,207 @@ + + +
+ +
+

{title}

+ {#if subtitle} +

{subtitle}

+ {/if} +
+ + +
+ {#each path as nodeId, i} + {@const node = getNode(nodeId)} + {@const isLast = i === path.length - 1} + {#if node} +
+ {#if i > 0} + + {/if} + + {#if node.type === 'question'} + {answers[nodeId] !== undefined ? (answers[nodeId] ? 'Yes' : 'No') : '?'} + {:else} + {node.text.substring(0, 20)}... + {/if} + +
+ {/if} + {/each} +
+ + + {#if currentNode} +
+ {#if currentNode.type === 'question'} + +
+
+ +
+ +
+

{currentNode.text}

+ {#if currentNode.description} +

{currentNode.description}

+ {/if} +
+ +
+ + +
+
+ + {:else} + + {@const Icon = getIcon(currentNode.icon)} +
+
+ +
+ +
+ Recommendation +

{currentNode.text}

+
+ + {#if currentNode.reasoning} +
+
+ + Why this choice? +
+

{currentNode.reasoning}

+
+ {/if} + + {#if currentNode.alternatives && currentNode.alternatives.length > 0} +
+
+ + Alternatives to consider +
+
    + {#each currentNode.alternatives as alt} +
  • + + {alt} +
  • + {/each} +
+
+ {/if} +
+ {/if} +
+ {/if} + + +
+ {#if path.length > 1} + + {/if} + {#if isAtEnd} + + {/if} +
+
diff --git a/src/lib/components/diagrams/GuidedWalkthrough.svelte b/src/lib/components/diagrams/GuidedWalkthrough.svelte new file mode 100644 index 0000000..4b55998 --- /dev/null +++ b/src/lib/components/diagrams/GuidedWalkthrough.svelte @@ -0,0 +1,223 @@ + + +
+ +
+
+

{title}

+ {#if subtitle} +

{subtitle}

+ {/if} +
+
+ +
+
+ + +
+
+
+
+
+ Step {currentStep + 1} of {steps.length} + {Math.round(progress)}% complete +
+
+ + +
+ {#each steps as s, i} + {@const Icon = getIcon(s.icon)} + + {/each} +
+ + + {#key currentStep} +
+
+ +
+
+ +
+
+ + +
+
+ Step {currentStep + 1} +

{step.title}

+
+ +

{step.description}

+ + {#if step.details} +
+
+ + Technical Details +
+

{step.details}

+
+ {/if} + + {#if step.tip} +
+
+ + Pro Tip +
+

{step.tip}

+
+ {/if} +
+
+
+ {/key} + + +
+ + +
+ {#each steps as _, i} + + {/each} +
+ + +
+
diff --git a/src/lib/components/diagrams/ServiceNode.svelte b/src/lib/components/diagrams/ServiceNode.svelte new file mode 100644 index 0000000..b62046c --- /dev/null +++ b/src/lib/components/diagrams/ServiceNode.svelte @@ -0,0 +1,90 @@ + + + diff --git a/src/lib/components/ui/Sidebar.svelte b/src/lib/components/ui/Sidebar.svelte new file mode 100644 index 0000000..06cf856 --- /dev/null +++ b/src/lib/components/ui/Sidebar.svelte @@ -0,0 +1,126 @@ + + + diff --git a/src/lib/stores/navigation.ts b/src/lib/stores/navigation.ts new file mode 100644 index 0000000..b380b50 --- /dev/null +++ b/src/lib/stores/navigation.ts @@ -0,0 +1,125 @@ +import { writable } from 'svelte/store'; + +export interface NavItem { + id: string; + label: string; + icon: string; + href: string; + children?: NavItem[]; +} + +export const navigationItems: NavItem[] = [ + { + id: 'home', + label: 'Overview', + icon: 'Home', + href: '/' + }, + { + id: 'fundamentals', + label: 'Fundamentals', + icon: 'BookOpen', + href: '/fundamentals', + children: [ + { id: 'cap-theorem', label: 'CAP Theorem', icon: 'Triangle', href: '/fundamentals/cap-theorem' }, + { id: 'consistency', label: 'Consistency Models', icon: 'RefreshCw', href: '/fundamentals/consistency' }, + { id: 'scaling', label: 'Scaling', icon: 'TrendingUp', href: '/fundamentals/scaling' }, + { id: 'latency', label: 'Latency vs Throughput', icon: 'Gauge', href: '/fundamentals/latency' } + ] + }, + { + id: 'compute', + label: 'Compute', + icon: 'Cpu', + href: '/compute', + children: [ + { id: 'vms', label: 'Virtual Machines', icon: 'Server', href: '/compute/virtual-machines' }, + { id: 'serverless', label: 'Serverless', icon: 'Zap', href: '/compute/serverless' }, + { id: 'containers', label: 'Containers', icon: 'Box', href: '/compute/containers' }, + { id: 'kubernetes', label: 'Kubernetes', icon: 'Boxes', href: '/compute/kubernetes' } + ] + }, + { + id: 'storage', + label: 'Storage', + icon: 'HardDrive', + href: '/storage', + children: [ + { id: 'object', label: 'Object Storage', icon: 'File', href: '/storage/object' }, + { id: 'block', label: 'Block Storage', icon: 'Database', href: '/storage/block' }, + { id: 'file', label: 'File Storage', icon: 'Folder', href: '/storage/file' } + ] + }, + { + id: 'databases', + label: 'Databases', + icon: 'Database', + href: '/databases', + children: [ + { id: 'sql', label: 'SQL Databases', icon: 'Table', href: '/databases/sql' }, + { id: 'nosql', label: 'NoSQL Databases', icon: 'FileJson', href: '/databases/nosql' }, + { id: 'cache', label: 'Caching', icon: 'Layers', href: '/databases/caching' }, + { id: 'replication', label: 'Replication', icon: 'Copy', href: '/databases/replication' } + ] + }, + { + id: 'networking', + label: 'Networking', + icon: 'Network', + href: '/networking', + children: [ + { id: 'vpc', label: 'VPC & Subnets', icon: 'Globe', href: '/networking/vpc' }, + { id: 'dns', label: 'DNS', icon: 'Link', href: '/networking/dns' }, + { id: 'load-balancing', label: 'Load Balancing', icon: 'Scale', href: '/networking/load-balancing' }, + { id: 'cdn', label: 'CDN', icon: 'Radio', href: '/networking/cdn' } + ] + }, + { + id: 'messaging', + label: 'Messaging', + icon: 'MessageSquare', + href: '/messaging', + children: [ + { id: 'queues', label: 'Message Queues', icon: 'ListOrdered', href: '/messaging/queues' }, + { id: 'pubsub', label: 'Pub/Sub', icon: 'Bell', href: '/messaging/pubsub' }, + { id: 'event-driven', label: 'Event-Driven', icon: 'Activity', href: '/messaging/event-driven' } + ] + }, + { + id: 'security', + label: 'Security', + icon: 'Shield', + href: '/security', + children: [ + { id: 'iam', label: 'IAM', icon: 'Key', href: '/security/iam' }, + { id: 'encryption', label: 'Encryption', icon: 'Lock', href: '/security/encryption' }, + { id: 'secrets', label: 'Secrets Management', icon: 'KeyRound', href: '/security/secrets' } + ] + }, + { + id: 'compare', + label: 'Compare', + icon: 'GitCompare', + href: '/compare', + children: [ + { id: 'sql-vs-nosql', label: 'SQL vs NoSQL', icon: 'GitCompare', href: '/compare/sql-vs-nosql' }, + { id: 'kafka-vs-rabbitmq', label: 'Kafka vs RabbitMQ', icon: 'GitCompare', href: '/compare/kafka-vs-rabbitmq' }, + { id: 'rest-vs-graphql', label: 'REST vs GraphQL vs gRPC', icon: 'GitCompare', href: '/compare/api-design' } + ] + }, + { + id: 'decisions', + label: 'Decision Trees', + icon: 'GitBranch', + href: '/decisions', + children: [ + { id: 'which-database', label: 'Which Database?', icon: 'HelpCircle', href: '/decisions/which-database' }, + { id: 'serverless-or-not', label: 'Serverless or Not?', icon: 'HelpCircle', href: '/decisions/serverless' }, + { id: 'which-queue', label: 'Which Message Queue?', icon: 'HelpCircle', href: '/decisions/which-queue' } + ] + } +]; + +export const sidebarOpen = writable(true); +export const activeSection = writable('home'); +export const expandedSections = writable>(new Set(['fundamentals'])); diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte new file mode 100644 index 0000000..dabae10 --- /dev/null +++ b/src/routes/+layout.svelte @@ -0,0 +1,21 @@ + + +
+ + +
+
+ {@render children()} +
+
+
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte new file mode 100644 index 0000000..b070a0e --- /dev/null +++ b/src/routes/+page.svelte @@ -0,0 +1,225 @@ + + + + System Design Explorer + + +
+ +
+
+ + Interactive Visual Learning +
+ +

+ Master System Design +

+ +

+ Learn cloud infrastructure, distributed systems, and architecture patterns through + interactive diagrams, visual comparisons, and decision-guided walkthroughs. +

+ + +
+ + +
+ {#each categories as category} + {@const Icon = getIcon(category.icon)} + +
+
+ +
+
+

+ {category.title} +

+

{category.description}

+
+
+
+ Explore + +
+
+ {/each} +
+ + +
+
+
+ +
+
+

Quick Comparisons

+

Side-by-side analysis with "when to use" guidance

+
+
+ +
+ {#each quickLinks as link} + {@const Icon = getIcon(link.icon)} + + + {link.label} + + {/each} +
+
+ + +
+ +
+
+
+ +
+
+

Amazon Web Services

+

EC2, S3, Lambda, RDS, EKS, and more

+
+
+
+ {#each ['EC2', 'S3', 'Lambda', 'RDS', 'EKS', 'SQS'] as service} +
+ {service} +
+ {/each} +
+
+ + +
+
+
+ +
+
+

Google Cloud Platform

+

Compute Engine, Cloud Storage, GKE, and more

+
+
+
+ {#each ['Compute', 'Storage', 'GKE', 'Cloud SQL', 'Pub/Sub', 'BigQuery'] as service} +
+ {service} +
+ {/each} +
+
+
+ + +
+
+
+ +
+
+

Key Concepts You'll Learn

+

Each with interactive diagrams and real-world examples

+
+
+ +
+ {#each [ + { name: 'CAP Theorem', desc: 'Consistency, Availability, Partition Tolerance trade-offs' }, + { name: 'Load Balancing', desc: 'L4 vs L7, algorithms, health checks' }, + { name: 'Database Sharding', desc: 'Horizontal scaling, partition strategies' }, + { name: 'Caching Patterns', desc: 'Cache-aside, write-through, invalidation' }, + { name: 'Message Queues', desc: 'When to use Kafka vs RabbitMQ vs SQS' }, + { name: 'Kubernetes', desc: 'Pods, services, deployments, scaling' } + ] as concept} +
+

{concept.name}

+

{concept.desc}

+
+ {/each} +
+
+
diff --git a/src/routes/compare/kafka-vs-rabbitmq/+page.svelte b/src/routes/compare/kafka-vs-rabbitmq/+page.svelte new file mode 100644 index 0000000..75dfde5 --- /dev/null +++ b/src/routes/compare/kafka-vs-rabbitmq/+page.svelte @@ -0,0 +1,406 @@ + + + + Kafka vs RabbitMQ + + +
+

Kafka vs RabbitMQ

+

Event streaming platform vs traditional message broker - understanding the fundamental differences

+ + +
+
+

TL;DR

+
+
+
+
+ Kafka + = Event streaming. High throughput, message replay, data pipelines. +
+
+
+
+
+ RabbitMQ + = Message broker. Complex routing, guaranteed delivery, task queues. +
+
+
+
+
+ + +
+

Architecture Difference

+

The fundamental architectural difference explains most of their behavior differences.

+ +
+ +
+

{architectureDiff.kafka.title}

+

{architectureDiff.kafka.description}

+ +
+ {#each architectureDiff.kafka.flow as step, i} +
+
+ {i + 1} +
+
+
{step.label}
+
{step.desc}
+
+ {#if i < architectureDiff.kafka.flow.length - 1} +
+ {/if} +
+ {/each} +
+ +
+
{architectureDiff.kafka.keyPoint}
+
+
+ + +
+

{architectureDiff.rabbitmq.title}

+

{architectureDiff.rabbitmq.description}

+ +
+ {#each architectureDiff.rabbitmq.flow as step, i} +
+
+ {i + 1} +
+
+
{step.label}
+
{step.desc}
+
+ {#if i < architectureDiff.rabbitmq.flow.length - 1} +
+ {/if} +
+ {/each} +
+ +
+
{architectureDiff.rabbitmq.keyPoint}
+
+
+
+
+ + +
+

Message Lifecycle

+ +
+
+

Kafka: Log-Based

+
+
+ 1. +
+
Message written to partition
+
Appended to end of log with offset
+
+
+
+ 2. +
+
Consumers read at their offset
+
Multiple consumers can read same message
+
+
+
+ 3. +
+
Retention policy deletes old messages
+
After 7 days or 1GB (configurable)
+
+
+
+
+ +
+

RabbitMQ: Queue-Based

+
+
+ 1. +
+
Message routed to queue(s)
+
Exchange determines destination
+
+
+
+ 2. +
+
Broker pushes to consumer
+
One consumer receives each message
+
+
+
+ 3. +
+
Consumer acknowledges
+
Message deleted from queue
+
+
+
+
+
+
+ + +
+

Feature Comparison

+ +
+ + + + + + + + + + {#each features as feature, i} + + + + + + {/each} + +
FeatureKafkaRabbitMQ
{feature.name}{feature.kafka}{feature.rabbitmq}
+
+
+ + +
+

When to Use Each

+ +
+ + +
+

RabbitMQ Routing Patterns

+

RabbitMQ's flexible exchange types enable complex routing scenarios that Kafka cannot do natively.

+ +
+
+
Direct
+
Route by exact routing key match
+
order.created to orders queue
+
+
+
Topic
+
Route by pattern matching (*.error)
+
app.*.error to error-handler
+
+
+
Fanout
+
Broadcast to all bound queues
+
notification to all subscribers
+
+
+
Headers
+
Route by message headers
+
x-priority: high to fast queue
+
+
+
+ + +
+

Kafka Partitioning

+

Kafka achieves scalability through partitions - each partition is an ordered, immutable log.

+ +
+
+
+
Partition 0
+
+ {#each [0, 1, 2, 3, 4] as offset} +
{offset}
+ {/each} +
+
+
+
Partition 1
+
+ {#each [0, 1, 2, 3] as offset} +
{offset}
+ {/each} +
+
+
+
Partition 2
+
+ {#each [0, 1, 2, 3, 4, 5] as offset} +
{offset}
+ {/each} +
+
+
+ +
+
+
Ordering
+
Guaranteed within partition only
+
+
+
Parallelism
+
Max consumers = number of partitions
+
+
+
Key-based routing
+
Same key always goes to same partition
+
+
+
+
+ + +
+

Real World Examples

+ +
+
+

Kafka Use Cases

+
+
+
Real-time Analytics
+
Stream clickstream data to analytics pipeline
+
+
+
Event Sourcing
+
Store all state changes as immutable events
+
+
+
Log Aggregation
+
Centralize logs from thousands of services
+
+
+
CDC Pipelines
+
Stream database changes to data warehouse
+
+
+
+ +
+

RabbitMQ Use Cases

+
+
+
Task Queues
+
Background job processing with retries
+
+
+
Microservices
+
Async communication between services
+
+
+
IoT Messaging
+
MQTT protocol for device communication
+
+
+
Request/Reply
+
RPC-style communication patterns
+
+
+
+
+
+
diff --git a/src/routes/compare/sql-vs-nosql/+page.svelte b/src/routes/compare/sql-vs-nosql/+page.svelte new file mode 100644 index 0000000..f49cc17 --- /dev/null +++ b/src/routes/compare/sql-vs-nosql/+page.svelte @@ -0,0 +1,343 @@ + + + + SQL vs NoSQL - System Design Explorer + + +
+ +
+
+ Compare + + SQL vs NoSQL +
+

SQL vs NoSQL Databases

+

+ Understanding when to use relational vs non-relational databases for your use case. +

+
+ + +
+
+
+
+ +
+ SQL in a Nutshell +
+

+ Structured data in tables with relationships. Strong consistency, ACID transactions, + complex queries with JOINs. Scale vertically. Best when data structure is known and + relationships matter. +

+
+ +
+
+
+ +
+ NoSQL in a Nutshell +
+

+ Flexible schemas, horizontal scaling, eventual consistency. Different types for + different needs: documents, key-value, wide-column, graph. Best for scale, + flexibility, and specific access patterns. +

+
+
+ + + + + +
+
+
+ +
+
+

The Real Question to Ask

+

+ Instead of "SQL or NoSQL?", ask yourself these questions: +

+
+
+
+ + What are my query patterns? (JOINs? Key lookups?) +
+
+ + How important is consistency vs availability? +
+
+
+
+ + Will my schema evolve frequently? +
+
+ + What scale do I need to handle? +
+
+
+
+
+
+ + +
+

Common Patterns in Production

+
+
+
+ 1 +
+
+

Polyglot Persistence

+

+ Use multiple databases for different needs. PostgreSQL for transactions, Redis for caching, + Elasticsearch for search, MongoDB for flexible data. Match the database to the use case. +

+
+
+ +
+
+ 2 +
+
+

Start with SQL, Add NoSQL Later

+

+ Begin with PostgreSQL - it's versatile, well-understood, and handles most use cases. + Add specialized databases when you hit specific scaling or performance needs. +

+
+
+ +
+
+ 3 +
+
+

Cache Hot Data

+

+ Use Redis in front of your primary database. Most apps have hot data (frequently accessed) + and cold data. Cache the hot data for massive performance gains without changing your primary DB. +

+
+
+
+
+ + + +
diff --git a/src/routes/compute/kubernetes/+page.svelte b/src/routes/compute/kubernetes/+page.svelte new file mode 100644 index 0000000..6b9c72e --- /dev/null +++ b/src/routes/compute/kubernetes/+page.svelte @@ -0,0 +1,397 @@ + + + + Kubernetes Architecture + + +
+

Kubernetes Architecture

+

Understanding the control plane, worker nodes, and how they work together

+ + +
+
+
+ +
+

Control Plane

+

The brain - makes decisions about the cluster

+ +
+ {#each controlPlaneComponents.slice(0, 4) as component} + + {/each} +
+
+ + +
+

Worker Nodes

+

The muscle - runs your actual workloads

+ +
+ {#each nodeComponents as component} + + {/each} +
+
+
+ + + {#if selectedComponent} + {@const allComponents = [...controlPlaneComponents, ...nodeComponents]} + {@const component = allComponents.find(c => c.id === selectedComponent)} + {#if component} +
+

{component.name}

+
    + {#each component.details as detail} +
  • + - + {detail} +
  • + {/each} +
+
+ {/if} + {/if} +
+
+ + +
+

Control Plane Components

+ +
+ {#each controlPlaneComponents as component} +
+
+
+

{component.name}

+

{component.description}

+
+ + Control Plane + +
+
+ {#each component.details as detail} +
+ + {detail} +
+ {/each} +
+
+ {/each} +
+
+ + +
+

How a Pod Gets Scheduled

+

Follow the journey from kubectl apply to running pod

+ +
+
+
+
+ {#each requestFlow as step} +
+
+ {step.step} +
+
+
{step.title}
+
{step.desc}
+
+
+ {/each} +
+
+
+
+ + +
+

Pod Lifecycle

+ +
+
+ {#each podLifecycle as phase, i} +
+
+
{phase.phase}
+
{phase.desc}
+
+ {#if i < podLifecycle.length - 1} +
->
+ {/if} +
+ {/each} +
+
+
+ + +
+

Key Kubernetes Objects

+ +
+
+
Pod
+

Smallest deployable unit. One or more containers that share network/storage.

+
+
+
Deployment
+

Manages ReplicaSets. Handles rolling updates and rollbacks.

+
+
+
Service
+

Stable network endpoint for pods. ClusterIP, NodePort, LoadBalancer.

+
+
+
ConfigMap
+

Non-sensitive configuration data. Injected as env vars or files.

+
+
+
Secret
+

Sensitive data like passwords, tokens. Base64 encoded (not encrypted!).

+
+
+
Ingress
+

HTTP routing rules. Path-based routing to Services.

+
+
+
StatefulSet
+

For stateful apps. Stable network identity and persistent storage.

+
+
+
DaemonSet
+

Run pod on every node. Used for logging, monitoring agents.

+
+
+
HPA
+

Horizontal Pod Autoscaler. Scale pods based on CPU/memory/custom metrics.

+
+
+
+ + +
+

Kubernetes Networking Model

+ +
+
+
+

Pod-to-Pod

+

Every pod gets a unique IP. Pods can communicate directly without NAT.

+
Implemented by CNI plugin (Calico, Cilium, etc.)
+
+
+

Pod-to-Service

+

Services provide stable virtual IPs (ClusterIP). kube-proxy routes to pods.

+
Uses iptables or IPVS rules
+
+
+

External-to-Service

+

NodePort, LoadBalancer, or Ingress expose services externally.

+
Ingress for HTTP, LoadBalancer for TCP/UDP
+
+
+
+
+ + +
+

Production Best Practices

+ +
+
+

DO

+
    +
  • + + + Set resource requests and limits on all pods +
  • +
  • + + + Use liveness and readiness probes +
  • +
  • + + + Run multiple replicas with anti-affinity +
  • +
  • + + + Use namespaces for isolation +
  • +
  • + + + Backup etcd regularly +
  • +
+
+
+

DON'T

+
    +
  • + - + Run workloads on control plane nodes +
  • +
  • + - + Use :latest image tags in production +
  • +
  • + - + Store secrets in ConfigMaps +
  • +
  • + - + Skip pod disruption budgets +
  • +
  • + - + Ignore resource quotas in multi-tenant clusters +
  • +
+
+
+
+
diff --git a/src/routes/compute/serverless/+page.svelte b/src/routes/compute/serverless/+page.svelte new file mode 100644 index 0000000..f335c83 --- /dev/null +++ b/src/routes/compute/serverless/+page.svelte @@ -0,0 +1,390 @@ + + + + Serverless - Cold & Warm Starts + + +
+

Serverless Computing

+

Understanding cold starts, warm starts, and optimization strategies

+ + +
+
+ + +
+ +
+ {#if showColdStart} +
+

Cold Start

+

No existing execution environment - must provision new container

+
+ + +
+
+
+ {#each coldStartPhases as phase, i} +
+
+
+
+ {phase.name} + {phase.duration} +
+

{phase.desc}

+
+
+ {/each} +
+
+
+
+ Handler Execution + Your code +
+

Finally, your function handler runs

+
+
+
+
+ +
+
Total Cold Start: 200ms - 3s+
+
Depends on runtime, package size, and dependencies
+
+ {:else} +
+

Warm Start

+

Reuses existing execution environment - skips initialization

+
+ +
+
+
+ {#each coldStartPhases as phase} +
+
+
+
+ {phase.name} + SKIPPED +
+
+
+ {/each} +
+
+
+
+ Handler Execution + ~1-5ms +
+

Jump straight to your code!

+
+
+
+
+ +
+
Total Warm Start: 1-5ms
+
Container reused for ~5-15 minutes of inactivity
+
+ {/if} +
+
+ + +
+

Cold Start Deep Dive

+ +
+ + +
+

Runtime Comparison

+

Cold start times vary significantly by language runtime

+ +
+ + + + + + + + + + + {#each runtimeComparison as rt, i} + + + + + + + {/each} + +
RuntimeCold StartWarm StartNotes
{rt.runtime}{rt.coldStart}{rt.warmStart}{rt.notes}
+
+
+ + +
+

Optimization Strategies

+ +
+ {#each optimizations as category} +
+

{category.category}

+
+ {#each category.items as item} +
+
+ {item.name} + + {item.impact} impact + +
+

{item.desc}

+
+ {/each} +
+
+ {/each} +
+
+ + +
+

Provisioned Concurrency vs SnapStart

+ +
+
+

Provisioned Concurrency

+

+ Pre-initialize a specified number of execution environments that are always ready. +

+
+
+ + + Eliminates cold starts completely +
+
+ + + Works with any runtime +
+
+ - + Costs money even when idle +
+
+ - + Must estimate concurrency needs +
+
+
+
Best for: Consistent, predictable traffic patterns
+
+
+ +
+

SnapStart

+

+ Snapshot initialized state and restore from cache instead of re-initializing. +

+
+
+ + + Up to 10x faster cold starts +
+
+ + + No additional cost +
+
+ - + Only Java, Python, .NET +
+
+ - + May need code changes for uniqueness +
+
+
+
Best for: Java/.NET with variable traffic
+
+
+
+
+ + +
+

Best Practices

+ +
+
+
+

DO

+
    +
  • + + + Initialize SDK clients outside the handler (global scope) +
  • +
  • + + + Reuse database connections across invocations +
  • +
  • + + + Use Lambda Layers for shared dependencies +
  • +
  • + + + Monitor INIT duration in CloudWatch +
  • +
  • + + + Use ARM architecture for cost savings +
  • +
+
+
+

DON'T

+
    +
  • + - + Create new connections on every invocation +
  • +
  • + - + Bundle unnecessary dependencies +
  • +
  • + - + Use VPC unless you need private resources +
  • +
  • + - + Ignore cold start metrics in production +
  • +
  • + - + Use Java without SnapStart for user-facing APIs +
  • +
+
+
+
+
+
diff --git a/src/routes/databases/caching/+page.svelte b/src/routes/databases/caching/+page.svelte new file mode 100644 index 0000000..7fc7d19 --- /dev/null +++ b/src/routes/databases/caching/+page.svelte @@ -0,0 +1,442 @@ + + + + Caching Patterns + + +
+

Caching Patterns

+

Understanding different caching strategies and when to use each

+ + +
+
+

Why Caching Matters

+
+
+
10-100x
+
Faster than database
+
+
+
<1ms
+
Cache read latency
+
+
+
90%+
+
Target hit rate
+
+
+
$$$
+
Reduced DB costs
+
+
+
+
+ + +
+

Caching Patterns

+ +
+ {#each patterns as pattern} +
selectedPattern = selectedPattern === pattern.id ? null : pattern.id} + on:keydown={(e) => e.key === 'Enter' && (selectedPattern = selectedPattern === pattern.id ? null : pattern.id)} + role="button" + tabindex="0" + > +
+
+
+

{pattern.name}

+

{pattern.description}

+
+ + {pattern.useCase} + +
+ + +
+ {#each pattern.steps as step, i} +
+
+ {step} +
+ {#if i < pattern.steps.length - 1} + -> + {/if} +
+ {/each} +
+ + {#if selectedPattern === pattern.id} +
+
+

Pros

+
    + {#each pattern.pros as pro} +
  • + + + {pro} +
  • + {/each} +
+
+
+

Cons

+
    + {#each pattern.cons as con} +
  • + - + {con} +
  • + {/each} +
+
+
+ {/if} +
+
+ {/each} +
+
+ + +
+

Cache-Aside in Detail

+

The most common caching pattern - walk through each step.

+ +
+ + +
+

Eviction Strategies

+

When cache is full, which items should be removed?

+ +
+ {#each evictionStrategies as strategy} +
+

{strategy.name}

+

{strategy.description}

+
Best for: {strategy.best}
+
+ {/each} +
+
+ + +
+

Common Caching Problems

+ +
+
+

Cache Stampede

+

+ Many requests hit an expired cache key simultaneously, all querying the database at once. +

+
+
Solutions:
+
    +
  • - Lock/mutex on cache refresh
  • +
  • - Staggered TTLs
  • +
  • - Background refresh
  • +
+
+
+ +
+

Stale Data

+

+ Cache contains outdated data that does not reflect current database state. +

+
+
Solutions:
+
    +
  • - Appropriate TTL values
  • +
  • - Cache invalidation on writes
  • +
  • - Write-through pattern
  • +
+
+
+ +
+

Cache Penetration

+

+ Requests for non-existent data bypass cache and always hit the database. +

+
+
Solutions:
+
    +
  • - Cache negative results
  • +
  • - Bloom filter for existence check
  • +
  • - Input validation
  • +
+
+
+
+
+ + +
+

Redis vs Memcached

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureRedisMemcached
Data StructuresStrings, Lists, Sets, Hashes, Sorted SetsStrings only
PersistenceYes (RDB, AOF)No
ReplicationBuilt-inNo
Pub/SubYesNo
Lua ScriptingYesNo
Memory EfficiencyGoodBetter (simpler)
Best ForFeature-rich caching, sessions, queuesSimple, high-throughput key-value cache
+
+
+
diff --git a/src/routes/databases/replication/+page.svelte b/src/routes/databases/replication/+page.svelte new file mode 100644 index 0000000..2331338 --- /dev/null +++ b/src/routes/databases/replication/+page.svelte @@ -0,0 +1,396 @@ + + + + Database Replication + + +
+

Database Replication

+

Understanding replication topologies, sync vs async, and consistency trade-offs

+ + +
+
+

Why Replicate?

+
+
+
HA
+
High Availability
+
Survive node failures
+
+
+
R
+
Read Scaling
+
Distribute read load
+
+
+
GEO
+
Geographic
+
Data closer to users
+
+
+
DR
+
Disaster Recovery
+
Backup in another region
+
+
+
+
+ + +
+

Synchronous vs Asynchronous

+ +
+ + +
+ +
+ +
+

Synchronous Replication

+ +
+
+
1
+
+
Client writes to leader
+
+
+
+
2
+
+
Leader sends to replica
+
+
+
+
3
+
+
WAIT for replica confirmation
+
+
+
+
4
+
+
Acknowledge to client
+
+
+
+ +
+
Guarantee: Data exists on N nodes before success
+
+
+ + +
+

Asynchronous Replication

+ +
+
+
1
+
+
Client writes to leader
+
+
+
+
2
+
+
Acknowledge immediately
+
+
+
+
3
+
+
Replicate in background
+
May lag behind leader
+
+
+
+ +
+
Trade-off: Faster writes, but possible data loss on failover
+
+
+
+
+ + +
+

When to Use Each

+ +
+ + +
+

Replication Topologies

+ +
+ {#each replicationTypes as type} +
+
+
+

{type.name}

+

{type.description}

+
+ + {type.useCase} + +
+ +
+
+

Pros

+
    + {#each type.pros as pro} +
  • + + + {pro} +
  • + {/each} +
+
+
+

Cons

+
    + {#each type.cons as con} +
  • + - + {con} +
  • + {/each} +
+
+
+
+ {/each} +
+
+ + +
+

Understanding Replication Lag

+ +
+

+ Replication lag is the delay between when data is written to the leader and when it appears on replicas. + Multiple metrics help pinpoint where the lag is occurring. +

+ +
+ {#each lagMetrics as metric, i} +
+
+
{i + 1}
+ {metric.name} +
+

{metric.desc}

+
+ {/each} +
+ +
+

PostgreSQL: Check Replication Lag

+
SELECT client_addr, state,
+  pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) AS lag_bytes,
+  replay_lag
+FROM pg_stat_replication;
+
+
+
+ + +
+

Failover Considerations

+ +
+
+

Automatic Failover

+

+ System automatically promotes replica when leader fails. Fast recovery but risks split-brain. +

+
    +
  • + ! + Requires proper fencing to prevent split-brain +
  • +
  • + ! + May lose uncommitted transactions (async) +
  • +
  • + ! + Applications may need reconnection logic +
  • +
+
+ +
+

Manual Failover

+

+ Operator manually promotes replica after verifying state. Slower but safer. +

+
    +
  • + - + Verify replica is fully caught up +
  • +
  • + - + Stop writes to old leader first +
  • +
  • + - + Update DNS/connection strings +
  • +
+
+
+
+ + +
+

Common Patterns

+ +
+
+
Read Replicas
+

Route reads to replicas, writes to leader. Scale read capacity horizontally.

+
+
+
Hot Standby
+

Sync replica ready for instant failover. Zero data loss guarantee.

+
+
+
Delayed Replica
+

Intentionally lag behind. Protection against accidental deletes.

+
+
+
Cascading Replication
+

Replicas replicate to other replicas. Reduce load on leader.

+
+
+
Cross-Region Replica
+

Async replica in another region. Disaster recovery and local reads.

+
+
+
Logical Replication
+

Replicate specific tables/databases. Schema changes, version upgrades.

+
+
+
+
diff --git a/src/routes/decisions/which-database/+page.svelte b/src/routes/decisions/which-database/+page.svelte new file mode 100644 index 0000000..77cee28 --- /dev/null +++ b/src/routes/decisions/which-database/+page.svelte @@ -0,0 +1,350 @@ + + + + Which Database? - System Design Explorer + + +
+ +
+
+ Decision Trees + + Which Database? +
+

Which Database Should I Use?

+

+ Answer a few questions about your use case, and we'll recommend the best database for your needs. +

+
+ + + + + +
+

Quick Reference

+
+
+

By Use Case

+ {#each [ + { case: 'E-commerce orders', db: 'PostgreSQL', color: 'blue' }, + { case: 'User profiles', db: 'MongoDB', color: 'green' }, + { case: 'Session caching', db: 'Redis', color: 'red' }, + { case: 'IoT sensor data', db: 'TimescaleDB', color: 'purple' }, + { case: 'Social graph', db: 'Neo4j', color: 'pink' } + ] as item} +
+ {item.case} + {item.db} +
+ {/each} +
+
+

By Data Type

+ {#each [ + { type: 'Relational', db: 'PostgreSQL/MySQL', color: 'blue' }, + { type: 'Documents', db: 'MongoDB/Firestore', color: 'green' }, + { type: 'Key-Value', db: 'Redis/DynamoDB', color: 'yellow' }, + { type: 'Time-Series', db: 'TimescaleDB/InfluxDB', color: 'purple' }, + { type: 'Graph', db: 'Neo4j/Neptune', color: 'pink' } + ] as item} +
+ {item.type} + {item.db} +
+ {/each} +
+
+
+ + + +
diff --git a/src/routes/fundamentals/cap-theorem/+page.svelte b/src/routes/fundamentals/cap-theorem/+page.svelte new file mode 100644 index 0000000..7ce7cdd --- /dev/null +++ b/src/routes/fundamentals/cap-theorem/+page.svelte @@ -0,0 +1,376 @@ + + + + CAP Theorem - System Design Explorer + + +
+ +
+
+ Fundamentals + + CAP Theorem +
+

CAP Theorem

+

+ The fundamental trade-off in distributed systems: you can only guarantee two of three properties. +

+
+ + +
+
+ +
+ + + + + + + + + selectCombination('CA')} + onmouseenter={() => {}} + > + + + CA + + + (Not viable) + + + + + selectCombination('CP')} + > + + + CP + + + + + selectCombination('AP')} + > + + + AP + + + + + {#each Object.entries(vertices) as [key, vertex]} + hoveredVertex = key as 'C' | 'A' | 'P'} + onmouseleave={() => hoveredVertex = null} + > + + + {vertex.short} + + + {/each} + + + + Click an edge to learn more + + +
+ + +
+

The Three Properties

+ {#each Object.entries(vertices) as [key, vertex]} +
hoveredVertex = key as 'C' | 'A' | 'P'} + onmouseleave={() => hoveredVertex = null} + > +
+
+ {vertex.short} +
+ {vertex.label} +
+

{vertex.description}

+
+ {/each} +
+
+
+ + + {#if selectedChoice && selectedChoice !== 'C' && selectedChoice !== 'A' && selectedChoice !== 'P'} + {@const combo = combinations[selectedChoice]} +
+
+
+ {selectedChoice} +
+
+
+

{combo.name}

+ {#if !combo.viable} + Not Achievable + {/if} +
+

{combo.explanation}

+ + {#if combo.viable} +
+ +
+
+ + Examples +
+
    + {#each combo.examples as example} +
  • + + {example} +
  • + {/each} +
+
+ + + {#if combo.useCase} +
+
+ + Best For +
+

{combo.useCase}

+
+ {/if} +
+ {:else} +
+
+ + Why Not Achievable? +
+

+ In any distributed system, network partitions can and will occur. When they do, + you MUST choose between consistency and availability - you cannot have both. + CA systems only exist as single-node databases. +

+
+ {/if} +
+
+
+ {/if} + + +
+
+
+ +
+
+

The Key Insight

+

+ In practice, Partition Tolerance (P) is mandatory for any + distributed system - network failures are a reality. This means your real choice is between + CP (consistency over availability) and + AP (availability over consistency). +

+
+
+
+ + +
+

Choosing Between CP and AP

+
+
+
+
+ CP +
+ Choose CP when... +
+
    + {#each [ + 'Wrong data causes real harm (financial transactions)', + 'Users expect immediate consistency (booking systems)', + 'You need strong guarantees (inventory counts)', + 'Data conflicts are hard to resolve' + ] as item} +
  • + + {item} +
  • + {/each} +
+
+ +
+
+
+ AP +
+ Choose AP when... +
+
    + {#each [ + 'Availability is critical (always-on services)', + 'Eventual consistency is acceptable (social feeds)', + 'You can merge conflicts automatically', + 'Stale data is better than no data' + ] as item} +
  • + + {item} +
  • + {/each} +
+
+
+
+ + + +
diff --git a/src/routes/networking/dns/+page.svelte b/src/routes/networking/dns/+page.svelte new file mode 100644 index 0000000..0582216 --- /dev/null +++ b/src/routes/networking/dns/+page.svelte @@ -0,0 +1,306 @@ + + + + DNS - How it Works - System Design Explorer + + +
+ +
+
+ Networking + + DNS +
+

DNS: Domain Name System

+

+ The internet's phonebook - translating human-readable domain names to IP addresses. +

+
+ + +
+
+
+ +
+

What

+

Translates domain names to IP addresses

+
+
+
+ +
+

Speed

+

20-120ms for uncached lookups

+
+
+
+ +
+

Layers

+

Multiple caching layers for efficiency

+
+
+ + + + + +
+

DNS Record Types

+
+ + + + + + + + + + + {#each recordTypes as record} + + + + + + + {/each} + +
TypeDescriptionExampleUse Case
+ + {record.type} + + {record.description}{record.example}{record.useCase}
+
+
+ + +
+

A Record vs CNAME: When to Use Each

+
+
+
+ A + Direct IP Mapping +
+
    +
  • + + Use for root domain (example.com) +
  • +
  • + + Slightly faster (no extra lookup) +
  • +
  • + + Must update if IP changes +
  • +
  • + + Can't point to another domain +
  • +
+
+
+
+ CNAME + Alias to Another Domain +
+
    +
  • + + Use for subdomains (www.example.com) +
  • +
  • + + Great for CDNs and load balancers +
  • +
  • + + Target can change IP without updating +
  • +
  • + + Cannot use at root domain (usually) +
  • +
+
+
+
+ + +
+

DNS Providers Comparison

+
+ {#each [ + { + name: 'Cloudflare', + icon: 'Cloud', + color: 'orange', + pros: ['Free tier', 'Fast propagation', 'DDoS protection'], + bestFor: 'Most websites' + }, + { + name: 'Route 53', + icon: 'Compass', + color: 'yellow', + pros: ['AWS integration', 'Health checks', 'Geo-routing'], + bestFor: 'AWS infrastructure' + }, + { + name: 'Cloud DNS', + icon: 'Cloud', + color: 'blue', + pros: ['GCP integration', '100% SLA', 'Global anycast'], + bestFor: 'GCP infrastructure' + } + ] as provider} +
+
+ + {provider.name} +
+
    + {#each provider.pros as pro} +
  • + + {pro} +
  • + {/each} +
+
Best for: {provider.bestFor}
+
+ {/each} +
+
+ + + +
diff --git a/src/routes/networking/load-balancing/+page.svelte b/src/routes/networking/load-balancing/+page.svelte new file mode 100644 index 0000000..364874f --- /dev/null +++ b/src/routes/networking/load-balancing/+page.svelte @@ -0,0 +1,368 @@ + + + + Load Balancing - L4 vs L7 + + +
+

Load Balancing

+

Understanding Layer 4 vs Layer 7 load balancers and when to use each

+ + +
+

OSI Model & Load Balancer Layers

+

Load balancers operate at different OSI layers, determining what information they can see and use for routing decisions.

+ +
+
+ {#each osiLayers as layer} +
{ + if (layer.num === 7) selectedLayer = 'l7'; + else if (layer.num === 4) selectedLayer = 'l4'; + }} + on:keydown={(e) => e.key === 'Enter' && (layer.num === 7 ? selectedLayer = 'l7' : layer.num === 4 ? selectedLayer = 'l4' : null)} + role="button" + tabindex="0" + > +
+ {layer.num} +
+
+ {layer.name} + - {layer.protocols} +
+ {#if layer.lb !== '-'} + + {layer.lb} + + {/if} +
+ {/each} +
+ +
+
+
Layer 7 (ALB)
+
Sees HTTP content
+
+
+
Layer 4 (NLB)
+
Sees IP + Port
+
+
+
Layer 3 (GLB)
+
Network gateway
+
+
+
+
+ + +
+

How They Work

+ +
+ +
+

Layer 4 Load Balancer

+
+
+
1
+
+
Extract 5-tuple
+
Source IP, Source Port, Dest IP, Dest Port, Protocol
+
+
+
+
2
+
+
Apply hash algorithm
+
Deterministic routing based on connection info
+
+
+
+
3
+
+
Forward entire connection
+
All packets in session go to same backend
+
+
+
+
+
Key insight:
+
Cannot see inside the packet payload - only network headers
+
+
+ + +
+

Layer 7 Load Balancer

+
+
+
1
+
+
Terminate connection
+
Client connects to LB, LB connects to backend
+
+
+
+
2
+
+
Parse HTTP request
+
Read URL path, headers, cookies, body
+
+
+
+
3
+
+
Apply routing rules
+
/api/* to API servers, /static/* to CDN
+
+
+
+
+
Key insight:
+
Full visibility into application data - can route by content
+
+
+
+
+ + +
+

Feature Comparison

+ +
+ + + + + + + + + + {#each features as feature, i} + + + + + + {/each} + +
FeatureLayer 4 (NLB)Layer 7 (ALB)
{feature.name}{feature.l4}{feature.l7}
+
+
+ + +
+

When to Use Each

+ +
+ + +
+

AWS Load Balancer Types

+ +
+ {#each awsServices as service} +
+
+ {service.name} + + {service.layer} + +
+

{service.use}

+
+ {/each} +
+
+ + +
+

Quick Decision Guide

+ +
+
+
+
1M+
+
+
Need millions of requests/second?
+
Use NLB (Layer 4) - designed for extreme performance
+
+
+ +
+
/api
+
+
Need path-based routing?
+
Use ALB (Layer 7) - can route by URL, headers, cookies
+
+
+ +
+
IP
+
+
Need static IP addresses?
+
Use NLB (Layer 4) - provides static IPs per AZ
+
+
+ +
+
WAF
+
+
Need WAF or advanced security?
+
Use ALB (Layer 7) - integrates with AWS WAF
+
+
+ +
+
DB
+
+
Load balancing databases or non-HTTP?
+
Use NLB (Layer 4) - protocol agnostic
+
+
+
+
+
+ + +
+

Real World Examples

+ +
+
+

E-commerce Platform

+
+
+ ALB + /api/* to API servers +
+
+ ALB + /static/* to static content servers +
+
+ ALB + Sticky sessions for shopping cart +
+
+
+ +
+

Gaming Server

+
+
+ NLB + UDP game traffic (low latency) +
+
+ NLB + TCP matchmaking servers +
+
+ NLB + Static IPs for firewall rules +
+
+
+
+
+
diff --git a/svelte.config.js b/svelte.config.js new file mode 100644 index 0000000..e7f0869 --- /dev/null +++ b/svelte.config.js @@ -0,0 +1,12 @@ +import adapter from '@sveltejs/adapter-auto'; +import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; + +/** @type {import('@sveltejs/kit').Config} */ +const config = { + preprocess: vitePreprocess(), + kit: { + adapter: adapter() + } +}; + +export default config; diff --git a/tailwind.config.js b/tailwind.config.js new file mode 100644 index 0000000..ffb12df --- /dev/null +++ b/tailwind.config.js @@ -0,0 +1,58 @@ +/** @type {import('tailwindcss').Config} */ +export default { + content: ['./src/**/*.{html,js,svelte,ts}'], + darkMode: 'class', + theme: { + extend: { + colors: { + // AWS colors + aws: { + orange: '#FF9900', + dark: '#232F3E', + light: '#37475A' + }, + // GCP colors + gcp: { + blue: '#4285F4', + red: '#EA4335', + yellow: '#FBBC04', + green: '#34A853' + }, + // Custom theme colors + surface: { + 50: '#f8fafc', + 100: '#f1f5f9', + 200: '#e2e8f0', + 300: '#cbd5e1', + 400: '#94a3b8', + 500: '#64748b', + 600: '#475569', + 700: '#334155', + 800: '#1e293b', + 900: '#0f172a', + 950: '#020617' + } + }, + fontFamily: { + sans: ['Inter', 'system-ui', 'sans-serif'], + mono: ['JetBrains Mono', 'Fira Code', 'monospace'] + }, + animation: { + 'flow': 'flow 2s ease-in-out infinite', + 'pulse-slow': 'pulse 3s ease-in-out infinite', + 'fade-in': 'fadeIn 0.5s ease-out' + }, + keyframes: { + flow: { + '0%, 100%': { strokeDashoffset: '0' }, + '50%': { strokeDashoffset: '20' } + }, + fadeIn: { + '0%': { opacity: '0', transform: 'translateY(10px)' }, + '100%': { opacity: '1', transform: 'translateY(0)' } + } + } + } + }, + plugins: [] +}; diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..4344710 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "./.svelte-kit/tsconfig.json", + "compilerOptions": { + "allowJs": true, + "checkJs": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "sourceMap": true, + "strict": true, + "moduleResolution": "bundler" + } +} diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..3406f32 --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,6 @@ +import { sveltekit } from '@sveltejs/kit/vite'; +import { defineConfig } from 'vite'; + +export default defineConfig({ + plugins: [sveltekit()] +});