Blog /Product News

How We Made Twine POS Faster: The Order Entity Refactor

By Mark Bonnici|
How We Made Twine POS Faster: The Order Entity Refactor

If you have updated Twine POS recently, you have probably noticed it feels faster. Tapping products, scanning barcodes, completing payments — everything responds quicker than it used to. That is not a placebo effect, and it is not the result of one small tweak. It is the outcome of a fundamental change we made to how the app handles order data.

In version 4.0, we rewrote the order entity — the core data structure behind every order in Twine POS. It touched 417 files across the codebase. And it is the single biggest reason the app is faster and more reliable today.

What Was Wrong with the Old Approach

In v3, every order in Twine POS was built around a data structure called OrderEntity. It worked, but it had accumulated technical debt over time as features like split billing, course management, delivery integrations, and multi-device sync were added on top of it.

The biggest problem? N+1 database queries. Every time the app needed to display an order — on the register, in the cart, on a receipt — it would fetch the order, then individually fetch each item's variant, VAT rate, menu item details, discount information, and addon options. For a single order with a handful of items, that could mean 189 or more separate database queries.

During a quiet lunch service, you might not notice. But during a Friday night rush with multiple devices syncing, orders flying in from Wolt and Bolt, and staff tapping through the register at speed — those queries add up. Every millisecond counts.

What We Changed

The v4.0 order entity refactor replaced the old OrderEntity with a new OrderWithDetails data transfer object (DTO), purpose-built for how orders actually flow through the app. Here is what that means in practice:

Batch Queries Instead of One-by-One

Instead of fetching each piece of order data individually, the app now batches related queries together. Variants, VAT rates, menu items, discounts, addon groups, and addon options are all fetched in bulk.

The result: 189+ queries reduced to 4-8 batch queries for the same order. That is not an incremental improvement — it is an order-of-magnitude change.

Typed, Structured Data

The old order item model relied on loose data structures that were prone to inconsistencies. The new OrderableWithDetailsDto uses typed getters and pattern matching, meaning the app knows exactly what data it is working with at every step. Fewer runtime surprises, fewer edge-case bugs.

Centralised Logic

Over time, the same order-enrichment logic — calculating totals, resolving discounts, mapping item details — had been duplicated across multiple parts of the codebase. We extracted this into a single OrderableDetailsMapper, consolidating roughly 330 lines of duplicated code into one shared source of truth.

This matters beyond just code cleanliness. When there is one place that calculates order totals and one place that resolves item details, bugs get fixed once and improvements benefit every screen in the app.

Why This Matters for Your Business

You do not need to understand DTOs or batch queries to feel the difference. Here is what the refactor means at the till:

  • Faster order loading — opening an order, scrolling the cart, and reviewing items before payment all happen noticeably quicker
  • Smoother multi-device sync — less data to process per order means secondary devices stay in sync more reliably
  • More consistent receipts and tickets — centralised order logic means what you see on screen matches what prints, every time
  • Fewer edge-case bugs — typed data structures catch inconsistencies before they reach the customer

The Foundation for Everything After

The order entity refactor was not the end of the performance story — it was the beginning. Once the codebase was structured cleanly, subsequent optimisations became possible:

  • v4.1.3 eliminated an unnecessary database lookup during barcode scanning, making it instant
  • v4.2.0 enabled SQLite performance pragmas on Windows, speeding up every tap and scan
  • v4.3.0 removed limits on SQLite's query planner statistics, allowing smarter query execution during busy periods

Each of these changes was smaller in scope, but they were only feasible because the order entity refactor had already eliminated the structural bottlenecks. You cannot optimise a query planner when the app is making 189 queries where it should be making 8.

What Comes Next

A cleaner codebase does not just make the app faster today — it makes it easier to build on tomorrow. New features like camera-based barcode scanning, customer pickup boards, and warranty printing all sit on top of the same order architecture. They work reliably because the foundation is solid.

If you are running Twine POS, make sure you are on the latest version to benefit from all of these improvements. You can check for updates directly in the app, or visit the downloads page. And if you are evaluating POS systems for your restaurant or retail shop, this is what a modern, actively maintained POS looks like under the hood.

Ready to modernise your business?

See how Twine POS can streamline your operations and grow your revenue.