← Back to all field notes
Patterns & practice

When Things Slow to a Crawl

Miscellaneous antipatterns I’ve observed in the wild

Every troubled project I’ve seen had a moment where momentum stopped. Rarely a dramatic failure. A slow, grinding deceleration until shipping anything became hard. The causes are few. The same antipatterns recur across companies, teams, and decades, dressed slightly differently each time. I’ve been guilty of a few of these myself.

What follows is a field guide to the ones I keep meeting. They are grouped by where they originate: architecture, product, planning, people and culture. Each has notes on what I’ve seen work to avoid or recover. None of it is novel. That is the point. These are well-trodden mistakes, and they keep happening because the lessons are hard to internalise before you’ve been burned.


Part one: architecture and technology

Microservice sprawl with no coordinating strategy

The pattern: a new product with no users yet starts life as tens of microservices. Each is owned by someone. Each has its own repository, deployment, sometimes its own datastore and language. No shared plan for how they talk to each other, no contract discipline, no versioning. Within months the team spends more time chasing broken integrations than building features. A change in one service silently breaks three. Nobody can run the whole system on a laptop. Onboarding takes a fortnight.

This usually travels with gratuitous technology diversity: a different language or database or queue for each service, each individually “the best tool for the job.” The Boring Technology Club names the trap. Every new technology you adopt spends a scarce, finite resource, your team’s ability to operate things competently under pressure. Ten technologies, ten failure modes nobody has seen, ten on-call runbooks nobody has written.

Microservices are an organisational technology. They let many teams deploy independently without coordinating. With one team you pay the full operational and cognitive cost of that independence and collect none of the benefit. You have distributed your monolith without earning the right.

What helps: Start with a modular monolith. One deployable unit, firm internal module boundaries enforced by language features (OCaml signatures, TypeScript module exports) or disciplined package structure. You get clean separation without a network call in the middle of every function. Extract a service only under a named pressure: a component with different scaling characteristics, or a second team that needs to deploy on its own cadence. Treat each new technology as a purchase with a price. The default answer to “can we use X” is “no, we already have something that does that.” Stack diversity should be a rare, justified exception.

Event sourcing and distribution for everything, from day one

The pattern: before the product exists, the team decides every state change will be an immutable event in a log, the system will be eventually consistent, and services will communicate through asynchronous event streams. Elegant on the whiteboard. In practice the team debugs across event replays, chases consistency bugs that only appear under load, and cannot answer “what is the current state of order 12345” without consulting three projections. Velocity collapses.

This is often the work of theoreticians who have read deeply and hold strong architectural opinions but have not spent enough time on the front line watching systems debugged, extended, and operated at 3am. Even Martin Fowler, who documented event sourcing carefully and clearly admires it, is plain that it is a demanding pattern with serious costs, not a default. Event sourcing solves specific problems: audit requirements, temporal queries, rebuilding state in new shapes. Without those problems, it is a tax with no return.

What helps: Use a boring, transactional, mutable-state database until something forces you off it. It is well understood, easy to reason about, and “what is the current state” is one query. If you need an audit trail, add an event log for the specific aggregate that needs one, without converting the whole system to a religion. Reach for distribution and asynchrony the same way. Per problem, when the problem is in front of you, not as a foundational assumption. Architecture is earned by requirements, not chosen by aesthetics.

Serverless everything

The pattern: the whole backend is functions-as-a-service, sold on no servers to manage and a bill that scales to zero. Then reality arrives. Cold starts add latency on user-facing paths. Local development and debugging become awkward. Per-invocation pricing, fine for short bursty work, turns punishing for anything long-running. The architecture fragments into dozens of tiny functions wired together by cloud configuration nobody can hold in their head.

