skip to content

In WireMock, what does withChunkedDribbleDelay() do to a reply that withFixedDelay() does not?

level: seniorimportance: should knowfreq 56%

answer

  1. silent socket versus a trickle
  2. which part of the reply is held back
  3. headers first, then the body in slices
  4. interval is duration divided by chunks
  5. no body means nothing to dribble

basics

~20 s

WireMock's withFixedDelay writes nothing until the pause elapses, then sends the whole reply at once. WireMock's withChunkedDribbleDelay sends the status line and headers immediately and spreads only the body across the stated duration, in the requested number of slices.

solid answer

~50 s

WireMock's `withFixedDelay(Integer)` sets an initial delay: the stub matches, and then WireMock writes nothing at all — no status line, no headers, no body — until the milliseconds have elapsed, at which point the whole reply goes out together. WireMock's `withChunkedDribbleDelay(int numberOfChunks, int totalDuration)` does the opposite: the status line and headers are written immediately, and only the body is spread out, split into `numberOfChunks` slices written one at a time with `totalDuration` divided between them. So the first is slow to *answer* and the second is slow to *transfer*. They are separate properties of one response definition and compose freely, and a client that restarts its clock on every byte received tolerates the dribble far longer than the silence. WireMock also quietly reduces the chunk count to the body's length in bytes whenever you ask for more slices than the body has bytes to give.

code

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

// Headers at once, then the body in 20 pieces over 4000 ms.
stubFor(get(urlPathEqualTo("/fitting/devices/HX-9002/telemetry"))
    .willReturn(aResponse()
        .withStatus(200)
        .withHeader("Content-Type", "application/json")
        .withBodyFile("telemetry.json")
        .withChunkedDribbleDelay(20, 4000)));

// Nothing on the socket for 4000 ms, then the whole reply.
stubFor(get(urlPathEqualTo("/fitting/devices/HX-9002/battery"))
    .willReturn(aResponse()
        .withStatus(200)
        .withBodyFile("battery.json")
        .withFixedDelay(4000)));

go deeper

for a junior

Know that WireMock has two different kinds of slowness: one that holds the whole reply back and one that drips the body out. Be able to name WireMock's withFixedDelay and withChunkedDribbleDelay.

for a middle

Be ready to say exactly what reaches the client first under each WireMock method, and to work out the interval between slices as the total duration divided by the number of chunks actually produced.

for a senior

Demonstrate that you have debugged this. A WireMock dribbled body keeps a client that restarts its clock on every byte alive far longer than a silent socket does, and a stub with an empty body cannot be dribbled at all.

for a principal

Be able to say which of the two a team should reach for by default, and why a stand-in that is slow to transfer exercises different client code than one that is merely slow to answer.

