Field work

Offline-first phlebotomy, and the conflicts nobody plans for.

A home visit and a hospital basement are the two places a phlebotomist reliably loses signal, and they are also the two places where guessing which write wins is unacceptable. What queues, what cannot queue, and why a conflict has to reach a person.

Published26 May 2026
Reading~10 min
AuthorThe LabFlow team
Field workOfflineChain of custody

The article

A home visit and a hospital basement are the two places a phlebotomist reliably loses signal, and they are also the two places where guessing which write wins is unacceptable. What queues, what cannot queue, and why a conflict has to reach a person.

A phlebotomist loses signal in two places with great reliability: inside somebody’s house, and in the basement corridor where the phlebotomy room is. Both are places where the work continues regardless, and both are places where a laboratory system that stops working is a laboratory system that gets worked around on paper.

This post is about specimen collection only. Result entry, validation and release are online operations in LabFlow and this article does not argue otherwise — the reasons for that are at the end rather than assumed at the start.

Why the round is the offline case#

A collection round is a sequence of visits planned in advance, executed away from the building, and reconciled afterwards. Every property of that sentence pushes toward offline-first.

The work is planned, so the data needed can be fetched before leaving. The work is away, so connectivity is a variable rather than a given. The work is reconciled afterwards, so a short delay between an action and the server hearing about it is normal rather than exceptional. And crucially, the phlebotomist is the only person doing anything to these specimens while they are out — which is what makes most of the conflict problem disappear, and makes the remainder sharp.

Offline-first is not a resilience feature here. It is the normal operating mode for a shift. A design that treats it as a degraded state will get the priorities backwards — including, usually, by making the offline path the one nobody tests.

Identity is the thing you cannot defer#

Everything in a collection depends on the phlebotomist having correctly identified the patient in front of them, and that check cannot be deferred to a moment when the network returns, because by then the patient has gone.

So the round is downloaded with what identification requires: the patient’s name, date of birth and identifier, the tests requested, the tubes needed, and any special preparation. That download happens on a good connection before the round starts, and it is the one moment in the design that genuinely needs the network.

The corollary is unpleasant and worth stating: a round that was not downloaded cannot be worked offline. Not "works with reduced information" — cannot be worked. Presenting a phlebotomist with a patient record that might be stale in the fields that identify a person is worse than presenting nothing.

Labels are printed at the patient, and that is a hardware problem#

The accession identifier and the tube labels belong at the point of collection. A tube labelled later is a tube that might be labelled wrong, and mislabelling is the pre-analytical error with the worst consequences and the least visibility downstream.

That means the device must be able to allocate an identifier without asking the server. The usual answer is to pre-allocate a block of accession numbers into the round at download time, which is unglamorous and completely reliable: the identifiers are real, the server already knows they belong to this round, and there is no collision to resolve later.

The alternative — a client-generated identifier reconciled to a server one afterwards — means the barcode on the tube and the identifier in the laboratory are two different things for a while, and every system that touches the specimen in that window has to know about both.

What queues#

An action queues when it is a statement about something the phlebotomist personally observed, and nobody else is in a position to contradict it.

  • The visit was attempted, at this time, at this address.
  • The patient was not there.
  • The specimen was collected, at this time, into these tubes, by this person.
  • The volume was insufficient, and a second attempt was or was not made.
  • The labels were printed and applied.
  • The specimen was placed in this storage condition, in this container, at this time.
  • The visit was rescheduled, with a reason.
  • A note was added.

These are all events, not edits. They append to a custody record rather than changing a field, and appending is what makes them safe to replay in order when the connection returns. Two of them arriving out of order is a sorting problem, not a conflict.

What cannot queue, and why#

The list of things that must not be available offline is shorter and much more important.

  • Anything that reads or writes another patient’s data. An offline cache is a copy of clinical data on a device that gets left in cars, and it holds today’s round and nothing else.
  • Cancelling an order. The cancellation may have already happened centrally, or the order may already have been collected elsewhere, and a queued cancellation that replays an hour later can withdraw work that has been done.
  • Anything that releases a result to anybody. Release is the line after which somebody may act on a value, and it is not a decision to take without knowing the current state of the record.
  • Changing who a specimen belongs to. If identity is wrong, the correct action is to record that it is wrong, not to fix it from the field.
  • Anything that spends money or sends a message to a patient or clinician.

The unifying rule: an action may queue if replaying it late is still true. "I collected this at 09:14" is still true at 11:00. "Cancel this order" is a command about the present, and the present has moved.

A queued command is a command from the past. Events survive the delay because they describe something that happened. Commands do not, because they describe something that should happen now — and by the time they arrive, now is different.

What synchronisation actually has to do#

With that split, the sync is mostly boring, which is the goal.

The device holds an append-only queue of events, each with a client identifier generated at creation, a monotonic sequence number within the round, and the time it actually occurred. On reconnect it replays them in order. The server accepts each one idempotently on the client identifier, so a partial upload retried in full changes nothing and a duplicate is a no-op rather than a second collection.

