A regional airline operator came to us with a problem that sounds small and isn’t: the monthly bill for their real-time data layer would not come down, and every attempt to optimize it ended in the same uncomfortable trade-off — either they overpaid, or the information reached the ramp too late.
We redesigned the system that keeps each flight’s operational data in sync and distributes it live to the tablets used by ground and onboard staff. Daily synchronization load dropped between 95% and 98.75% in the highest-volume blocks, and reads against Firebase Realtime Database fell by a factor of ~420x — without losing a single second of freshness on screen.
01
The problem was not volume. It was flat cadence.
The previous system treated every flight the same way, all the time. A flight departing at 22:00 was polled just as insistently at 06:00 in the morning as at 21:40, when something is actually happening. Multiplied across every eligible flight, every endpoint of the reservation system and every hour of the day, that produces hundreds of thousands of daily refreshes, of which a tiny fraction discover a real change.
It is the most expensive pattern in aviation integrations: paying for constant frequency to catch events that cluster in very narrow windows.
And it isn’t solved by simply polling less. Lowering the frequency evenly makes the operation cheaper and breaks the product: the moment the data has to be exact — door close, the last seat change, the passenger who never showed — is exactly the moment that relaxed polling arrives late.
02
First decision: adaptive cadence by operational proximity
We rebuilt synchronization as a ladder of stages anchored to each flight’s estimated time of departure. Every flight climbs that ladder on its own, according to how far it is from its operation, and each stage has its own rhythm. The principle is simple to state and surprisingly rich to calibrate: a flight’s refresh frequency should be a function of its distance to the event, not of the wall clock.
The compound effect is decisive: the manifest went from 396,000 daily refreshes to 4,950, and aircraft data from 108,000 to 4,950. Not because the system looks less, but because it stopped looking where nothing was happening.
The least obvious consequence, and the most valuable operationally: data quality during the hot hour went up.
By freeing the request budget that was being spent on dormant flights, we could tighten cadence in the critical window without moving total cost upward.
The detail that changes everything: configuration to the millimeter
A ladder of stages hard-wired in code is a new problem dressed as a solution. Airline operations are not stable: they change by season, by station, by flight type, by how the reservation system behaves in a specific market. That is why every stage is configuration, not code. For each one, the following is defined independently:
That enables something worth as much in practice as the savings themselves: adjusting the synchronization policy without deploying. If a station needs more resolution in the last 30 minutes, you move a parameter. If an endpoint starts responding slowly at a specific time of day, you relax that branch alone without touching the rest. If an international route requires one additional field, you add it only where it belongs.
03
Second decision: use Firebase for what Firebase does best
Here was the other major drain, and it was less visible. Firebase Realtime Database is excellent at one very specific and difficult thing: distributing a state change to many subscribed devices, instantly, securely, with reconnection already solved. When a flight’s state changes, every subscribed tablet receives it by push, without anyone asking. That is exactly what a ramp operation needs.
What RTDB is not — and where cost explodes — is a query database for the backend. Billing is proportional to bytes downloaded. A server process that re-reads the flights root node in a loop to learn which flights it has to handle now is paying, over and over, to download 600 KB of data it wrote itself thirty seconds ago. In numbers: 20,160 daily reads of the main node, roughly 362.88 GB of monthly download traffic, almost entirely redundant.
The in-memory mirror
We inverted the relationship. The service keeps an in-memory mirror of flight state, hydrated with a full snapshot and refreshed every 30 minutes, while the changes the service itself produces are applied to the mirror at the same moment they are written.
20,160 / day → 48 / day. The root snapshot refreshes every 30 minutes; everything else lives in memory.
362.88 GB → 0.864 GB. A factor of ~420x, with identical behavior on screen.
Every component ended up doing only what it does better than the alternative.
Process memory handles hot, high-frequency state. Firebase handles real-time distribution to N devices with delivery and security guarantees. Neither one pays the price of doing the other’s job.
04
The savings, endpoint by endpoint
Comparable base: 50 visible flights per day at one station, average departure time 12:00, 2 hours of average live tracking. The table shows the verifiable floor, not the best case.
| System / data | Before / day | Now / day | Savings |
|---|---|---|---|
| Flight manifest | 396,000 | 4,950 | −391,050 · −98.75% |
| Passenger detail | 396,000 | 4,950 | −391,050 · −98.75% |
| Special service requests (SSR) | 396,000 | 4,950 | −391,050 · −98.75% |
| Leg inventory | 396,000 | 4,950 | −391,050 · −98.75% |
| Government security information (international only) | 396,000 | 4,950 | −391,050 · −98.75% |
| Aircraft data (inbound) | 108,000 | 4,950 | −103,050 · −95.42% |
| Flight status (PSS) | 14,400 | up to 7,290 | −7,110 · −49.4% |
The flight status figure deserves an honest caveat, because it is the one we usually see reported badly in this kind of write-up: 7,290 is an upper bound, not an expected value. It assumes all 50 daily operations are consecutive departures and that each stays live for 2 hours. If some of those flights are arrivals, or if actual live time is shorter, the number drops appreciably — in mid-range scenarios it falls to 3,665 and in the tightest ones to 2,915.
05
What it means on the bill
Against a reference history of $800 to $1,000 per month, the new model projects into a far lower band. We communicate $80 – $200 as the working estimate, not the optimistic scenario: we would rather the number a committee walks away with be the one that holds under conservative assumptions.
The direct saving, in any case, is the least interesting part of the outcome. What was gained alongside it:
06
What we took away as principle
Three ideas we have applied since then in any real-time system with a per-operation cost.
Cadence is a resource, and it has to be budgeted.
It is not about refreshing more or less: it is about deciding explicitly where frequency gets spent. It is almost always badly distributed, and the redesign almost always improves cost and quality at the same time, not one at the expense of the other.
If a policy is going to change, it has to be configuration.
Every synchronization parameter that is hard-wired today is a future maintenance window. Externalizing them turns each adjustment from weeks into minutes, and allows calibration by station, by route and by season without touching the system.
Every piece of infrastructure is irreplaceable at one thing and expensive at many.
Firebase is extraordinary at distributing changes to thousands of subscribed devices. It is a poor place for a backend to go read its own state. Separating those roles required no new technology: it required seeing where the same data was being paid for twice.
07 — Let’s work together
If you are paying for constant frequency to catch events that happen in narrow windows, there is a similar case waiting in your bill.
Flyware designs and builds operational data systems for aviation: real-time synchronization, PSS integrations, and ground and onboard platforms. We start by measuring where cadence is going — and that measurement alone usually pays for the project.
Case study · Flight operations synchronization. Figures on a comparable base of 50 flights/day.