Post

Why five small tickets can be harder than one feature

Tiny tasks look fast on paper and expensive in the working set. Context cost, review overhead, and when to batch or refuse the scatter.

On this page

The email arrived on a Thursday evening with the subject line "a few quick ones". It was from a small business I looked after on a monthly maintenance retainer, and it had five bullet points:

  • Change the phone number on the site, we've got a new line.
  • Add a "How did you hear about us?" dropdown to the booking form.
  • The PDF receipts are sometimes a cent out on the VAT, can you check?
  • Update the cookie banner wording, our accountant sent new text.
  • The hosting company says our PHP version is ending support, can you upgrade it?

The client's estimate, which they mentioned kindly, was "probably an hour or so for all of them". I thought that was optimistic, and I blocked out Friday. By six o'clock on Friday I had two of the five live, one waiting on a decision from them, one on staging, and one rolled back with nothing to show for it. A full day, around six hours of actual work once you count the deploys and checks, and from the client's side the website had a new phone number and new cookie text.

Nothing about that day was unusual. That's what makes it worth taking apart.

Nothing about that day was unusual.

How the Friday actually went

The phone number was in three places, not one. The config file, a footer partial that someone had hard-coded at some point, and the footer of the PDF receipt, which was generated by a different template. Twenty-five minutes, most of it searching, plus checking the PDF still rendered.

The dropdown needed a database column, validation, the option list somewhere editable, the value showing up in the booking export the client downloads every week, and a test. Each piece was small. Together they took an hour and forty minutes, including the time to remember how that export worked, because I hadn't touched it in eight months.

The VAT cent was the interesting one. The receipts calculated VAT per line and rounded each line, and the totals at the bottom were calculated on the sum. Both methods are defensible, they give different answers by a cent on some orders, and which one is "right" for their receipts was not my call. I spent an hour and a quarter confirming the cause, writing it up clearly with two example orders, and emailing the client to ask which way they wanted it. Blocked until Monday at the earliest.

The cookie banner was genuinely quick: twenty minutes including checking it on a phone.

Then the PHP upgrade, which I started at ten past four because it was the last thing on the list and I wanted the list done. Updating dependencies for the new PHP version pulled in a new major version of the library that generated the PDF receipts, and a handful of method calls had changed. By half past five I had the receipts half working on my machine, nothing I'd trust in production, and a Friday evening ahead. I reverted the branch and wrote a note.

Why it cost six hours, not one

The client wasn't wrong that each change was small. The phone number was literally one string. Their mistake, and mine for a long time before I learned to spot it, was adding up the size of the changes when what costs time is the number of different places you have to load into your head.

Illustration · 16:9five tiny tickets in five different corners of one codebase, to show why setup is paid five times, scattered files, 16:9, AI illustration

Each of those five tickets lived in a different corner of the system: config and templates, the booking form and its database, the receipt calculation, the frontend banner, and the server and dependencies. None of them shared a working set. So I paid the setup five times: open the right files, find the right test, remember how that bit was built, work out how to check it, then deploy and verify. And each one ended with its own small overhead of committing, deploying, checking on the live site and telling the client.

For planning conversations I use a rough rule of thumb. It is not science, just the numbers that have held up in my own work: each new context costs somewhere around twenty to forty minutes before any productive change happens, and each separate change that goes through review and deploy carries around thirty to forty-five minutes of fixed overhead, however tiny the diff. On a team, part of that overhead lands on whoever reviews it.

With 30 minutes for setup and 35 minutes for overhead, here's what that looks like for one developer:

ShapeContextsSetupChange timeReview and deploy overheadRough total
One feature in one area130 min4 hours35 minAbout 5 hours
Five tickets in five areas55 × 30 = 150 min5 × 45 = 225 min5 × 35 = 175 minOver 9 hours

The five tickets were sold as five hours. The rough total is more than a full day, before any meetings or interruptions, and it doesn't count the risk that one of them, like my PHP upgrade, turns out to be a different size altogether. Background on why switching costs this much is in the real cost of context switching.

The same thing happens on teams, just less visibly

I've seen the same pattern on remote teams, where it hides better. A sprint gets five one-point stories that look like a light load: fix a typo in an admin email, adjust validation on the signup form, bump a dependency in an old scheduled job, add a column to a report query, patch logging in the payment webhook. Templates, forms, infrastructure, reporting SQL and payments. Five working sets.

By the afternoon there are five branches, or one messy branch touching five surfaces, and five small pull requests sitting in a reviewer's queue, each of which asks the reviewer to load a different context too. Standup the next day says "worked on five tickets". The merge log says nothing finished. It felt like a full day for everyone involved, and it was, but it was full of setup. Busy versus finishing work is about that exact gap.