I made this mistake myself, early, when serverless was new and the enthusiasm was infectious. The place it hurts most now is applied AI. An LLM call is dominated by waiting: many seconds, often more, especially with streaming responses where you hold a connection open for the duration. In a serverless model you are billed for that wall-clock waiting time, a premium rate for a function doing nothing but holding a socket. Close to a worst-case fit. FaaS economics and latency were designed for short, stateless, bursty work. A streaming AI workload is none of those.

What helps: Default to long-lived processes (servers, containers) for steady traffic, long-running requests, or streaming. They are cheaper under sustained load, simpler to debug locally, and do not penalise waiting. Serverless still earns its place for spiky, infrequent, short-lived work: a webhook handler, a nightly job, glue that runs rarely. Pick it as a considered fit for a specific workload, not as a blanket default.

Applied AI with no evaluation framework

The pattern: a team ships an AI-powered feature and improves it by feel. Someone changes a prompt, tries a few examples, decides it looks better, ships. No systematic measurement. When a stakeholder asks “is the new model actually better,” the answer is a shrug dressed up as confidence. Worse, regressions are invisible. A prompt change that fixes one category of input quietly breaks two others, and nobody knows until a customer complains.

Without an evaluation framework you are not engineering, you are decorating. Every decision rests on anecdote, on whoever argued most forcefully about whichever examples they happened to try. You cannot tell improvement from drift. You cannot safely change anything, because you cannot see what you broke.

What helps: Build the eval harness early, before the feature is interesting. Assemble a dataset of real inputs with known-good characteristics. Define metrics that reflect product quality, not convenient proxies. Make the eval runnable on demand and in CI. Treat a prompt or model change like a code change: it must pass the suite. Include adversarial and edge cases, and grow the set every time a failure escapes to production. The harness converts AI development from anecdote to a feedback loop, the only thing that compounds.


Part two: product and strategy

Saying yes to everything

The pattern: a SaaS product lands a handful of large customers, and each of them, being large and paying, dictates the roadmap. Every customer’s special request becomes a feature. No triage, no sense of which requests express the product’s purpose and which express one account’s idiosyncrasy. Over a couple of years the product becomes a bunyip, assembled from everyone’s wishes, coherent to nobody. Each new customer is harder to satisfy because the product no longer has a clear shape to sell. Development grinds to a halt under conditional logic and special cases.

The cause is absent product identity. Without a clear answer to “what is this product for, and who is it for,” every request looks equally valid and the loudest voice wins. Saying yes feels like good service. Repeated, it is how a product loses the thread.

What helps: Decide what the product is, and let the decision do real work. A request that serves the core purpose and many customers is a feature. A request that serves one account’s peculiarity is either custom consulting, priced and quarantined as such, or a polite no. Triage every request against the product’s identity, out loud, consistently. Some of the most important strategic moves a product makes are visible refusals. A product shaped for everyone is shaped for no one, and cannot be sold as anything in particular.

Misreading product-market fit

The pattern: early signals look wonderful. Friendly contacts try the product and say encouraging things. A few pilots convert. The founders read this as product-market fit, scale the team, hire ahead of need, and commit to a burn rate that assumes the curve continues. It doesn’t. The warm-network enthusiasm was affection, not demand. The pilots were exploratory budgets, not committed revenue.

Two errors hide in here. First: treating warm-network signals as representative. People who know you will try your thing and say kind words. That is friendship, not evidence. Second: treating pilot run-rate as ARR. A pilot is an option to buy, exercised with someone else’s discretionary money. Annualising it is a story you tell yourself. The standard reflex, hiring people to fix the unease, is one Y Combinator warns founders against repeatedly. Scaling the team early multiplies burn, dilutes culture, and creates the appearance of progress while the underlying question, does anyone actually need this, stays unanswered.

What helps: Discount warm-network feedback heavily. Weight evidence by what it cost the other party to give. Money committed, contracts signed, and unprompted reuse count. Polite enthusiasm does not. Keep pilot revenue and recurring revenue in separate columns and never let them mingle in a board deck. Stay deliberately small and understaffed until the demand signal is loud and comes from strangers. Hiring does not discover product-market fit. It is a bet that follows it.

