Prasoon Soni

All writing

How Where Is My Train finds your train without internet or GPS

· 10 min read · Android, Mobile networks, System design

Your phone is talking to a mobile tower all the time, even with mobile data off. Where Is My Train turns that one fact, plus a timetable stored on your phone, into a live position for your train. Here is how it works, how accurate it can be, and how to see the same data on your own phone.

0mobile data needed on the train
Topic
Mobile networks · location · Android
Based on
The app's Google Play listing, 3GPP and Android docs, Mozilla's location service docs, and press coverage of the 2018 Google deal
Edition
November 2026

TL;DR

  • Where Is My Train shows a train's live position in India. Its own listing says that when you're on the train, this feature "can work without internet or GPS as it uses cell tower information to find the location" [1].
  • A phone stays registered to a mobile tower whenever it has signal, with data on or off. That's how calls and SMS reach you, and every cell has an ID the phone can read.
  • The app keeps the Indian Railways timetable offline on the phone [1], so it already knows your train's route and the order of its stations.
  • Matching "which cell am I on right now" to a spot on that known route gives a position with no data connection. When the cell changes, the train has moved on.
  • It's an estimate, not a GPS fix: a cell can be small in a city and many kilometres wide in the countryside [6], so precision follows the size of the cell.
  • Google bought the app's maker, Sigmoid Labs, in December 2018 [3].
0
internet or GPS needed on the train [1]
500M+
Play Store downloads, Nov 2026 [1]
10M+
downloads when Google bought it, 2018 [2][3]
Dec 2018
Google acquires Sigmoid Labs [3]
2015
first Android release [5]

Mobile networks, from zero

A mobile network covers the country with towers (base stations). Each tower serves one or more cells: the patch of ground its antennas cover. Your phone is always "camped" on one serving cell and keeps an eye on the neighbouring ones, so it can switch as you move.

Every cell has a name

Each cell broadcasts an identity. In GSM this is the Cell Global Identity (CGI): four numbers that together are unique worldwide [7].

PartWhat it identifiesExample
MCC · Mobile Country CodeThe country404 / 405 = India
MNC · Mobile Network CodeThe operator in that countrye.g. 45
LAC · Location Area CodeA group of cells (a location area)e.g. 1302
CI · Cell IdentityOne cell inside that areae.g. 40123

4G uses the same idea under another name, the E-UTRAN Cell Global Identity (ECGI), with a longer 28-bit cell ID [7]. The MNC, LAC and CI values above are illustrative.

Your phone reports in, even with data off

To deliver a call, the network has to know roughly where you are. So an idle phone sends a location update whenever it moves into a new location area, and also on a regular timer [8]. None of this uses mobile data: it's the same signalling that lets a call ring on a phone with data switched off.

Always
Phonecamps on a cell, reads its IDwatches neighbour cells
On the move
enters a new arealocation updatenetwork knows where to ring you

The part that matters here: the phone itself always knows which cell it's on, and apps can read it (see "See your own cell ID" below).

Why a moving train is hard to track

Problem 1: data comes and goes

On a long journey, coverage keeps changing: city stretches with good 4G, then fields, ghats and tunnels with weak or no data. An app that needs the internet to fetch a live position goes blank exactly when you most want to know where you are.

City
4G ✓live status loads
Countryside
No data ✗spinner, nothing loads
Next town
4G ✓loads again

Problem 2: GPS inside a train isn't easy either

GPS needs a clear view of the sky. Under open sky a smartphone is typically accurate to about 4.9 m, but buildings, bridges and trees make it worse [9]. Inside a metal coach, away from the window, a phone can take a long time to get a fix, and keeping GPS on for hours drains the battery.

Why it matters

  • Waking up at the right station is the real job, and it matters most at night, often in exactly the stretches with no data.
  • Telling family where you are shouldn't depend on 4G.
  • Battery: a long journey with GPS always on is a drained phone.

The insight: the route is already known

Finding a random phone from a cell ID alone is rough, because a cell can be big. But a train is not a random phone.

1 · The track is fixedA train can only be on its own line. A cell that covers a 5 km circle covers only a short stretch of that one track, so "which cell" narrows the train down to a segment of the route, not a whole area.
2 · The schedule is knownThe app stores the Indian Railways timetable offline [1]. It knows the station order and roughly when the train should be where, which helps it choose between nearby segments and fill the gaps between cell changes.

How it works, step by step