Both of these WireMock methods make a stub slow, and they make it slow in two entirely different places. Telling them apart is the whole question, because a client that copes with one may not cope with the other, and it is the wire behaviour — which bytes appear on the socket, and when — that decides which. A stub server is one of the few places where you can draw that distinction deliberately and repeatably, so it is worth knowing precisely what each method does rather than treating both as "make it slow". ## What WireMock's withFixedDelay does WireMock's `withFixedDelay(Integer milliseconds)` sets an *initial* delay on the response definition. When the stub matches, WireMock holds the whole reply back for that long and then writes it in one go. Nothing reaches the client in the meantime — no status line, no headers, no first byte of body. The socket is open and completely silent, and then the entire response appears. Mechanically WireMock spends that wait in one of two places. On the default path it sleeps on the very thread that is handling the request. If the server was started with `--async-response-enabled`, WireMock schedules the response on a scheduled executor instead and releases the container thread for the duration. ## What WireMock's withChunkedDribbleDelay does instead WireMock's `withChunkedDribbleDelay(int numberOfChunks, int totalDuration)` builds a `ChunkedDribbleDelay` and attaches it to the response definition. When the stub matches, WireMock writes the status line and headers **immediately**, reads the body, splits it into `numberOfChunks` byte slices, and then loops: sleep, write one slice, flush. The interval between slices is `totalDuration` divided by the number of slices actually produced, so the body arrives spread across roughly `totalDuration` milliseconds. The differences that matter to a client: - Under WireMock's `withFixedDelay(`, the connection stays silent for the whole delay, so any client watching for a first byte notices at once. - Under WireMock's `withChunkedDribbleDelay(`, the client receives a complete set of response headers straight away and then a trickle. A client whose clock restarts each time bytes arrive can sit there for the whole `totalDuration` without complaining; a client holding one deadline for the entire exchange will not. - WireMock sleeps *before* each slice, the first one included, so the first body byte arrives one interval after the headers rather than instantly. - WireMock's dribble does not change what the headers already declared about the reply, so the client has been told about a body that is still on its way. ## Two ways the arithmetic surprises people 1. If `numberOfChunks` is larger than the body's length in bytes, WireMock reduces the count to the body length and logs an error saying so. Asking for one hundred slices of a twenty-byte body yields twenty slices at a twentieth of `totalDuration` each, not one hundred at a hundredth. 2. If the response has no body at all, WireMock logs `Cannot chunk dribble delay when no body set` and writes the reply with no dribbling whatsoever. A header-only stub cannot be dribbled, because there is nothing to spread out. ## They compose, and that is often what you want WireMock keeps the initial delay and the chunked dribble as separate properties of the same response, so one stub may carry both. WireMock's `aResponse().withFixedDelay(2000).withChunkedDribbleDelay(10, 5000)` on a `GET /fitting/devices/{deviceSerial}/telemetry` stub gives two seconds of complete silence, then headers, then the body in ten pieces over five seconds — a stand-in that is slow to start *and* slow to finish. In MockServer the chunk-level control is a different thing entirely: `ConnectionOptions.withChunkDelay(` shapes how the connection is written and is separate from MockServer's response-level `withDelay(`. ## Which one a fitting suite should reach for 1. Use WireMock's `withFixedDelay(` when the question is whether the client survives a dependency that takes a long time to *begin* answering. That is the common case, and it maps onto a client that gives up before anything at all has arrived. 2. Use WireMock's `withChunkedDribbleDelay(` when the question is whether the client survives a dependency that answers promptly and then transfers slowly. That is a genuinely different failure, because the client has already been handed a set of headers and has committed to reading a body it has been told about. 3. Use both on the same response when you want the pessimistic shape — a `GET /fitting/patients/{patientId}/audiogram` stub that stalls and then trickles — remembering that the wall-clock cost is the sum of the two durations rather than the larger of them. ## Mistakes worth naming - Believing WireMock's `withChunkedDribbleDelay(` delays the headers. It does not; only the body is spread out. - Believing WireMock's `withFixedDelay(` sends headers early and then pauses. It does not; nothing at all is written until the delay has elapsed. - Expecting WireMock's `withChunkedDribbleDelay(` to honour a chunk count larger than the body's length in bytes. - Reaching for WireMock's `withChunkedDribbleDelay(` on a stub with an empty body and then wondering why the test finishes instantly. - Treating the two WireMock methods as alternatives. They answer different questions about a client, and one response definition can carry both.

  • What does WireMock do when withChunkedDribbleDelay asks for more chunks than the body has bytes?
    It reduces the chunk count to the body's length in bytes and logs an error saying so. The interval then becomes `totalDuration` divided by that smaller count, so the pieces are fewer and further apart than you asked for. The total transfer time is unchanged; only the granularity is.
  • Can one WireMock stub carry both a fixed delay and a chunked dribble delay?
    Yes. They are separate properties of the same response definition. WireMock applies the initial delay first — complete silence on the socket — and only then writes the headers and begins dribbling the body across the dribble's own duration. In wall-clock terms the two durations add up.

saying these in an interview costs you the question

  • Thinks WireMock's chunked dribble delays the headers too
  • Thinks WireMock's fixed delay sends headers before the pause
  • Believes the two WireMock delays cannot be combined
  • Expects more chunks than the body has bytes
  • Uses chunked dribble on a WireMock stub with no body