Two details are worth building in from the start. Record the time the event occurred, not the time it was uploaded, and record both — the gap between them is diagnostic. And keep the queue after a successful upload for long enough that a phlebotomist who is asked "what happened at the second address" can answer from the device rather than from memory.

The conflicts that remain, and why a person has to see them#

Most of the collection workflow cannot conflict, because only one person is doing it. What remains is the set of cases where the world changed centrally while the device was away, and every one of them is a case where guessing is unacceptable.

  • The order was cancelled centrally, and the specimen was collected anyway. The specimen exists. It is in a bag. Discarding the event because the order is cancelled loses the fact that a patient was bled.
  • The patient was collected at a walk-in centre while the phlebotomist was en route, so there are two collections for one order.
  • The requested tests changed after download, so the tubes drawn do not match the tests now requested.
  • The specimen was rejected on receipt for a reason the phlebotomist could not have known.

Last-write-wins resolves all four silently and gets at least two of them wrong. The correct behaviour is to accept the event — it is true, it happened — and raise the discrepancy for a person to settle, with both sides of it visible.

This is the same argument as versioned results, one workflow earlier. A collection that conflicts with a cancellation is not a data problem to be reconciled by a rule; it is a clinical situation in which somebody drew blood that may not be needed, and that person deserves an answer rather than a silent discard.

What the device is allowed to hold#

An offline-capable clinical application is a device carrying patient data outside a building, and the design has to be honest about that.

  • Today’s round only, and only what identification and collection require. No history, no results, no other patients.
  • Encrypted at rest by the platform, behind the device lock, with the application requiring authentication on resume rather than staying open.
  • Purged when the round is reconciled, on a timer that runs whether or not anybody remembers.
  • Remotely revocable, so that a lost device stops being a problem once it next has signal — and a device that never regains signal is why the purge timer is local rather than server-driven.

Why the rest of the laboratory stays online#

It would be consistent-sounding to extend the same model to result entry and validation. It would also be wrong.

Validation is a judgement made with context: the patient’s previous values, the delta check, the quality-control state of the run, and whether a critical value needs an escalation. Every one of those is a fact about the current state of the system, and a validation made against a cached version of them is a judgement made on stale evidence. Release is worse still, because it is the moment somebody else may act.

So collection is offline-first and the bench is online, and that is a deliberate boundary rather than an unfinished one. The place where a person is standing in front of a patient with a needle is the place where the network cannot be a prerequisite. The place where a person is deciding whether a number is safe to send to a clinician is a place where knowing the current state is the whole job.

Where to read the real thing.

The synchronisation ideas here are general computing rather than clinical, and the clinical constraints are somebody else’s to set.

  • Your accrediting body’s requirements on specimen identification and labelling, which are the ones that decide what a phlebotomy application must enforce at the patient rather than afterwards.
  • The literature on pre-analytical error, which is where the argument for labelling at the point of collection comes from. It is not a design opinion.
  • Any good account of event sourcing and idempotent replay. The queueing model in this article is an ordinary one and the laboratory part is only in which actions are allowed into it.
  • Your platform’s guidance on data at rest on mobile devices, which is the part of this that is a security question rather than a workflow one.

Scoped to specimen collection, deliberately. Result entry, validation and release are online operations in LabFlow, and the last section says why rather than leaving it as an omission. Written by the LabFlow team, not by phlebotomists.

Written by the team that implemented it.

The LabFlow team, who build LabFlow and wrote the rule evaluation this article describes. Not laboratory scientists: the domain here was read rather than practised, from standards documents, published rule sets and the source of the system being replaced.

That is enough to build software carefully and it is not the same as having run a bench for ten years. Where this article states something as fact it is traceable to a source above or to code; where it is inference, the sentence says so.

If something here is wrong, say so. It gets corrected in place with a dated note and the original quoted, as the correction above shows, and credited unless you ask otherwise.

This article

Published2026-05-26
AuthorThe LabFlow team
Clinical reviewNone
SponsoredNo. There is nobody to sponsor it

More on who is behind LabFlow, and why there is no team page, is on the about page.

14 Jul 2026

HL7 v2 or FHIR: which one to build first

The honest answer is v2, and the reason is not technical merit. Includes the boundary between a message format and the network process that carries it.

About 9 minutes.

16 Jun 2026

Tenant isolation in a multi-tenant LIMS

Why a list query has to prove its own tenant from its own filters, and why a policy reading a field the query never filters on leaks with a clean 200.

About 12 minutes.

The rule that decides what may queue.

An action may queue if replaying it late is still true. "I collected this at 09:14" survives the delay because it describes something that happened. "Cancel this order" does not, because it describes something that should happen now, and by the time it arrives now has moved.

Everything else follows: events queue, commands do not, and the conflicts that remain are the ones where a person drew blood that may not have been needed. Those reach a human being rather than a resolution rule.

Found something wrong in this article? Say so. It is corrected in place with a dated note and the original quoted, exactly as the correction above was.