The app's makers haven't published their algorithm, so this is a simplified model built from what the listing says [1] and how mobile networks work [7][8]. Treat the details as a reconstruction, not the app's code.

  1. 1

    Download the timetable once

    The Indian Railways timetable (trains, stations, order, times) is stored on the phone [1]. You pick your train, and the app knows its route.

  2. 2

    Know which cells sit along each route

    To turn a cell ID into a place, the app needs a map from cell IDs to stretches of track. How Where Is My Train builds this isn't public; a map like this is typically built up from many phones' observations along known routes.

  3. 3

    Read the serving cell

    On the train, the phone reports which cell it's camped on (and which neighbours it can see). It's the same information the phone uses for calls, so it works with data off.

  4. 4

    Snap it to the route

    The cell is looked up in the map and placed on your train's route: "between Station B and Station C". The timetable helps choose when a cell touches more than one segment.

  5. 5

    Follow the changes

    As the train runs, the serving cell changes. Each new cell further down the line moves the train forward on the map. Between changes, the timetable gives a sensible guess of progress.

The picture

📶 Serving cell

MCC · MNC · LAC · CI read from the radio. No data, no GPS.

🗺️ Cell → track map

Which stretch of which line each cell covers (simplified).

🕒 Offline timetable

Stations, order and times for your train [1].

🚆 Position

"Between Station B and C": a live estimate on the route.

The matching idea, in code

A tiny illustration of the last two steps. It is not the app's code; a real system also handles noise, neighbour cells and missing entries.

route matching · illustrative Kotlin
// a stretch of one line that a cell is known to cover
data class Stretch(val fromStation: String, val toStation: String, val km: ClosedRange<Double>)

// cell id ("mcc-mnc-lac-ci") -> stretches of track it covers (built offline)
val cellMap: Map<String, List<Stretch>> = loadCellMap()

fun locate(cell: String, route: Route, lastKm: Double): Stretch? {
    // keep only stretches on THIS train's route
    val onRoute = cellMap[cell].orEmpty().filter { route.covers(it) }
    // trains don't go backwards: prefer the stretch just ahead of the last fix
    return onRoute.filter { it.km.endInclusive >= lastKm }
                  .minByOrNull { it.km.start - lastKm }
}

Two cheap tricks do most of the work: the route filter (a train can't be on another line) and "forward only" (a train can't jump back).

Accuracy and trade-offs

  • Cell size sets the precision. Cells are small in cities and large in rural areas. Mozilla's open location service notes GSM cells can reach 35 km, rural 3G cells have been seen at 60–70 km, and 4G cells are often smaller [6]. On a route, though, a big cell still maps to one stretch of track.
  • Updates are steppy. The position jumps when the cell changes; in between, it's a guess from the timetable.
  • Late or early trains. The timetable says where the train should be; the cell says where it is. When they disagree, the cell wins, but a big cell leaves room for error.
  • Coverage gaps. With no signal at all (some tunnels), there's no cell to read either; the app can only estimate until the next cell.
  • Privacy and permissions. On Android, reading cell information requires the location permission [10], because a cell ID reveals roughly where you are.
  • Battery and data. Reading the serving cell costs almost nothing, which is why the listing calls the app very efficient in battery and data use, with key features working offline [1].

GPS vs a cell tower, to scale

How big is the "you are somewhere in here" circle? Typical radii, drawn to scale against a 10 km rural cell:

GPS, open sky
~4.9 m
Small city cell
e.g. 300 m
Rural cell
e.g. 10 km

GPS figure from GPS.gov [9]. The two cell sizes are illustrative examples within the ranges in [6]; real cells vary by operator, terrain and technology. The GPS bar shows at its minimum visible width.

Ways to track a train, compared

ApproachNeedsTrade-off
Official running status (Indian Railways NTES)InternetAuthoritative, but you need data to see it
Phone GPSSky view, batteryPrecise when it works; weak inside a coach, heavy on battery
Shared live location (maps apps)GPS + internetStops updating in dead zones
Cell tower + offline timetableJust the signal you need for callsWorks offline, almost no battery; precision depends on cell size

See your own cell ID

You can read the same information the app uses. Here's a minimal Android example that prints the cell your phone is camped on.

1. Ask for location permission

Cell information counts as location data, so Android requires ACCESS_FINE_LOCATION for it [10].

AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

2. Read the serving cell

TelephonyManager.getAllCellInfo() returns the camped/registered cell and the neighbours the phone can see [10]. The registered one is your serving cell.

MainActivity.kt · Kotlin
val tm = getSystemService(TelephonyManager::class.java)
// call only after the user has granted ACCESS_FINE_LOCATION
val serving = tm.allCellInfo?.firstOrNull { it.isRegistered }