Not running the Mom Test

The pattern: a team validates an idea by describing it to potential customers and asking whether they’d use it, whether they like it, whether they’d pay. The answers are warm. The team feels validated and builds. The warmth was meaningless. The questions were leading, and the people answering had every social incentive to be kind.

Rob Fitzpatrick’s The Mom Test exists to prevent this failure. The insight: do not ask people for opinions about your idea. Even your mother will lie to spare your feelings. Ask instead about their life. What they did. When they last hit this problem. What it cost them. What they have already tried and paid for. Facts about the past are reliable. Opinions and predictions about your idea are not.

What helps: Never pitch during a validation conversation. Ask about specifics that already happened. “When did you last run into this?” “Walk me through how you handled it.” “What did that cost you, in money or time?” “What have you already tried, and what did you pay for it?” If someone has never sought a solution, never spent anything, cannot recall a concrete instance, you have found a problem nobody is motivated to solve, regardless of how enthusiastically they endorse your slide. Compliments are not data. Behaviour is.

Building something on the commoditisation path

The pattern: a team builds a product that sits in the path of a large platform’s natural expansion, or that is thin enough to be cloned quickly once it works. For a while it sells. Then the obvious happens. The incumbent ships the feature, or three competitors copy it, and the product has no defensible reason to exist. The differentiation was a head start. Head starts expire.

The risk is sharper now. Capable AI models make a large class of once-defensible software cheap to replicate, and platform owners are expanding their surface area aggressively. A product whose entire value is a thin wrapper over a capability everyone can access is not a business. It is a demo with a payment form.

What helps: Before committing, ask where the product sits relative to the giants’ roadmaps and how hard it is to copy. Then build a moat that compounds rather than expires. Deep vertical expertise is one. Encoding the hard-won domain knowledge of a specific industry into the product in a way a generalist platform will not bother to match. A data flywheel is another. Use generates proprietary data that makes the product better, which attracts more use, a loop a latecomer cannot copy because they lack the accumulated data. Workflow integration, switching costs, regulatory and trust barriers, and genuine network effects are others. The test is whether your advantage grows with time or erodes with it. If it erodes, you are renting your differentiation, and the lease is short.


Part three: planning and process

Waterfall and the year-long roadmap

The pattern: the organisation commits to a detailed roadmap stretching twelve months or more, often maintained by a non-technical management layer. The roadmap is treated as a promise rather than a guess. Engineers are measured against it. When reality diverges, as it always does, the response is to pressure the team to hit it anyway. The result is burnout, expensive turnover, and the slow loss of institutional knowledge that walks out with each departure.

A long-range software roadmap is fantasy presented as commitment. It assumes you will learn nothing over the year that changes your mind, which is the same as assuming the work is not worth doing. If you learn nothing, you were not exploring anything. It is hubris: a claim to know in January what you cannot know until you have shipped something in March and watched what happened.

The same disease shows up in miniature as process ceremony. RFCs that stay open for months accreting comments. Issue trackers, now often populated in bulk by an AI assistant wired into the project management tool, holding hundreds of tickets that describe an approach the team will abandon the moment it learns the approach was wrong. The volume of planning artefacts becomes a measure of activity, and the artefacts are stale on arrival.

What helps: Plan in horizons. Be concrete and committed about the next few weeks, directional about the next quarter, and frankly vague about anything beyond that, because vague is the accurate description of what you know. Treat the plan as a hypothesis the team is actively trying to disprove, and make updating it a sign of health rather than failure. Optimise for three things: learning speed, non-regrettability (the preference for decisions that are cheap to reverse), and cheap pivots. Keep planning artefacts thin and disposable. An RFC should be decided or discarded in days. A backlog of five hundred issues is not foresight. It is debt with a due date you have already missed.


Part four: people and culture

Tolerating the curmudgeon

