HomeOffline-First POS
Offline-First Architecture

Offline-first POS architecture

Internet connectivity is a convenience, not a guarantee. A POS system that stops working when the network drops is a liability. Offline-first design inverts this: the network is optional, and synchronization happens when it's available — not as a precondition for operation.

Get Started Architecture

What offline-first actually means

"Offline support" often means a limited fallback mode. Offline-first means the opposite: the local database is the primary source of truth, and the network is used only for synchronization when available. Every operation — sale, payment, inventory deduction, loyalty calculation — completes against local storage before any network call is attempted.

Local-first storage

All POS data lives in a local SQLite database on the terminal. Sales, inventory, customers, and campaigns are all queryable without a network connection.

Outbox pattern

Every completed event (sale, closure, stock movement) is written to a local queue before any sync attempt. The queue is durable — it survives application restarts.

Background sync

A background thread periodically attempts to flush the queue to OFFICE or GATE. Success marks items as synced. Failure leaves them in the queue for retry.

How SaleFlex implements offline-first

SaleFlex.PyPOS implements the offline outbox pattern through two components: SyncQueueItem (the durable queue) and SyncWorker (the background thread).

1

Sale completes locally

Payment is confirmed, the temp transaction is atomically moved to permanent models, and a receipt number is assigned. All against local SQLite — zero network calls.

2

Event written to outbox

A SyncQueueItem record is created for the completed transaction. It includes the serialized payload and a status of PENDING.

3

Background worker checks connectivity

The SyncWorker QThread wakes on its configured interval and attempts to reach OFFICE or GATE. If the network is unavailable, it sleeps and retries next cycle.

4

Queue is flushed when connected

Pending items are pushed in order. Successfully acknowledged items are marked SYNCED. Failed items remain PENDING and are retried next cycle.

5

Pull updates on connection

After a successful push cycle, the worker pulls product and campaign updates from GATE, refreshing the local cache without interrupting active sales.

Crash recovery and data integrity

SaleFlex.PyPOS uses a temp → permanent transaction model. Every sale starts as a draft in temp models. On payment completion, the temp models are atomically copied to permanent models in a single database transaction. If the application crashes mid-sale, the temp draft is restored on next startup — no data is lost and no partial records are written to permanent storage.

 No partial writes

The temp-to-permanent copy is a single atomic SQLAlchemy transaction. Either the full record is written or nothing is — no half-completed sales.

 Automatic crash recovery

On startup, any non-pending ACTIVE document is automatically detected and restored. The sale UI reopens exactly where it was before the crash.

Offline-first reduces the failure surface

SaleFlex writes committed transactions locally before sync, so network outages do not block checkout. Reliability still depends on normal operational controls such as backups, hardware health, and monitoring failed queues.

Get Started Integration Details