
This module tears apart the assumption that running code is the same as production-ready code. You'll trace a single HTTP request through all twelve systems it touches before a response comes back, name the six dimensions production actually demands (availability, reliability, durability, security, performance, and economy), and see how mature engineering teams spend only 20-40% of their time on new features while the rest goes to operational and reliability work that most developers skip entirely. By the end, you'll be able to read a deployed app and spot the layers of risk hiding beneath the feature surface, explain why your local environment actively lies to you about production behavior, and set up a monthly health-check routine covering backups, dependencies, certificates, costs, and error rates before degradation catches you off guard.
In this module, you'll learn to read systems the way engineers do - not as a collection of features, but as a network of components, boundaries, and contracts where state determines what breaks and when. You'll trace a request from browser to database and back, work through the decision framework for where state belongs (client, server, external store, database), and match rendering models like CSR, SSR, SSG, and ISR to real content freshness needs rather than framework hype. By the end, you'll be able to draw a C4 Level 2 architecture diagram, apply the clone test to decide whether your server is truly stateless, and spot hydration mismatches before they ship - so when someone asks you why the cart empties on refresh or why two servers give users different data, you'll have a concrete answer, not a guess.
In this module, you'll build the decision-making instincts that separate engineers from coders: how to read any technical choice across three axes (constraints, tradeoffs, reversibility), when to satisfice instead of gold-plate, and how to run a 30-minute litmus test that keeps you from wasting days on a call that doesn't matter. You'll learn to diagnose accidental complexity before it kills a codebase, wield abstraction without getting burned by its hidden assumptions, and treat technical debt as a tracked, argued, numbered strategy rather than a confession. You'll also apply the Twelve-Factor App methodology to new projects, practice reading systems and documentation you didn't write, and spot code smells in unfamiliar code - so you can walk into any codebase, any architecture decision, and make a call you can defend.
In this module you'll go well past "git commit, git push" and learn to treat version control as a thinking tool. You'll be able to draw Git's directed acyclic graph from memory, use the three-tree model to stage individual hunks with git add -p, and write atomic commits with imperative subject lines that explain the why - not just the what. You'll pick a branching strategy that fits your team, know exactly when to rebase versus merge, and resolve conflicts without panic. You'll also set up Gitleaks for pre-commit secret scanning - because over 39 million secrets leaked on GitHub in 2024 and automated bots find them within minutes. By the end you'll use revert, bisect, cherry-pick, and the reflog to read history like an investigator, which is the skill that separates someone who uses Git from someone who actually understands it.
In this moduel, you'll build a concrete, repeatable workflow for AI-assisted development - one that actually holds up under pressure. You'll learn to write a specification before you prompt for anything non-trivial, defining inputs, outputs, edge cases, and a clear definition of done. You'll be able to identify exactly where AI breaks down (novel judgment calls, missing security checks, swallowed errors), review generated code for what's absent rather than just what's there, and set up static types plus runtime schema validation as hard guardrails against the most dangerous AI failure modes. You'll also lock in automated quality enforcement - linting on save, pre-commit hooks, CI checks on push - because human discipline fails under deadline pressure and machines don't get tired.
In this module, you'll build a working mental model of what actually happens between your source code and running production software - covering compilation, interpretation, JIT, stack vs. heap memory, garbage collection mechanics, OS threads, event loops, coroutines, blocking vs. non-blocking I/O, and async/await's state machine behavior. After completing this module, you will be able to diagnose memory leaks caused by forgotten event listeners and unbounded caches, choose the right execution model for I/O-bound vs. CPU-bound workloads, correctly use Promise.all for independent async operations, and configure container health checks, connection pools, and file descriptor limits before they silently kill your production containers.
This module replaces the vague question "is this fast?" with a concrete engineering habit: asking what happens as the data grows. You'll learn the five Big-O growth rates (O(1) through O(n²)), recognize the single most common performance mistake in AI-generated code - an O(n) method like Array.includes() or .find() sitting inside a loop - and know how to fix it by reaching for a hash map or Set instead. Beyond arrays and hash maps, you'll get a working mental model of Sets, stacks, queues, trees, and graphs, plus a four-question checklist that routes you to the right structure for any situation. You'll also learn to prompt AI more precisely by naming complexity targets ("rewrite this in O(n) using a hash map"), so instead of accepting whatever code the AI produces, you can direct it to the algorithm you actually need.
This module walks through the frontend decisions AI gets wrong once you look past the screenshot: state scattered across five different places, derived values stored instead of computed, memo slapped on instead of restructuring the component tree, and forms that only handle the happy path. You'll learn where each of the five kinds of state actually belongs, why the URL is a state container you're probably ignoring, why semantic HTML saves you days of reimplementing keyboard and screen reader behavior, and how to treat every byte you ship as a budget decision with CI enforcement. By the end you'll be able to read a component tree and spot exactly which useState calls shouldn't exist, catch re-render problems before you reach for memo, and audit a CSS and design system setup for the "fifty shades of gray" problem that shows up in every AI-generated UI.
This module walks through what actually happens when you run install: hundreds of megabytes of strangers' code, transitive dependencies you never chose, and a lock file that either protects you or gets deleted the first time someone hits a bug. You'll learn to read semver ranges as blast radius (exact versions in apps, caret ranges only in published libraries), commit and enforce lock files with npm ci, spot diamond dependency conflicts and peer dependency mismatches, and configure two settings, a seven day minimum release age and lifecycle scripts off with a named allowlist, that stop most supply chain attacks before they run. You'll also work through a real case where a malicious patch update to a popular utility package with 14 million weekly downloads leaked secrets from 35,000 CI pipelines, and use it to build a habit of scanning diffs for package names and registry URLs you don't recognize. By the end you'll know how to decide whether a package belongs in your project at all, triage audit output into real risks instead of a pile of maybes, and tell tree shaken code that actually ships from dead weight sitting in your bundle.
This module is where you stop treating the database as an afterthought and start treating it as the actual shape of your app. You'll work through entities, attributes, and cardinality until you can model a real domain (what something IS versus what HAPPENED to it) as plain tables and keys before writing a single line of code. You'll learn to normalize to third normal form by default, when denormalization is a legitimate bet instead of laziness, and when a JSON column is honest versus when it's hiding a schema you're afraid to commit to. By the end you'll know how to pick surrogate versus natural keys, write constraints that actually enforce your business rules, choose between managed, self-hosted, and embedded databases without lying to yourself about your real requirements, and default to PostgreSQL unless you can name the specific signal that says otherwise.
This module gets you past treating SQL as a foreign language and into treating it as a set of rules you can reason about. You'll learn why the query runs in a different order than you wrote it, why JOINs multiply rows when you least expect it, and how to count things correctly without double-counting or dropping nulls. You'll pull apart isolation levels through a double-booking scenario, fix read-check-write races with unique constraints and SELECT FOR UPDATE, catch N+1 patterns before they wreck your p99, and read an EXPLAIN ANALYZE plan to find where estimated rows diverge from actual rows. By the end you'll know when to reach for a CTE versus a subquery, why NOT IN with nulls is a landmine, when a window function saves you from pulling data out to compute it elsewhere, and when a materialized view is the fix instead of another index.
This module is about what happens the moment your database stops cooperating: connection pools exhausted under load, a migration that locks a production table, two writers stomping on the same row, a replica serving stale reads while you think everything's fine. You'll learn to calculate pool size correctly (cores times two plus disk concurrency, divided across your instances), run schema changes with expand-and-contract and CONCURRENTLY indexes so nothing locks up, choose between atomic SQL, optimistic locking, and SELECT FOR UPDATE depending on what you're actually protecting, and climb the scaling ladder in the right order instead of sharding a table that just needs an index. By the end you'll know how to read replication lag as a measure of real data loss, what a failover actually does to your old primary, and why a backup you've never restored isn't a backup, it's a guess.
This module treats your API as a legal document, not a code artifact. You'll learn to tier routes as internal, partner, or public before writing a single handler, pick HTTP status codes that actually mean something (422 for validation, 409 for version conflicts, 401 versus 403), default to cursor pagination with a tiebreaker key, and ship one RFC 9457 error shape across every endpoint. You'll compare REST, GraphQL, gRPC and tRPC on when each one earns its cost, then lock down versioning and enum policy so 'additive' stops being your excuse for breaking changes. By the end, you'll be able to design a contract that survives real consumers: one that documents deprecation with Sunset headers, requires idempotency keys on every money-moving POST, and treats every observable behavior as a promise the moment enough people depend on it, whether you documented that behavior or not.
This module takes you through the entire path a request travels, from socket to DNS to TCP/UDP to TLS to HTTP/2 and HTTP/3, so you stop treating "the internet" as a black box. You'll learn to bisect a networking problem the way engineers actually do it: dig for name resolution, mtr for reachability, curl -v for the handshake, curl -w for the five timing numbers, only opening your application code once the network is cleared. You'll set DNS TTLs to 60 seconds before a cutover instead of hoping for propagation, automate certificate renewal with alerts 14 days out, and configure explicit connect timeouts, read timeouts, pool sizes and jittered retries on every outbound client so your retries don't become the outage. You'll also fix CORS by routing through a reverse proxy instead of guessing at allowlists, and calculate real latency budgets from physical distance, like the 75ms each way between New York and London. By the end you can look at a slow request and point to the exact hop that's costing you time, whether that's a cold DNS lookup, a missing HTTP/2 connection reuse, or a TLS handshake that never needed to happen.
This module gives you a real decision tree for real-time systems: when to reach for SSE, WebSockets, long polling, or webhooks, based on three numbers (direction of data flow, freshness budget in seconds, and peak concurrent connections) instead of whatever's trendy. You'll learn to reconnect WebSockets without leaking auth through cookies or query strings, using Origin allowlisting and token-based handshakes, and to write the four-step webhook handler that survives duplicates and out-of-order delivery: verify the HMAC on raw bytes, dedupe on the provider's event id, enqueue, and return 200 in under 50 milliseconds. You'll also be able to separate commands from events instead of mislabeling instructions as facts, apply event sourcing to a single aggregate without turning your whole system into a ledger, start CQRS at the simplest useful level, and handle connection state at scale with backplanes and TTL-based presence instead of relying on disconnect events.
Working code and safe code are different claims, and this module closes the gap. You'll run a thirty-minute threat model using STRIDE on trust boundaries, spot injection and XSS before they hit review, and fix the authorization checks AI keeps skipping by denying by default and returning 404 instead of 403. You'll wire up authentication you buy instead of build (PKCE, passkeys, Argon2id), rotate secrets with least privilege, and commit config for defense in depth like CSP and HSTS so it's not a one-off fix. By the end you'll be able to walk through the OWASP Top Ten as a checklist against your own app, tell the difference between a bouncer at the door and a key to every apartment when reviewing access control, and lock down cookies, JWTs, and CORS without guessing.
This module is about what happens when your code hits reality instead of the happy path AI generated for you. You'll learn to classify errors as retryable or not right on the error object, set timeouts on every external call (yes, including the Postgres pool acquire timeout that ships at zero), and build retries with exponential backoff, jitter, and one retry layer instead of three stacked on top of each other. You'll also work through circuit breakers, bulkheads sized with Little's Law, and fallback ladders that keep checkout running when recommendations fall over. You'll see why a slow dependency is more dangerous than a dead one, how partial failures like a charge with no order actually happen, and how to alert on error rate instead of raw volume so you page on symptoms and file tickets on causes. By the end you'll design error handling as architecture, not cleanup, and you'll be able to predict, in three lines, what your function does when a call is slow, down, or wrong before you ever ship it.
This module rebuilds your testing strategy around one question: does this test catch a real bug, or just prove code ran? You'll learn to write the behavior sentence before the test and delete tests that break during safe refactors, size your suite by where complexity actually lives (domain logic pulls weight toward unit tests, glue-heavy apps push it toward integration tests against a real containerized database), and double only at process boundaries using fakes over mocks with outcome-based assertions. You'll also pick up property-based testing to find inputs you'd never think to type, contract testing to catch breaking API changes before customers do, and mutation testing to get an honest score instead of a coverage percentage that counts executed lines but not verified behavior. By the end you'll know how to review AI-generated tests for real assertions, set a flaky test policy with actual deadlines, and decide when TDD earns its keep as a design tool instead of a ritual.
This module takes you from flying blind to actually seeing what your system is doing at 3 AM when nobody wrote down the question in advance. You'll structure logs as events instead of sentences, tell the difference between what belongs on a metric label versus a log field (cardinality is the line, and it decides your bill), and stamp a traceparent ID at the edge so it survives every hop through queues and background jobs. You'll build dashboards around the four golden signals, set an SLO from last month's real numbers, and write burn-rate alerts instead of CPU alerts so your on-call stops getting paged for nothing. By the end you'll know how to instrument once with OpenTelemetry and export anywhere, sample traces so errors and slow requests always survive the cut, and keep your observability stack from sharing a failure domain with the app it's supposed to be watching.
This module strips away the Docker cargo-culting and gets into what a container actually is: a process on the host kernel wearing namespaces and cgroups, not a tiny VM. You'll learn why your app needs to handle SIGTERM as PID 1, why layer order controls your eleven-minute build times, why localhost lies to you across container boundaries, and why pinning base images by digest beats trusting a mutable tag. You'll also lock down runtime with non-root users, cap_drop ALL, read-only filesystems, and memory limits that keep the OOM killer from taking down services you didn't expect, plus you'll know exactly when a plain VPS or serverless function beats reaching for Kubernetes. By the end you can write a Compose file for a full stack, set resource limits and health checks on every service, and decide whether a workload should be containerized at all instead of just assuming it should.
This module walks through the actual decisions cloud infrastructure forces on you: picking compute off your utilization curve instead of a tutorial, defaulting uploads to object storage with presigned URLs, locking down VPCs with security groups that reference other security groups, and setting IAM blast radius before something breaks instead of after. You'll size compute correctly for spiky versus steady workloads, catch the NAT gateway and data transfer charges that quietly inflate your bill, and convert click-built infrastructure into locked, version-controlled IaC with plan output reviewed in every pull request. By the end, you'll look at any workload and know whether it belongs on a VM, a container, or a serverless function, and you'll be able to explain exactly what the shared responsibility model does and doesn't cover before a misconfiguration turns into an incident.
This module builds the CI/CD pipeline that most teams fake and few actually run. You'll learn why integration hell is a tax you're already paying, how to build an artifact once and promote the same image digest through every environment, and where the line sits between continuous delivery and continuous deployment for your team right now. You'll set up zero downtime mechanics (readiness probes, SIGTERM handling, drain timeouts, expand-and-contract migrations), pick a deployment strategy that fits your risk tolerance (rolling, blue green, canary), and separate feature flags from deploys so shipping code and releasing it stop being the same decision. You'll also lock down pipeline security by scoping secrets per job, switching to OIDC short-lived credentials, and pinning third-party actions by commit SHA, and you'll walk away with a rehearsed rollback procedure instead of a panic plan you've never tested. By the end, you'll know exactly what makes a pipeline fast, safe, and boring in the best possible way.
This module walks through how architecture actually gets decided: not by picking monolith or microservices in the abstract, but by mapping team ownership, counting real pain points, and drawing boundaries where the org chart already lives. You'll learn to build a modular monolith with CI-enforced boundaries and per-module database roles, recognize the four forces that justify a service split, and calculate the real cost of decomposition (availability multiplying downward, idempotency keys, a pager rotation per service) before you commit to it. You'll also work through data ownership rules like staleness budgets and transactional outboxes, decide who owns what data across services, and use the strangler fig pattern to migrate a system one endpoint at a time without betting the company on a rewrite. By the end you'll be able to state, with a number, whether your system needs to be decomposed at all.
This module rips apart the assumption that async just means "faster." You'll learn when to actually move work off the request path (hint: only when the user won't see the result on the next screen), the real difference between queues and streams, and why a Postgres table with SKIP LOCKED beats a broker at low volume. You'll build idempotency keys with unique constraints so retries stop double-charging people, wire a transactional outbox so you never split a database write from a broker publish, and set up DLQ alerting and backpressure rules that shed load with 503 and Retry-After before a traffic spike becomes a data integrity incident. By the end you'll know how to design background jobs, saga transactions across services, and dead letter handling that hold up when individual components fail, not just when everything goes right.
This module walks through caching from the CDN edge down to Redis, covering HTTP caching with ETags and Vary headers, cache-aside versus write-through, eviction policies like allkeys-lru, and invalidation strategies that actually expire on time. You'll learn why shared caches without identity in the key leak private data across users, and how a simple two-user response test catches that failure before it ships. By the end you'll be able to set TTLs and jittered expirations with intent, pick the right maxmemory-policy instead of trusting Redis's noeviction default, and name the handful of things that must never sit behind a shared cache regardless of how tempting the performance win looks.
This module kills the habit of guessing at performance problems. You'll classify slowness into CPU, memory, I/O, or contention (and learn why contention fakes I/O on every dashboard), read a flame graph without pretending to understand it, and set up default instrumentation: a 99Hz sampling profiler in production, spans on outbound calls, and slow query logs at 100ms sorted by total time. You'll work through load testing, autoscaling that arrives before the traffic spike instead of after, rate limiting with token buckets, and the real choice between a bigger machine, more machines, or a different architecture. By the end you'll know how to prove a fix worked with a before-and-after number taken the same way, cap an autoscaler at what your database connections can actually survive, and recognize when spending five more engineer-days to shave a few hundred dollars off a cloud bill is a bad trade.
This module rewires how you read distributed systems: timeouts mean "I don't know," not "it failed," and you'll learn why silence can hide four completely different failures (lost request, slow server, crashed server, lost reply). You'll walk through the eight fallacies as a working checklist, use monotonic clocks and version vectors instead of wall-clock timestamps, and replace CAP with PACELC so you can state, dataset by dataset, whether it refuses or accepts writes during a partition. You'll come away defending concrete defaults, single-leader replication with a synchronous cross-zone replica, odd cluster sizes of three or five, consensus rented from etcd rather than built by hand, and a fencing token on every distributed lock. You'll also separate liveness checks from readiness checks, set failure detection timeouts above worst-case garbage collection pauses instead of averages, and build a recovery pattern (persisted state machine plus sweeper) for any multi-step operation that crosses a service boundary.
This module walks through what actually happens between a card swipe and money landing in your bank account, and where that process breaks. You'll learn to model a payment as three separate events (authorize, capture, settle) instead of a single boolean, keep raw card data off your servers entirely, and build a subscription state machine that gates access on a timestamp rather than a fragile status string. You'll set up webhook handlers that can't double-charge a customer even during a retry storm, build a dunning and proration schedule that doesn't punish paying users, price in fraud tolerance as a dial instead of an on/off switch, and run daily three-way reconciliation so you find your own bugs before your bank does. By the end you'll be able to pick a payment provider without locking yourself into it, fight chargebacks worth fighting and refund the ones that aren't, and handle currency, local payment methods and tax without guessing.
This module treats your event tracking as production code, not an afterthought bolted on by marketing. You'll design an event schema before writing a single track() call, decide which events fire server-side versus client-side, and build an identity_map that resolves one human across five user IDs without ever mutating history. You'll set up experiment infrastructure with deterministic hashing, exposure logging, and a sample-ratio-mismatch check that halts a broken test, plus a daily reconciliation between your analytics numbers and the billing system. You'll also learn why retention curves lie when the return action isn't a value action, how to sessionize events in a warehouse so the timeout is a parameter you control, and how to write privacy-compliant tracking where consent is enforced as part of the system, not a checkbox someone clicks once.
This module tears apart the attribution stack most teams treat as gospel. You'll build an immutable touchpoints table and run every attribution model as a query on top of it instead of trusting whatever number the ad platform hands you. You'll fire conversions server-side through a transactional outbox, dedupe with matching event IDs, hash identifiers correctly (no hashing empty strings, a mistake that quietly breaks feeds), and capture UTMs and click IDs in edge middleware before Safari's 24-hour cookie cap or your SPA router eats them. You'll design a geo holdout or ghost-ad lift study to find out which channels actually cause conversions versus which ones just claim credit, treat automated bidding as a training-label problem instead of a black box, and set up a weekly reconciliation job to catch ad fraud before it eats your budget. By the end, you'll know how to build measurement infrastructure that survives an audit instead of one that just looks good on a slide.
This module covers how machine learning models actually learn: fitting patterns to examples rather than reasoning through them, which means a model is exactly as good and exactly as biased as the data behind it. You'll go through supervised, unsupervised, and reinforcement learning, understand why data leakage produces scores that look great and mean nothing, and build train/validation/test splits that hold up under real time and entity constraints. By the end you'll be able to spot overfitting from the gap between training and validation scores, read a confusion matrix instead of trusting a single accuracy number, choose your default stack (a linear baseline plus gradient boosted trees for tabular data, not a neural network by default), and recognize the cases where the right engineering decision is to not build a model at all.
This module walks you through adding AI features without wrecking your budget or your users' trust: renting a hosted model instead of fine-tuning too early, writing prompts as versioned code with refusal strings, chunking documents at 400 to 800 tokens for retrieval that actually works, and putting token caps and a kill switch in place before launch, not after. You'll cover the five rungs from a plain API call to self-hosted GPUs, learn why prompt injection is a permissions problem rather than a persuasion problem, and see how structured outputs create a trust boundary between what the model suggests and what your code actually executes. By the end you'll be able to build a full RAG pipeline stage by stage, pick a model without chasing leaderboard rankings, and ship an AI feature with cost controls and an evaluation set already in place instead of bolting them on after something breaks.
This module takes you from "it worked in the demo" to an AI feature that survives production traffic. You'll pick interaction patterns by reversibility instead of raw model capability, treat prompts as versioned code with hashes and golden-set diffs, and design for prompt injection instead of hoping it won't happen. You'll build grounding and citation checks that let the system abstain when retrieval is weak, bound agent loops so they can't run wild, and set up observability that tracks citation failure rate and escalation rate above uptime. By the end you'll know how to order prompts for provider caching, cascade from cheap to expensive models without letting escalation run away, and rehearse a fallback path for the day the provider goes down, because that path never runs on its own until it has to.
This module replaces guesswork with a method. You'll write hypotheses before touching code, run a debugging journal that separates observed from tried from ruled out, and apply the forty-five minute rule so a stuck session becomes a signal to stop instead of push harder. You'll learn to bisect a search space with binary search, git bisect, and delta debugging instead of scanning line by line, read stack traces and flame graphs to separate proximate cause from root cause, and debug across the client, the network tab, the database layer, and containers where four things never make it into the image. By the end you'll design concurrency bugs out of existence with atomic updates, unique constraints, and idempotency keys, confirm races by deliberately widening the timing window, and strip out every temporary log and relaxed timeout you left behind, because leaving debugging scaffolding in place is how a fixed bug turns into the next outage.
This module covers what happens after the deploy button, from probes and shutdown ordering to migrations you can't undo, alerts nobody ignores, and backups you've actually restored. You'll be able to write a launch checklist that answers whether your service is healthy, slow, and reversible in ten minutes, set liveness and readiness probes correctly, ship a migration that survives old and new code running together, and build alerts with runbook links instead of noise. By the end you'll know how to stop the bleeding during an incident before you diagnose it, write runbooks and ADRs so knowledge doesn't live only in your head, and verify a backup by actually restoring it and timing the result as your real recovery time.
This course contains the use of artificial intelligence.
You can build an app with AI in a weekend. Then real users show up, and running code turns out to be nowhere near working software. This course covers what happens in between: how state actually behaves, why your schema decisions matter, what breaks at your first traffic spike, how deploys go wrong, and the security holes AI generated code ships with.
38 modules from first principles to production, each built around decisions instead of theory: real postmortems from companies that learned the hard way, assignments you build yourself, and the defaults a principal engineer would pick. You'll trace a request through DNS, TLS, and load balancers so outages stop being mysteries.
Along the way you'll read the SQL your ORM writes, migrate a live schema without losing data, and know when a cache is saving you and when it is quietly lying. You'll wire up CI that blocks bad deploys, queues that survive restarts, payments that pass compliance, and AI features with real cost and latency budgets instead of vibes. There are modules on debugging as a discipline, on observability, and on shipping mobile through app store review. If you started coding last month with AI, everything is explained from first principles.
If you have shipped for years, the sharp edges and the defaults will still surprise you. Every module stands alone, and the course compounds if you take it in order.
Made for people who ship with AI and want their software to hold.