The pattern: a team carries a senior engineer who is gruff, dismissive, and reflexively negative, and the culture tolerates it because he is “brilliant” or because he has been there longest. Often the brilliance is not even there. The archetype is the expert beginner. Someone who reached a local plateau years ago, mistook it for the summit, and stopped climbing. A greenhouse flower: capable inside the one environment he has always known, unaware of the size of what he does not know. His confidence is not earned by range. It is preserved by never leaving the greenhouse.

The damage is disproportionate and compounding. He shoots down ideas reflexively, so people stop offering them. Juniors learn not to ask questions, which means they learn slowly and badly. Good engineers, the ones with options, leave first. What remains is a team selected for tolerance of the curmudgeon, which is not the trait you wanted to select for.

What helps: Name the behaviour early, specifically, and as a performance problem, because that is what it is. Technical skill does not buy an exemption from being a decent colleague. Make “how does this person affect everyone around them” an explicit, weighted part of how senior engineers are evaluated. Counter the greenhouse effect by exposing strong opinions to outside air: external review, rotation, conferences, contact with how other organisations work. Be willing to part with the person if the behaviour does not change. A team almost always speeds up after a tolerated curmudgeon leaves, which tells you what the tolerance was costing all along.

The side-quester

The pattern: a developer who is energetic and visibly busy but rarely on task. Assigned tickets sit open or quietly get handed back while they pursue something more interesting. A tooling migration nobody asked for. A refactor of a part that was working. A shiny new framework introduced over a weekend. The work is real, and visible, which is part of the appeal. The boring, critical foundations get skipped. Coordination with the team gets skipped. They are wounded if the surprise initiative is not applauded, because in their mind they were showing drive.

The cost is subtler than slacking, which is why it is tolerated longer. The side-quester produces output, sometimes impressive output, so it takes a while to notice that committed work is not getting done, that other people are blocked, and that the codebase is accumulating half-finished enthusiasms. They optimise for the interesting and the visible over the necessary and the dull. A team cannot run on that.

What helps, including screening for it: Hard to catch in interviews because the side-quester interviews well. Shiny work shows initiative, breadth, and energy, exactly what a standard interview rewards. A few things help. In the behavioural interview, ask not for an impressive project but a boring one: “Tell me about a tedious piece of work you owned end to end. How did you stay with it?” The side-quester struggles to produce a good answer and often visibly deflates, because the question gives no room for the shiny. Probe handoffs and follow-through: “Tell me about something you started that someone else finished,” and listen for whether they tracked it to completion or lost interest at the fun part. In any take-home or pairing exercise, set a deliberately mundane task and watch whether they do the asked thing or gold-plate, add an unrequested tool, or wander. In references, ask the specific question: “Did they reliably finish the unglamorous parts of what they took on?” Design every signal to reward finishing the boring thing, because that is precisely what the default interview fails to test and the side-quester lacks. Once hired, make completion of committed work the visible, praised metric, and treat unsanctioned side projects as the thing that needs justification, not the thing that earns applause.

Treating R&D as a cost centre

The pattern: leadership frames research and development as overhead, a cost to be controlled, minimised, and justified. Budgets are defended rather than invested. The implicit goal is to spend as little as possible on engineering while keeping the lights on. The framing leaks into every decision. Hiring is reluctant, tooling is starved, exploratory work is the first thing cut when numbers tighten.

This inverts the relationship. In a software company, R&D is not the cost of doing business. It is the business. The function that creates the product, the differentiation, and the future value. Calling it a cost centre is a category error that becomes self-fulfilling. Starve it and it produces less, which seems to confirm that it was a drain, which justifies starving it further. Companies talk themselves into decline this way, one defensible-looking cut at a time.

