What is a startup hook in a web framework, and what belongs in an eager check that runs there?
answer
- hooks run at defined boot moments
- the useful window is before listening
- pull verification forward in time
- fail at deploy, not at request
- exiting is not the only failure mode
basics
~20 sA startup hook is a callback the framework runs after wiring and before it accepts traffic. Eager checks belong there - validate settings, resolve critical components, verify required resources - so a broken process fails at boot, not at the first request.
solid answer
~50 sFrameworks expose **hook points** in the boot sequence — typically “after the object graph is built” and “after the server is listening” — plus matching shutdown hooks. The one that matters most runs after wiring and before the bind, because code there can still abort the boot. An **eager check** is verification deliberately pulled forward into that window: confirm required settings are present and coherent, force-resolve components that would otherwise be created lazily, open and test a connection to a resource the service cannot serve without, warm an expensive cache. The payoff is a **loud, early failure** — a deploy that stops with a named cause, instead of a process that starts happily and then fails the first real request. The cost is a slower, more failure-prone boot, so an eager check is worth adding only where the failure it catches is genuinely fatal.
go deeper
Know that frameworks let you register code to run during boot, and that code placed before the server starts listening can stop a broken process from serving at all.
Explain which hook points exist and what each may still do, and give concrete eager checks: settings coherence, forced graph resolution, one round trip to a required resource, cache warm-up.
Show judgment about the cost: boot time on every restart, and coupling that stops your service starting while a dependency is down. Know that reporting not-ready beats exiting for recoverable failures.
Treat boot-time verification as a fleet-wide policy. Decide which failures are allowed to block a deploy, and remember that an eager check multiplies one dependency's outage across every instance that tries to restart.
A framework's boot sequence is fixed, but it is not closed: it exposes **hook points** where application code can run at a defined moment. Knowing which hooks exist, and what may still be done at each, is the difference between a service that fails a deploy cleanly and one that fails a user's request confusingly. ## The hook points that matter - **After wiring, before listening.** The object graph exists, settings are bound, routes are registered — but the socket is not open. This is the *only* window where you can still abort the boot without having served anything, so it is where verification belongs. - **After listening.** The process is reachable. Work here is for things that must not block traffic: background schedulers, registering with a discovery mechanism, emitting a “started” event. - **On shutdown.** The mirror image, normally run in reverse order of startup so that a component is never torn down while something that depends on it is still running. ## What an eager check is An **eager check** is verification moved forward in time on purpose. Without it, a defect is discovered by whichever request first happens to exercise the broken path. With it, the same defect stops the boot. Good candidates: 1. **Settings coherence** — not just “the value parsed” but “these values make sense together”: a timeout smaller than the retry budget, a pool sized for one host but pointed at another. 2. **Forced resolution of the object graph** — in a framework that builds components lazily, ask the container to create everything now, so a missing registration is a boot error instead of a failed request. 3. **Credentials and required resources** — acquire the secret, open one connection, run the cheapest possible round trip against a dependency the service genuinely cannot serve without. 4. **Schema and version agreement** — confirm the data store's shape matches what the code expects, rather than discovering it on the first write. 5. **Warm-up** — fill a cache, establish minimum pool connections, pay one-time initialization costs before real traffic pays them. ## Fail fast versus start degraded | Approach | What a broken dependency does | Best for | |---|---|---| | Eager check that aborts the boot | deploy stops, old instances keep serving | defects that make the service useless anyway | | Eager check that only records the result | process starts but reports itself not-ready | dependencies that recover on their own | | No check at all (lazy) | first affected request fails | optional or rarely used dependencies | The middle row is the underrated one. Exiting is not the only way to fail fast; a process can complete its boot, keep the readiness signal negative, and retry the check in the background. Nothing is routed to it, the failure is visible, and it recovers without a redeploy. ## The costs you are trading against - **Boot time.** Every eager check is on the critical path of every start, every deploy and every automatic replacement of an instance. - **Boot-time coupling.** A check that requires another system to be up means your service cannot start while that system is down — exactly when you are most likely to be restarting things. - **False confidence.** A check that ran once at boot says little about the state of the dependency five minutes later; it catches misconfiguration far better than it catches outages. - **Noise.** A check that aborts the boot for something the service could work around trains people to bypass checks. ## How frameworks differ Some frameworks build the whole graph eagerly by default, so most wiring mistakes are already boot failures and an explicit check adds little; others build lazily and offer an opt-in verification step you must remember to switch on. Hook registration also varies — a callback list, an interface a component implements, or an event published on a lifecycle bus — but the guarantees are the same: ordering relative to the bind, and whether throwing aborts the boot. Check that second guarantee before relying on it: in some designs an exception thrown from a post-listen hook is logged and swallowed, which is precisely the case where a check silently stops protecting you. ## What an interviewer is listening for That you place verification *before* the socket opens; that you can name the trade (early loud failure versus slower, more coupled boot); and that you know exiting is not the only outcome available — refusing to report ready is often the better one.
- Should a failed eager check exit the process or start it in a not-ready state?Exit when the failure is permanent and the process could never serve — bad settings, a missing registration. Stay up but not-ready when the dependency can recover on its own, so no traffic is routed, the problem is visible, and recovery needs no redeploy. Exiting during a transient outage adds restart churn without fixing anything.
- Why can a hook that runs after the socket is open be a weaker place for verification?The process is already reachable, so a failure there races with real traffic, and in some designs an exception from a post-listen hook is logged rather than aborting the boot. Verification that is meant to gate serving belongs before the bind, where throwing still stops everything.
- What makes a good eager check different from a general health check?An eager check answers “can this process ever serve?” once, so it targets misconfiguration and missing wiring — defects that do not heal. It is a boot gate, not a continuous signal, and its result goes stale immediately, so it is poor evidence about a dependency's state later on.
saying these in an interview costs you the question
- Puts verification in a hook that runs after the socket is open
- Thinks an eager check must always exit the process on failure
- Believes a boot-time check proves the dependency is healthy later
- Adds an eager check for every dependency without weighing boot coupling
- Relies on lazy component creation to surface wiring mistakes