What Happens to Attendance When the Internet Goes Down

In one day of live traffic our attendance endpoints served 154,195 requests and returned 89 errors. Not one of the errors was on the endpoint that carries punches. That is not luck, it is the shape of the protocol.

A biometric terminal does not need your server to do its job. It matches the

finger or the face locally, writes the punch to its own memory, and delivers it

when it can. The network carries the record afterwards; it is not part of

recording it.

That distinction is why an attendance system can survive an outage without losing

anything, and it is worth understanding in detail, because the same architecture

explains what does go wrong.

What one day of real traffic looks like

From our production web server log, a single day, 31 August 2026:

154,195 requests, 96.1 per cent of everything the server handled that day, and 89

errors.

Every one of those 89 errors landed on getrequest or ping. **Zero landed on

cdata**, which is the endpoint that carries punches.

That is not luck. It is what the traffic shape makes almost inevitable, and the

reason is the ratio in the first column.

Why the punch endpoint is the safe one

getrequest is the terminal asking "do you have anything for me?". It runs

constantly, from every device, on a short interval. 153,575 times in a day. It

carries no data and nothing depends on any individual call succeeding, because

another one follows seconds later.

cdata is the terminal saying "here is what happened". It runs only when there is

something to deliver. 320 times in the same day.

So the endpoint that matters is used 480 times less often than the one that does

not, which means a brief server interruption is overwhelmingly likely to land on

a poll. The 88 failures we recorded represent 88 command checks that happened a

few seconds later than intended, and no user-visible consequence whatsoever.

The failures also cluster: 41 of the 89 fell in a single hour, and the rest

spread across three others. That is the signature of short interruptions rather

than a persistent fault, which is exactly what a restart looks like from the

device's side.

The acknowledgement is the whole design

Even when a punch upload does fail, the record survives, and the mechanism is

simpler than people expect.

The terminal sends its batch and waits for a reply. Our server responds with a

count of what it stored. Only on receiving that acknowledgement does the terminal

consider those records delivered and free them from its memory.

No acknowledgement, no deletion. A connection that times out, a server that is

restarting, a 502 from a proxy: all of them leave the terminal holding exactly

what it was holding before, and it tries again on its next cycle.

This is why "will a deploy lose punches?" has a boring answer. During a restart

the terminal cannot deliver, so it does not delete, so it delivers afterwards

instead. The only thing that changes is when the record arrives, and every record

carries the time it actually happened rather than the time it was received.

Why it works from sites you do not control

The connection is outbound. The terminal dials the server, not the reverse.

That single property removes most of the infrastructure that attendance

deployments used to require. No fixed IP at the site. No inbound port opened on

somebody's router. No VPN between head office and a shop unit whose network is

managed by the landlord. The terminal needs to reach one address on the public

internet, which is a thing almost every connection can already do.

It also means a site with a weak connection degrades gracefully rather than

failing. Records queue locally and drain when the link is available. In practice

we see the effect of this in the delivery latency rather than in loss: promptly

delivered punches arrive within about two hours of occurring, and the ones that

take longer are the ones behind a poor link.

Where data genuinely can be lost

Three ways, none of them a network outage.

Somebody clears the device. A terminal holding undelivered records, factory

reset or cleared during troubleshooting, loses them permanently. This is the most

common real cause and it usually happens while somebody is trying to fix

something else.

The device is replaced while holding a queue. Same problem with better

intentions. The old unit comes off the wall with records still in it.

The queue overflows. Terminals store tens of thousands of records, so this

takes weeks of disconnection for most sites. It is real but it is the least

likely of the three.

Every one of these is a human action during an outage rather than the outage

itself. Which suggests the correct operational rule: **when a terminal is

offline, restore the connection before you touch the device.** Let it drain

first. Whatever you were going to reset will still be resettable in ten minutes,

and the records will not.

The trade-off nobody mentions

Push architecture buys the resilience described above and costs something in

return, and it is worth stating because the cost is usually discovered rather

than chosen.

You cannot ask a terminal anything. The server never initiates. If you want

to know whether a device is holding undelivered records, you wait until it next

speaks to you. Everything you know about the fleet is what it last told you,

which is why the status field is a memory rather than a measurement.

Commands are answers to a question. When you want a device to do something,

enrol a user, delete a template, reboot, you cannot send it. You queue it and

wait for the device to ask. That is what those 153,575 polls are for: they exist

so the server has an opportunity to reply. It is a slightly odd inversion, and it

is why device commands feel slower than they should.

The serial number is the identity. There is no key exchange, no certificate,

nothing but a string in a query parameter. That is why pushes from unregistered

serials have to be refused: the serial is a name, not a credential, and anything

that treats it as proof is treating a name as proof.

Given the choice again we would take the same trade. Reaching outward from the

site is what makes the deployment possible at all, and a protocol that never

loses a record while occasionally being slow to answer a question is the right

way round for attendance. But a system built on it should be honest that fleet

visibility is inherently lagging, rather than presenting a cached state as a live

one.

What to check in your own system

Does the endpoint that receives punches acknowledge with a count? A generic

success reply is weaker: it tells the device to delete without telling you how

much was stored, and the two can disagree.

Do your error logs separate the polling endpoint from the upload endpoint? If

they are aggregated, a real ingestion failure is hidden inside a much larger

volume of harmless retries. Ours would have been: 89 errors in 154,195 requests

is noise until you split it by endpoint, at which point it is a clean result.

**Does every punch carry the time it happened, separately from the time it

arrived?** Without that, a delayed batch after an outage lands on the wrong day

and the outage causes a data problem after all.

See how Wurxa reads your terminals ·

Every way a terminal fails

Put the workflow into practice.

Start with every Wurxa feature for 14 days. No credit card required.

Start free trial

Frequently asked questions

Do biometric terminals keep working when the internet is down?

Yes. A ZKTeco terminal matches fingerprints and faces locally and stores the resulting punch in its own memory. The network is only needed to deliver that record onward. Employees clock in and out exactly as normal during an outage and the terminal keeps a queue.

Are attendance punches lost during a server outage?

They should not be, and the reason is the acknowledgement. The terminal only clears a record from its memory once the server confirms receipt. If the server is unreachable or returns an error, the terminal keeps the record and tries again. Punches are lost only if the terminal's own storage is cleared before delivery.

What happens to attendance when the server restarts?

In our production log, one day of traffic produced 154,195 requests to the attendance endpoints and 89 errors, every one of them on the command-polling endpoint rather than the data-upload endpoint. The polls are retried seconds later and nothing depends on any single one succeeding.

How does ZKTeco ADMS push data to a server?

The terminal opens an outbound HTTP connection and posts its records, identifying itself with its serial number in the query string. The server replies with a short acknowledgement. Because the connection is outbound, the terminal needs no fixed IP address, no inbound port and no VPN, which is why it works from sites the head office has no network control over.

How long can a terminal stay offline before data is lost?

It depends on the model's storage, but the practical limit is usually tens of thousands of records, which is weeks for most sites. The risk in a long outage is not the queue overflowing but somebody clearing the device or replacing it while records are still waiting to be delivered.

Related reading

More from Wurxa

Continue reading

Devices7 min read

Why We Stopped Trusting the Device Clock

29.5 per cent of our punches appear to have been recorded four hours before they happened. The devices are fine. The bug is a category error about what a timestamp means, and it is the most expensive one in attendance software.

Read article
Payroll7 min read

The Overtime You Are Paying and Cannot See

72 per cent of the overtime in our data is paid at the 150 per cent rate, not 125. If you budget overtime at the standard rate, you are budgeting with the number that applies to the smaller share of it.

Read article