How to run a spike
Timeboxed investigation is the cheapest way to buy certainty, and most teams do it in a way that produces neither certainty nor code.
A spike is a timeboxed investigation whose output is a decision, not a feature. Done well it is the highest-leverage day in a project. Done the way most teams do it, it produces a half-finished prototype and an opinion nobody trusts.
The difference is entirely in the setup.
write the question down first#
A spike without a written question becomes exploration, and exploration has no end condition.
The question has to be answerable and specific:
- Bad: "look into whether we can use X"
- Good: "can X ingest 50k events/second on a single node with our event shape, and what does its failure behaviour look like when the disk fills?"
The second one tells you when you are finished, what to measure, and what would count as a no. The first one runs until someone gets bored.
state the decision it feeds#
A spike exists to unblock a decision. Name the decision explicitly: we will use X for the ingest path, or we will stay with Y and shard it.
If you cannot name the decision, you are not running a spike, you are learning something — which is fine and should be called that, because it has a different budget.
set the box, and mean it#
Two days is the usual right answer. Long enough to get past setup, short enough that being wrong is cheap.
The rule that makes it work: when the box ends, you stop and report, even if you are nearly there. "Nearly there" is where spikes go to become three-week projects. If the answer genuinely needs more time, that is itself a finding — report it and ask for a second box with a narrower question.
the output is a document, not a branch#
This is the part teams skip. The deliverable is one page:
## Question
Can X ingest 50k events/s on one node with our event shape?
## Answer
Yes for the steady state, no for our burst profile.
32k/s sustained, 61k/s for ~40s before the write buffer backs up.
## Evidence
Harness: spike/x-ingest/ (throwaway). Ran on c7g.4xlarge, 20 min,
production event sample from 2026-08-10. Numbers: spike/x-ingest/results.md
## What surprised me
Backpressure is silent — it drops rather than erroring, and the drop
counter is only in a debug endpoint. That is a production risk with X
regardless of throughput.
## Recommendation
Stay with Y and shard. Revisit X if their 3.x backpressure work lands.
## What I did not test
Multi-node, recovery after disk-full, or the managed offering.Six sections, twenty minutes to write, and it is still useful in a year when somebody asks why the decision went the way it did. The "what I did not test" section is the one that keeps the document honest.
throw the code away#
Spike code is written to answer a question, not to be maintained. It has no tests, no error handling, hard-coded credentials and a main function that does everything.
That is correct — the speed comes from those omissions. The failure is letting it become the foundation of the real implementation, at which point you have shipped a prototype and will spend a year discovering what it does not handle.
Put it in a directory named spike/, or a branch you never merge. Say in the document where it is. Then write the real thing properly, informed by what you learned.
The strongest signal that a team's spikes are working: the spike code never ships.
when a spike is the wrong tool#
- When the answer is already written down. Read the documentation, the changelog, the issue tracker. A surprising amount of "we need to try it" is answerable in an hour of reading.
- When the question is about production behaviour under real load. A spike cannot tell you that. A canary can.
- When the decision is reversible and cheap. Then just pick one. A spike to choose between two libraries you could swap in a day costs more than being wrong.
Spikes are for expensive, hard-to-reverse decisions where the deciding information does not exist yet. That is a narrower set than it feels like, and it is exactly where two days is a bargain.
— Dom, August 18, 2026