Everything the adaptive question bank can teach and test in Hosting & Deployment, from foundations through advanced practice. Work through it in order, or start practicing and let the questions find your level.
A. What "deployed" actually means — the request path
This is why a site can be perfectly healthy and still unreachable: the failure happened before any server was contacted. Checking resolution separately from the request is the first split in any diagnosis.
Each stage fails with its own signature — refused or timed out, a certificate or handshake error, or a status code. Reading which one you got tells you how far the request actually traveled.
Almost every confusing symptom here comes from not knowing which of the two answered. A response can be correct at one and stale, cached or blocked at the other.
The choice decides whether caching, filtering and origin concealment are in play at all. Turning proxying off to debug also turns off every protection you were relying on.
Keeping them separate is what allows shipping code that is not yet switched on, and it means a rollback can be a configuration change rather than a rebuild. Conflating them forces every change to move at the same speed.
The operational surface does not disappear when a platform handles it; it is transferred. What you get back with more control is patching, scaling and a pager.
Detection guesses the stack from the files present, which works until the repository stops looking typical. Knowing what was inferred matters the moment the inference is wrong.
The saving is on the wire, so the origin's work is unchanged and already-compressed formats gain nothing. Compressing images or video again costs CPU for no benefit.
It removes setup latency from the critical path by paying it during idle time. Used indiscriminately it opens connections that are never used, which costs the client instead.
B. Domains, registrars and delegation
The commonest wasted hour in this area is editing records at a provider that is no longer authoritative. Confirming who answers for the zone precedes any record change.
Delegation is held one level up, at the registry, rather than in the zone itself — which is why the change is made at the registrar and takes effect there.
One hands the whole zone over and the other borrows a single hostname. Features that need to see the zone are unavailable in the second arrangement.
The distinction matters because the record types available differ between them, which is the root of most apex configuration problems. A subdomain has options the apex does not.
The signature chain is anchored by a record held at the registrar, so the two must move together. Failing validation takes the domain down completely rather than degrading it.
C. DNS record types
Clients choose between the families on their own, so a misconfigured address in one of them produces failures for a subset of users that reproduces nowhere else. Test both explicitly.
Because it delegates to another name, the eventual answer depends on a record you may not control. It also adds a resolution step, which costs latency on a cold lookup.
The exclusivity is the rule behind several apparently unrelated errors, since any name needing a TXT or MX record cannot also be an alias. Verification records are the usual collision.
The provider performs the indirection and publishes the result as an address record, which satisfies the exclusivity rule. The convenience depends on the provider refreshing it as the target changes.
Mail and web share a zone and nothing else, so a migration that recreates only the web records silently stops delivery. Enumerate the existing zone before replacing it.
Because it constrains issuance rather than serving, it fails at renewal time rather than at setup — often months after the record was written, when nobody connects the two.
Two answers for one name means a reported problem may be unreproducible from where you are standing. Establish which view the reporter had before investigating anything else.
D. TTL, caching and "propagation"
It bounds how long a resolver may keep an answer, so it governs how long a stale answer survives after a change. It says nothing about when the record was saved.
Since nothing is distributed anywhere, the wait is the tail of previously issued answers running out. Different users finish waiting at different moments, which is why a change looks partial.
The value in force when the old answer was cached governs the cutover, so lowering it afterwards changes nothing. The reduction has to precede the change by more than the original lifetime.
A resolver remembers the absence too, on a timer from the zone's own parameters. Creating the record does not clear that memory, which is why a new name can appear broken.
Clients keep the old answer for its lifetime, and some ignore the value entirely, so recovery time cannot be bounded. Use it for recovering from an outage, not for surviving one transparently.
E. TLS certificates and issuance
Trust flows from the authority the client already trusts, not from the server presenting it, which is why a self-signed certificate is cryptographically fine and still rejected.
A certificate can look correct in a dashboard and fail in a browser when the hostname is only in the legacy field. Check the list that clients actually read.
It substitutes for exactly one label, so neither the bare domain nor a deeper name is covered. Assuming it covers everything below is the standard misreading.
One proves control of the server and the other of the zone, which is why only the second can cover a wildcard. Which you can use is decided by what you control.
Because lifetimes are short, the interesting failure is always automation that stopped working, and it surfaces weeks after the breakage. Monitor the expiry date, not the issuance.
Browsers often repair an incomplete chain from cached intermediates while stricter clients do not, which produces a failure that only some callers see. Test with a client that does not help.
The hostname is sent before encryption is established, so the server can choose. That also means the name is visible on the wire even though the traffic is not.
The instruction persists in the browser for its stated lifetime, so a mistake cannot be undone by reverting the server. Start with a short lifetime and raise it once confident.
These are disabled because working attacks exist, not as housekeeping. Re-enabling one to accommodate an old client reopens the attack for everyone.
F. Origin trust and the two TLS legs
Since the legs are configured independently, the security of the whole is the weaker of the two — and only the first one is visible to the user. The padlock reports one leg.
The user sees a secure connection while the second hop crosses the network in the clear, so the indicator is accurate about what it measures and misleading about the system.
Encrypting without validating stops passive eavesdropping and not an active substitution, because any certificate is accepted. Only validation makes the connection authenticated.
Each side is behaving correctly in isolation: the origin insists on upgrading and the edge keeps arriving unencrypted. The loop is a configuration disagreement, not a bug.
Anything that can reach the origin directly bypasses every protection applied at the edge, so concealment is not enough. Restrict by address, shared secret or client certificate.
G. CDN caching semantics
Each location fills independently, so a site can be fast where you are testing and cold everywhere else. The first user in each region pays the origin cost.
Two audiences, two directives, and the shared one wins where both appear. That separation is what lets a browser hold a copy briefly while a CDN holds it for much longer.
One forbids storage and the other permits it while requiring a check before reuse. Reaching for the stronger directive when the weaker one is meant discards a free revalidation.
It is the directive that keeps per-user content out of a shared cache, which is the difference between a personalized page and a leaked one. Omit it and the CDN may store it.
The user is never made to wait for a refresh, at the price of one response being slightly out of date. It converts a latency problem into a freshness decision.
It turns an origin failure into stale content instead of an error page, which is usually the better outcome for the visitor. The window is how much staleness you accept during an outage.
A revalidation that matches returns headers only, so the saving is the body. That is where most of the bytes are, which is why this is worth doing on large assets.
Because a change produces a new URL, the old one can never be stale, so a long lifetime is safe. The scheme only holds if the hash really covers the content.
Fetching part of an object is what makes seeking in media and resuming an interrupted download possible. Support has to be present at every hop for it to work end to end.
Access is granted by a token in the URL with an expiry, so the content can sit in a cache without being public. The link is the credential, which means it must be treated like one.
H. Cache keys, purging and invalidation
What goes into the key decides what shares a copy, so two requests that look equivalent to a person may be entirely separate entries. Hit rate is a function of the key.
Each distinct value of the named header creates another stored copy, so varying on something high-cardinality fragments the cache into near-uniqueness. Vary on the smallest set that matters.
Campaign parameters differ per visitor and usually do not change the response, so leaving them in the key stores the same object thousands of times. Strip what the origin ignores.
Purging by URL requires reproducing the key exactly, which is error-prone; tagging lets one call clear a related set. The tag is applied when the object is stored.
There is no moment at which it is guaranteed complete everywhere, so a deploy that depends on it has a race. Versioned URLs avoid needing the guarantee at all.
A response carrying a session cookie, stored in a shared cache, is handed to the next requester along with that session. Responses that set cookies must never be shareable.
I. Reverse proxies and load balancers
Because it owns both connections it can inspect, modify and answer without the backend being involved. Everything the edge does well follows from holding that position.
Parsing the protocol costs work and buys routing decisions; forwarding bytes is cheap and blind. Which layer you are at decides what questions the balancer can answer.
With uniform fast requests the two behave identically, which is why the difference only appears under mixed durations. A slow request pins a backend the first strategy cannot see.
Pinning works, and the cost is that the backend now holds state nobody planned for. It cannot be drained or replaced without disrupting the users attached to it.
The header is client-supplied unless something trustworthy overwrote it, so using it for rate limiting or access control without validation is a spoofable control.
Routing follows measurement or location rather than a fixed order, so users are spread across healthy pools continuously rather than moved only after a failure.
Filtering at the edge stops known-bad traffic before it consumes origin capacity. It recognizes patterns, so it reduces exposure rather than eliminating a vulnerability.
J. Health checks, draining and zero-downtime
One answers whether to restart and the other whether to send traffic. Wiring a dependency check into the restart question turns a downstream blip into a crash loop.
A check that exercises a shared dependency reports the same failure from every instance at once, removing the whole fleet for a problem restarting cannot fix.
Without an allowance the supervisor judges a still-initializing process as failed and restarts it, so a slow boot becomes a loop that never completes. The allowance must exceed the real boot time.
The grace period is fixed, so the process either finishes within it or is killed regardless. Handling the first signal is what converts a hard stop into a clean one.
The ordering matters more than the duration: refuse new work first, then complete what is in hand. Reversing it drops requests that had already been accepted.
Removal propagates to the balancer after the fact, so traffic keeps arriving for a moment after readiness fails. Continuing to serve during that window is what makes the deploy invisible.
K. Static, server-rendered and hybrid output
With no process running there is nothing to scale under load, patch for a vulnerability or exploit. The constraint is that every page must be knowable at build time.
Cost and failure surface now track traffic, because every request does work. That is the price of content that depends on who is asking.
The server responds quickly with nothing useful, and the device does the work. The delay lands on the slowest hardware, and a crawler may see the empty shell.
Pages are served from a prerendered copy and refreshed behind the scenes, so origin work is bounded regardless of traffic. The tunable is how stale a page may be.
Routing happens in the browser, so the server knows nothing about the paths the app defines. Without the rewrite, only navigation from the entry page works.
The value is compiled in, so the deployed artifact carries whatever was set when it was built. Changing the environment afterwards requires a rebuild to take effect.
L. Serverless and edge runtimes
Concurrency is handled by creating more instances rather than by queueing inside one, so there is no pool of yours to size. Limits come from the platform and from what you call downstream.
Work done at module load runs on every new instance, so imports and initialization are paid by the unlucky request. Moving work inside the handler trades cold latency for warm latency.
Sharing a process gives near-instant startup and takes away native modules and parts of the runtime. The startup win and the API restriction are the same design decision.
Awaiting a network call consumes no processor time, so a limit expressed in CPU permits a much longer real duration. The number does not mean what it appears to.
The instance may be frozen once the response is sent, so anything not awaited simply stops. Background work needs an explicit mechanism, not a floating promise.
Module-level values persist while an instance stays warm and vanish when it does not, so they are a valid cache and never a place to keep anything that must exist.
Outbound addresses are shared and change, so an upstream that permits access by address cannot be satisfied. Authenticate with a credential or route through a fixed egress.
M. State, storage and data locality
Local writes are invisible to other instances and disappear with this one, so anything written there is both private and temporary. It is scratch space, not storage.
Sending the file through the application spends its memory and time on bytes it does not need. A signed URL lets the client upload directly and the app record the result.
A write propagates over seconds, so a read immediately afterwards can return the previous value. Designs that read back what they just wrote need a different store.
Anything that must be counted or held exactly once needs one authority, because replicas cannot agree quickly enough. Distributing the write is what breaks these primitives.
Running compute close to the user but far from the data pays the distance on every query, several times per request. Place the compute next to what it reads.
A legal requirement about where data lives constrains the whole path — compute, caches, logs and backups — not only the primary store. Copies count.
N. Container images and the Dockerfile
Everything below the writable layer is shared and immutable, which is why rebuilding one step invalidates what follows and why runtime writes are not persistent.
Removal in a later layer hides the file without removing it from the earlier one, so anything ever added remains extractable. Never add a secret intending to delete it.
A minimal base reduces size and vulnerability surface by removing programs, including the ones you would use to investigate a problem. The tradeoff is real and worth making deliberately.
The broader instruction also fetches remote files and unpacks archives, so it can do something surprising with an ordinary-looking argument. Prefer the one that does exactly one thing.
One names the program and the other supplies default arguments. Writing the shell form inserts a shell as the main process, which then swallows the signals your app needed to receive.
Unless the image says otherwise the process runs with full privileges inside the container, and isolation is a boundary rather than a guarantee. Declaring a user is one line.
It lets the runtime distinguish a process that is alive from one that is working, which is the state a plain process check cannot see. Hung and dead need different responses.
O. Build cache, image size and reproducibility
Dependencies change rarely and source changes constantly, so installing before copying the source keeps the expensive step cached. Reversing the order rebuilds everything on each edit.
Because each layer depends on the one before it, an early change rebuilds everything after it regardless of relevance. Put the volatile steps last.
Everything in the context is sent to the builder and participates in change detection, so an unignored directory that changes constantly defeats the cache entirely.
Compilers, dev dependencies and source stay in the first stage and never reach the shipped image. The result is smaller and exposes less.
Their values are recorded in the image metadata, so anyone with the image can read them. A value that must stay secret needs a mechanism that leaves no trace in the layers.
A floating tag makes the build non-reproducible, so the same input can produce a different output later. Pinning is what lets you distinguish your change from the base moving.
P. Registries and the orchestrator handoff
A tag is a mutable pointer and a digest names exact content, so deploying by digest guarantees that what ran in staging is what runs now. Tags are for humans.
A node that already holds a tag may not fetch it again, so re-pushing the same tag can leave old code running. This is why mutable tags and caching interact badly.
One tag can index several architectures, and a mismatch is not detectable until the image runs. Building on a different architecture from the target is the usual cause.
Credentials must be available where the image is pulled, and a missing one presents as a scheduling or pull failure rather than anything resembling an application error.
Writing to the standard streams lets the platform collect, rotate and ship the output. Managing files inside a container means managing them on a filesystem that disappears.
Q. Configuration and secrets in the pipeline
Keeping environment differences outside the artifact means one build can be promoted anywhere. Anything baked in forces a rebuild per environment and breaks that property.
A rebuild per environment means the bytes tested are not the bytes shipped, so staging stops being evidence. Promote the artifact rather than the commit.
A secret should be writable and not readable afterwards, which rules out dashboards that display it, build logs that echo it and debug endpoints that dump the environment.
A prefix is an explicit declaration that the value will be published in the client bundle, which is permanent. Anything that should stay server-side must not carry one.
If rotating requires a rebuild, it will not happen under time pressure, which is exactly when it is needed. Make the credential readable at runtime instead.
Exchanging an identity for a per-run token removes the long-lived key from the system entirely. The benefit is that there is nothing durable to steal, not that it is faster.
R. CI/CD: build once, preview, promote
Rebuilding from the same commit can still differ — a moved base image, a floating dependency, a different builder. Promoting the tested bytes removes that whole class of surprise.
Because every build stays addressable, promotion and reversal are both pointer moves. Nothing has to be rebuilt to go back, which is what makes rollback fast enough to use.
A reviewer can exercise the change rather than imagine it from a diff, which catches the problems that reading does not. The environment's value is that it is real.
An ephemeral environment pointed at live data is a production write path with a temporary name, and it will be treated casually precisely because it looks disposable.
A check that cannot fail the run is decoration. The gate is the ability to stop the deploy, not the presence of the step.
Credentials that can deploy are production credentials wherever they sit, so a workflow that untrusted code can trigger must never receive them. Fork pull requests are the classic exposure.
S. Release strategies and rollback
Both versions serve simultaneously for the length of the rollout, so they must tolerate each other — shared data, shared caches and shared sessions included.
Cutover and reversal are both single switches because the previous fleet is still running. The cost is paying for two environments during the overlap.
Exposure is limited while evidence is gathered, so a defect is found by a small share of users. The point is bounding the blast radius, not slowing down.
Without a comparison against the existing version, a gradual rollout only delays the same outage. The metric and the threshold are what make it a decision.
Shipping the code inert and enabling it separately means switching a behavior off takes seconds and no deploy. It also leaves flags to be removed later, which is its own cost.
Reverting the artifact is quick, but side effects already committed cannot be taken back. Once a migration has applied or a message has been sent, forward is the only direction.
Adding, dual-writing, backfilling and only then removing keeps every intermediate state compatible with both versions. A rename in one step breaks whichever version is not yet replaced.
T. Monitoring, logging and release signal
Each answers a different question — what happened, how much, and where the time went. Reaching for the wrong one is why investigations stall.
Fields can be filtered and aggregated; the same information in a sentence can only be searched as text. The cost is writing the field names up front.
Without a shared identifier, a specific user's failure cannot be reconstructed across services. Threading it through every hop is what makes the individual case findable.
An average is dominated by the majority that are fine, so the slow tail disappears into it. The users who complain are in the tail by definition.
Together they cover demand, correctness, speed and capacity, which is enough to tell whether a release is safe to widen. Watching one of them is how a regression is missed.
Resource alerts fire for conditions users never notice, which trains the on-call to dismiss the pager. Alerting on what users experience keeps the signal meaningful.
Logs inherit the obligations of whatever they contain, and the content is often accidental — a token in a query string, a body captured on error. Retention applies to that too.
Each distinct combination of labels is a separate series, so adding one high-cardinality label multiplies the total. A user id as a label is the standard way to break a metrics bill.
U. Cost, egress and capacity
Traffic in is usually free and traffic out is metered, so an architecture that moves data between providers pays repeatedly for the same bytes. It is invisible until the invoice.
Every request answered at the edge is one the origin did not serve, so the ratio shows up as money, capacity and latency at once. Improving it is the cheapest optimization available.
Two separate meters mean two separate ways to overspend, and they respond to different fixes. Knowing which dominates tells you whether to reduce calls or reduce time.
Keeping capacity warm costs money continuously; releasing it costs the first user a cold start. Which is right follows from the traffic pattern, not from a preference.
Where the memory tier also sets processing share, a larger instance can finish enough sooner to cost less overall. The cheapest tier is not automatically the cheapest result.
Runaway retries, crawlers and misfiring scheduled jobs convert directly into spend, and nothing stops them by default. A spend alert is the only thing that notices in time.
Paying to avoid operational work only pays where that work is genuinely happening. Buying away a burden nobody was carrying is just cost.
V. Production failure modes
Listening on a fixed port, or only on the loopback address, works on a laptop and fails every platform health check. The port is supplied and the interface must be the wildcard.
Simultaneous expiry sends every edge to the origin at once, which is when the origin is least able to cope. Spreading the expiry or collapsing the requests prevents it.
Retries at several layers multiply rather than add, so a brief failure becomes sustained load. Backoff, randomization and an overall budget are what keep them bounded.
Every instance opening its own pool means connections scale with concurrency, which a database cannot absorb. A shared pooler fixes it; a larger per-instance pool makes it worse.
A cached page requests assets whose names no longer exist, so the application breaks for users holding the old page. Invalidating the page is what ends it.
A call with no deadline holds a worker indefinitely, so a slow dependency consumes the whole pool. The timeout is what keeps one degraded service from becoming an outage.
Until a restore has been performed, the backup is an assumption about a file. The drill also measures how long recovery actually takes.
One bounds data loss and the other bounds downtime, and they are satisfied by different investments. Stating both turns recovery from a hope into a requirement.
W. Web security headers, cookies and CORS
A secure page pulling an insecure resource is either blocked or silently upgraded, so the page can break in ways the padlock does not explain. The indicator covers the document.
Constraining where executable content may come from means an injected script has no permitted origin. It reduces the impact of a flaw rather than removing the flaw.
Permitting inline code or dynamic evaluation admits exactly what the policy exists to block. A nonce or hash restores the capability without reopening the hole.
Without it a browser may infer a type from the bytes and execute something the server intended as data. The header makes the declared type binding.
Framing is controlled by the response headers because the attacker owns the outer page. Nothing written inside the document can prevent it.
Making the cookie unreadable to scripts means a successful injection still cannot take the session. It limits what a flaw yields.
It prevents the cookie from being sent over an unencrypted connection at all, which closes the window where a downgrade would expose it.
The attribute decides whether the cookie accompanies cross-site requests, which is the mechanism behind cross-site request forgery. Allowing it requires the encrypted-only flag too.
It controls how much of the current address is disclosed when a user leaves, which matters because paths and query strings often carry identifiers.
It relaxes a restriction browsers impose on scripts, so it grants access rather than restricting it, and a non-browser client ignores it entirely. It is not authorization.
Requests outside a narrow simple set are checked first with a separate request, so the permission is confirmed before the real one is sent. A custom header is the usual trigger.
The wildcard and credentialed requests are mutually exclusive by design, because together they would expose authenticated responses to any site. Name the origin instead.
Headers that are absent do not fail loudly; they simply leave the protection off. Starting restrictive and relaxing per surface makes omissions visible.
X. SLOs, error budgets and incident practice
It is the thing being measured rather than the standard being held to, and keeping the two separate is what lets the standard be debated without changing the measurement.
Committing to a target over a stated window makes it something that can be argued about, budgeted for and traded against feature work. A target without a window is not checkable.
The permitted failure is a resource to spend on change, so consuming it is the system working as intended. Exhausting it is information about pace, not a failure of character.
It converts knowledge held by one person into steps anyone can follow without context, which is the condition under which incidents are actually handled.
The useful output is the change that prevents recurrence, and naming an individual reliably stops people reporting the next one. Blame trades one fix for future information.
Y. Asynchronous work: queues, retries and idempotency
Work that the response does not need should not hold the response, so moving it behind a queue shortens the request and decouples the failure. The user stops waiting for it.
Arrivals above capacity become a backlog rather than a wave of timeouts, so the system degrades in latency instead of in errors. The backlog is the shock absorber.
Delivery guarantees usually permit duplicates, so processing the same message twice must be harmless. Designing for it is cheaper than trying to prevent it.
A key supplied by the caller lets the server recognize a retry of a request it already completed, which is what stops a retried payment charging twice.
Signaling upstream to slow down keeps the queue bounded, which is preferable to accepting work that will never be completed. Refusing early is a feature.
Parking messages that cannot be processed keeps one bad item from blocking everything behind it, and it preserves them for inspection rather than discarding them.
Z. Infrastructure as code and drift
Describing the end state lets the tool compute the difference, which is what makes a change reviewable before it happens. The plan is the artifact worth reading.
Reality diverging from the record usually starts with a change made directly in a console during an incident. It is a documentation failure before it is a technical one.
A scheduled run that expects no difference surfaces divergence while it is still small. Finding it during an emergency change is finding it too late.
A fork created after a license change, keeping the same language and workflow, so the practical question is governance and ecosystem rather than syntax.
Keentune is not affiliated with or endorsed by the organizations whose documentation informs these maps.
All exam, test, and product names and trademarks are the property of their respective owners and are used here for identification and reference only. Keentune is independent study practice — not affiliated with, authorized, or endorsed by any of these organizations.