What helps: Frame and fund R&D as the value-creating engine it is. The question is not “how little can we spend” but “what is the return on what we spend, and how do we raise it.” That reframe changes everything downstream. You invest in tooling because it compounds. You protect exploratory capacity because that is where next year’s product comes from. You hire as an investment with a return rather than a cost to be resisted. Leaders who see engineering as a cost manage it toward the minimum. Leaders who see it as the engine manage it toward leverage. Only one is trying to win.


Common themes

Lay these eleven antipatterns side by side and a few deeper patterns show through. Worth naming, because recognising the theme lets you spot a new variant before it has a name.

Paying for sophistication you have not earned. Microservices, event sourcing, serverless, distribution: each is a legitimate solution to a problem some companies have. The antipattern is not the technology. It is adopting the solution before you have the problem, paying the full operational and cognitive cost up front for benefits that only materialise at a scale you have not reached. Sophisticated tools have prerequisites. Using them without the prerequisites buys all the cost and none of the return.

Mistaking activity for progress. The bulging backlog, the months-old RFC, the side-quester’s flurry of visible work, the headcount added before product-market fit, the year-long roadmap: each generates motion, artefacts, and the comfortable feeling of effort. None necessarily moves the thing that matters. Much dysfunction is the substitution of legible activity for actual progress, because activity is easier to see, easier to measure, and easier to feel good about.

Refusing to let learning change the plan. The waterfall roadmap assumes you will learn nothing. Event-sourcing-from-day-one assumes the design needs no revision. Saying yes to everything is a refusal to learn what the product is. Misreading product-market fit is a refusal to hear what the market is saying. The healthy posture treats every plan, architecture, and product belief as a hypothesis to be tested and cheerfully revised. The antipatterns all, in their different ways, treat the early guess as a commitment and defend it against the evidence.

Avoiding the boring and the necessary. Gratuitous technology diversity, the side-quester’s shiny migrations, R&D managed as cost rather than craft: the recurring move is flight from unglamorous fundamentals toward something newer and more visible. Contract discipline, a boring database, finishing the assigned ticket, an evaluation harness, paying down the foundations: this is the work that compounds, and consistently the work that gets skipped because it does not look like much.

Optimism unchecked by instrumentation. No evaluation framework, so the AI feature is “better” because it feels better. Warm-network signals read as demand. Pilot revenue read as ARR. The Mom Test ignored, so compliments are read as validation. The failure is believing the flattering interpretation because nothing was built to produce a truthful one. The cure is always the same in shape. Build the instrument first: the eval suite, the separate revenue columns, the behavioural question. Reality needs a way to reach you before the expensive decision is made.

Tolerating the wrong things. The curmudgeon is kept for his seniority. The side-quester is praised for visible energy. The unearned architecture is admired for its elegance. The roadmap is respected for its detail. Each is a culture rewarding the wrong signal: comfort, polish, visible effort, apparent rigour, rather than what is actually wanted, a team that learns fast and ships steadily. Cultures get the behaviour they tolerate and reward. If the wrong things are tolerated, the wrong things compound.

If there is one sentence under all of it: things grind to a halt when a team optimises for how things look (sophisticated, busy, planned, harmonious, impressive) instead of for the humble, measurable, and often boring reality of learning quickly and shipping steadily. Every antipattern here is a version of that trade, made for understandable reasons, regretted later. The way out is not cleverness. It is the discipline to prefer the earned over the impressive, and the discipline to build the instruments that tell you which is which.

// Context & author

You are reading Field Notes by Auxil

Auxil is an independent software systems consultancy and active product factory operated by veteran software practitioner Tim Farland alongside a vetted peer network of senior specialists. Based on Waiheke Island, Auckland, we design, build, and audit high-stakes SaaS systems and production-grade AI pipelines globally.

Explore →

Tim Farland

Operator / Architect / Engineer
// Contact

Let's discuss your project

If you are looking for a reliable, competent, efficient Principal Architect or Engineer for scoped, delivery-focused contracting or advisory, reach out.

Waiheke Island, Auckland · Available for remote or CBD hybrid engagements