when (serving) {
    is CellInfoLte -> serving.cellIdentity.let {
        // 4G: mcc / mnc / tracking area / cell id
        println("LTE ${it.mccString}-${it.mncString}-${it.tac}-${it.ci}")
    }
    is CellInfoGsm -> serving.cellIdentity.let {
        // 2G: mcc / mnc / location area / cell id
        println("GSM ${it.mccString}-${it.mncString}-${it.lac}-${it.cid}")
    }
    else -> println("no registered cell (no signal?)")
}

3. Watch it change

  • Turn mobile data off and run it again: you still get a cell. That's the whole trick.
  • On a bus or train ride, log it every minute: the ID changes as you pass from tower to tower.
  • Newer Android versions cache cell info; requestCellInfoUpdate() asks for a fresh reading [10].

Code is illustrative and trimmed (no permission prompt or error handling). Field names come from Android's CellIdentityLte and CellIdentityGsm classes [10].

So, how does it find the train?

Tower + timetable.

Your phone always knows which mobile cell it's on, internet or not. The app already has your train's route and schedule on the phone. Put the two together and it can say "your train is between these two stations" from a coach with no data and no GPS.

What the phone givesThe serving cell's ID, for free, and a new ID every time the train moves into another cell.
What the app addsThe timetable, offline [1]; which cells lie along which stretch of track; and the matching that turns a cell into a spot on your route.

Getting the best out of it

DoOpen the app and pick your train before you lose signal. Set the destination alarm for night journeys [1]. Allow the location permission: it's needed to read the cell.
ExpectCoarser positions in rural stretches, where cells are big. Small jumps rather than a smooth glide. A pause in tunnels with no signal at all.

Caveats

  • Not the app's published design. The listing confirms the cell-tower method and the offline timetable [1]; the step-by-step model above is a simplified reconstruction.
  • How the cell map is built isn't public. Wikipedia mentions anonymised data from users and reports from Indian Railways' NTES, but cites pages that no longer load [5], so this post doesn't rely on it.
  • Two download numbers. "10M+" is from press coverage of the 2018 deal [2][3]; "500M+" is the Play Store counter in November 2026 [1].
  • Accuracy figures are general. The cell sizes in [6] come from Mozilla's location service, not from this app or Indian operators.

FAQ

Does it really work with mobile data off?
On the train, yes. The listing says the feature can work without internet or GPS because it uses cell tower information [1].
Does it need a SIM card?
It needs the phone to be on a mobile network, since the serving cell is what it reads. With no SIM and no network, there's no cell to read.
Is this the same as triangulation?
Not quite. Using only the serving cell ID is the simplest form. Combining several towers' signals can do better, but the core idea here needs just the one cell plus the known route.
Can my operator see where I am?
The network always knows roughly which cell you're in; that's how calls reach you [8]. The app reading the cell ID on your phone doesn't change that.
Why does it sometimes show the wrong station?
Big cells, a late train or a stale reading can put the estimate a stretch off. It corrects itself at the next cell change, or when data comes back.
Who makes it?
Sigmoid Labs, the Bengaluru startup Google bought in December 2018 [3]; the listing names "Sigmoid Labs and its affiliates" [1].

Glossary

Cell
The area covered by one set of antennas on a tower.
Serving cell
The cell your phone is camped on right now.
CGI / ECGI
Cell Global Identity: country + operator + area + cell number, unique worldwide (ECGI in 4G).
LAC / TAC
Location or tracking area code: a group of cells the network tracks you by.
Location update
The idle phone telling the network which area it's in, so calls can reach it.
NTES
National Train Enquiry System: Indian Railways' official train running information.
GPS fix
A position computed from satellite signals; needs a view of the sky.

Sources

  1. Where is my Train. Google Play listing (description, downloads), read November 2026.
  2. Google acquires the Where Is My Train app. Android Authority, December 2018.
  3. Google acquires Sigmoid Labs, developer of popular Indian app 'Where is my Train'. VentureBeat, 10 December 2018.
  4. Download count at the time of the deal (10M+): Android Authority [2] and VentureBeat [3].
  5. Where Is My Train. Wikipedia (launch date; data-source claims with dead citations).
  6. Accuracy. Ichnaea (Mozilla Location Service) documentation.
  7. Cell Global Identity. Wikipedia, after 3GPP TS 23.003.
  8. Location area. Wikipedia.
  9. GPS Accuracy. GPS.gov.
  10. TelephonyManager.getAllCellInfo() and CellIdentityLte. Android developer reference.