skip to content

In WireMock, when should injected delay live in setGlobalFixedDelay() rather than on each stub?

level: principalimportance: nice to knowfreq 44%

answer

  1. settings store versus the mapping file
  2. who can see it during review
  3. the stub's figure wins over the global
  4. replaces, never adds
  5. every waiting request holds a thread

basics

~20 s

WireMock's setGlobalFixedDelay writes the delay into the server's settings store. It applies to every stubbed reply and appears in no mapping file. WireMock's per-stub withFixedDelay serialises into the mapping and replaces the global figure rather than adding to it.

solid answer

~40 s

WireMock's `setGlobalFixedDelay(int)` writes a fixed delay into the running server's settings store — the same settings `PUT /__admin/settings` updates — so it applies to every stubbed reply and appears in no mapping file. WireMock's per-stub `aResponse().withFixedDelay(2500)` serialises into the mapping as `fixedDelayMilliseconds`, so it is visible in review, selective, and portable with the file. The precedence is the part people get wrong: a stub's own fixed delay **replaces** the global one rather than adding to it, so a global floor does not apply to any stub that declares its own. Default to per-stub, and reach for the global setting only when uniform slowness is the point of the run — then set it once at start-up, and run WireMock with `--async-response-enabled` so the waiting does not occupy a container thread per request.

code

java · 13 lines
java
import static com.github.tomakehurst.wiremock.client.WireMock.*;

// Server-wide: lives in the settings store, in no mapping file.
setGlobalFixedDelay(500);

// Per-stub: serialised as fixedDelayMilliseconds in the mapping,
// and it replaces the 500 above rather than adding to it.
stubFor(post(urlPathEqualTo("/fitting/devices/HX-9002/gain-profile"))
    .willReturn(aResponse()
        .withStatus(202)
        .withHeader("Content-Type", "application/json")
        .withBody("{\"fittingStatus\":\"PENDING\"}")
        .withFixedDelay(3000)));

go deeper

for a junior

Know that WireMock can hold a reply back either on one stub or across the whole server, and that setGlobalFixedDelay is the server-wide one. Do not expect it to target a single endpoint.

for a middle

Be ready to explain where each setting is stored: the stub's delay in the mapping JSON as fixedDelayMilliseconds, the global one in WireMock's settings store behind PUT /__admin/settings.

for a senior

Show that you know the precedence rule. A WireMock stub's own fixed delay replaces the global figure instead of adding to it, so a global floor silently exempts every stub that declares a delay of its own.

for a principal

Own the reviewability argument. A delay in a mapping file shows up in the diff; a global one is a property of a running process, and you should be able to say when that invisibility is worth accepting and how you compensate.

WireMock can hold a reply back in two quite different places, and choosing between them is really a choice about where the fact lives and who is able to see it. ## Two places a delay can live - A **per-stub** delay is part of the response definition: WireMock's `aResponse().withFixedDelay(2500)` inside `willReturn(`. It serialises into a WireMock mapping as `fixedDelayMilliseconds`, so it sits in the committed JSON beside the status and the body. WireMock's `withUniformRandomDelay(` and `withLogNormalRandomDelay(` serialise the same way, as a `delayDistribution` object. - A **global** delay is a server setting: WireMock's static `setGlobalFixedDelay(int milliseconds)` writes a fixed delay into the running server's settings store — the same settings the admin API exposes at `GET /__admin/settings` and `PUT /__admin/settings`. WireMock's `setGlobalRandomDelay(DelayDistribution)` does the same for a distribution. The consequence is immediate. The per-stub figure lives in a file a reviewer reads; the global figure is a property of a running process that no mapping file records anywhere. ## The precedence rule people get wrong When WireMock renders a stubbed reply it resolves the fixed delay and the distribution independently, and in each case **the stub's own value replaces the global one rather than adding to it**. A stub declaring WireMock's `withFixedDelay(3000)` on a server that has had `setGlobalFixedDelay(500)` applied waits three seconds, not three and a half. The same holds for the distribution: a stub carrying WireMock's `withUniformRandomDelay(` ignores whatever `setGlobalRandomDelay(` put into the settings store. What *is* additive is the pair. The resolved fixed delay and the sample drawn from the resolved distribution are summed into the reply's single initial delay, so a WireMock stub carrying both a fixed delay and a distribution waits for the total of the two. This matters more than it sounds. A team that sets a global floor expecting every stub to be at least that slow will find that every stub declaring its own delay is silently exempt from it. ## What a global delay costs - It applies to every stubbed reply the instance renders, so it cannot be aimed at one endpoint of the fitting API and not another. - By default WireMock spends the wait as a sleep on the thread handling the request, so a global figure multiplies that occupancy across every request the server sees. Running WireMock with `--async-response-enabled` moves the waiting onto a scheduled executor and is close to mandatory once a global delay is more than trivial. - It is invisible in review. A change that adds a `POST /fitting/sessions` mapping under WireMock's `mappings/` directory shows a reader nothing about the delay every response is already carrying. - It survives stub churn. Loading a fresh set of mappings does not clear a setting, because the setting does not live in a mapping. ## How I would decide 1. **Default to per-stub.** The delay is then part of the artefact under review, it is selective, and it travels with the mapping file to any other WireMock instance that loads it. 2. **Use the global setting only when uniformity is the point** — a run whose entire purpose is that the fitting service is slow across the board, where attaching the same figure to forty mappings would be noise rather than information. 3. **If you use it, set it once at start-up** rather than mutating it between tests. A setting changed mid-suite is shared mutable state, and the failure it eventually causes will not point back at it. 4. **Write down that it exists.** Because nothing under `mappings/` records it, the only place a reader can learn about a WireMock global delay is the code or configuration that sets it. In MockServer the comparable delay is declared on the individual expectation with `withDelay(`, so it travels with that expectation rather than sitting in server-wide settings. ## Mistakes worth naming - Assuming WireMock adds the global fixed delay to a stub's own figure, when it replaces it. - Setting a large WireMock global delay without `--async-response-enabled` and then blaming the resulting flakiness on the network. - Expecting a fresh set of mappings to clear a WireMock global delay, when the setting lives outside the mappings entirely. - Using WireMock's `setGlobalFixedDelay(` to make one endpoint slow, when the setting has no notion of which stub matched.

  • Does WireMock's global delay distribution behave the same way as the global fixed delay?
    Yes, with the same precedence. WireMock's `setGlobalRandomDelay(` writes a distribution into the settings store, and a stub declaring its own `withUniformRandomDelay(` or `withLogNormalRandomDelay(` replaces it rather than adding to it. What does add is the resolved fixed delay plus the resolved distribution sample: WireMock sums those two into one initial delay.
  • What is the operational risk of a large WireMock global fixed delay?
    By default the wait is a sleep on the thread handling the request, so a global figure holds a container thread for every request in flight. Concurrency collapses long before the delay itself looks large. Starting WireMock with `--async-response-enabled` moves the wait onto a scheduled executor and removes most of that cost.

A per-stub delay is a valve on one pipe; WireMock's global fixed delay is a restrictor fitted to the main. Anyone reading the drawing for a single room sees the valve and has no way of knowing the restrictor is there.

saying these in an interview costs you the question

  • Says WireMock adds the global fixed delay to the stub's own
  • Thinks setGlobalFixedDelay can target one WireMock endpoint
  • Expects a global WireMock delay to show up under mappings/
  • Sets a large global WireMock delay without async responses
  • Assumes fresh mappings clear a WireMock global delay