The question I've started asking during estimation is "how many contexts is this?" It predicts calendar time much better than line counts or points do. Five one-point stories in five areas can easily cost more than one five-point story in one area, and once a team sees that once, they tend to remember it.

When small tickets really are cheap

None of this means small tickets are always expensive. They're cheap when they share a context. Looking back at the Friday, the phone number and the cookie banner were both template changes on the same site. If I'd done them together, back to back, one deploy, one check on the live site, they'd have cost maybe thirty minutes between them instead of forty-five plus two rounds of deploying and checking.

Small tickets batch well when they have things in common:

  • The same service, the same test file, the same reviewer.
  • A follow-up in an area where a pull request is already open.
  • Copy or config changes with no logic in them.
  • Several bug reports that turn out to be one root cause.

That last one is common with support-driven tickets. Five customers report slightly different symptoms of the same bug, and five tickets get filed. If five people each take one, you load the same logs five times. One investigation ticket with the others linked to it gets fixed once. When batching helps and when it hurts goes into the limits of this, because batching unrelated work is just scatter with a nicer name.

And if five tickets all serve one outcome, such as "make checkout feel trustworthy", they should usually be one ticket with a checklist inside it. Splitting work into five cards for reporting purposes creates five artificial switches for whoever does it.

Refuse the shape and keep the request

Small things still need doing. What helps is being honest about their shape before someone plans a day around the wrong number.

On a team, the script I've used is roughly this:

I can do these five as one checkout hardening change by Thursday, or as five separate merges by next Wednesday, with review load on Ana and Luis. Which works better?

Both options say yes. The script puts the real cost on the table and lets whoever owns the priority pick. If they choose five separate merges, I call that day a scatter day out loud: low depth, lots of switching, small merges expected, and no big feature planned alongside it. Mixing an unnamed scatter day into a feature day is a reliable way to finish neither, which is the whole argument of planning eight hours into eight hours fails.

When a list lands and I have to decide quickly, I run through it like this:

  1. Do the items share one service, one test file or one reviewer? Batch them into one branch and one review, with a checklist in the ticket.
  2. Do they serve one user outcome? Rewrite them as one ticket. Subtasks are fine; five merges aren't required.
  3. Are they different symptoms of one root cause? One investigation, the rest linked. Fix it once.
  4. Are they five unrelated areas that all "need doing today"? Offer the two options above with dates and review load named.
  5. Is today already a feature day? Park them for a named scatter day. Starting five contexts in the middle of a feature is how both lots of work stall.

A reply that stays friendly: "I can do the signup validation and the admin email typo today, since they're both in the web app. The cron dependency and the payment logging need their own half-day or they'll blow up the checkout work. Shall I do the web two now and the infrastructure two on Thursday?"

Quoting tweak lists for clients

For freelance work, the Friday changed how I handle "a few quick ones". I now treat a tweak list as one piece of work, not a sum of line items. I group what shares a context, quote it as a batch with one staging check and one round of revisions, and split out anything that's clearly a different size.

On that client's next list, I replied the same day: the copy and template changes as one batch this week, the form change as a separate small job with the export included, and the PHP upgrade as its own task with a proper estimate, because I now knew it touched the receipt library. On a retainer of a few hours a month, that also meant telling them plainly that the upgrade alone would use most of a month's hours. They were fine with it. In my experience clients mind surprises far more than they mind honest estimates.

If a client prefers to drip-feed small requests through the week, I either price the setup cost in or suggest a fixed weekly tweak window, where everything that arrived goes in together. Fewer deploys is cheaper for them too, and it means fewer chances to break something. Juggling several clients' scatter in the same week is its own skill, and running a multi-client week without context thrash is how I manage it.

When the scatter has already happened

Sometimes you only notice at three in the afternoon, with four branches open and nothing merged. What I do then is stop starting. I rank what's left by what's closest to done and what's riskiest, merge or abandon branches until one or two remain, and tell whoever is waiting early, with the real reason. "This took longer because it touched five different parts of the system" is more useful to a client or a lead than "took longer than expected", and it makes the next estimate easier to have.

Counting tickets closed will always reward this kind of scatter, because five small closes look better on a chart than one large one. I'd rather count the things a user can now do. The Friday that ended with a new phone number and new cookie text was a long, honest day of work. It just wasn't an hour of it, and the sooner everyone involved can see that before the day starts, the fewer Fridays look like that one.

End of this piece

Writer

PrimedEcho

Independent notes on remote work, focus, and freelance practice. About this site.

All posts