How to Safely Query a Production MongoDB From Your Phone
Being able to check production from your phone is great right up to the moment a stray tap updates the wrong document, or a broad filter scans a hundred million records during peak traffic. This guide sets up a safe way to query a production MongoDB from your phone: what to configure in the database, on the network, in the connection string and in the habits you bring to a small screen.
What can go wrong
It helps to name the risks before fixing them:
- Accidental writes. Small screens and autocorrect make mistakes easier.
- Expensive queries. An unindexed filter or an unbounded count on a big collection competes with your real traffic.
- Network exposure. Opening the database to “anywhere” so a phone can connect.
- A lost or shared device holding credentials with too much power.
Each fix below addresses at least one of these.
1. Create a read-only user just for your phone
Don’t reuse your application’s database user, and never your admin account. Create a dedicated user with read-only privileges, so the worst a mistake can do is read.
In Atlas, go to Database Access → Add New Database User, choose password authentication and
pick the built-in role Only read any database (readAnyDatabase). To scope it further, use Specific Privileges
and grant read only on the databases you actually need.
On a self-hosted deployment, use mongosh:
db.getSiblingDB('admin').createUser({
user: 'phone-readonly',
pwd: passwordPrompt(),
roles: [
{ role: 'read', db: 'shop' },
{ role: 'read', db: 'billing' },
],
});
passwordPrompt() keeps the password out of your shell history. Use a long generated password; you
will paste it once into the connection string and store it in the phone’s Keychain.
If you sometimes need to fix data from the phone, create a second user with readWrite on a
single database and keep it as a separate connection, so that “edit mode” is a conscious choice
rather than the default.
2. Allow your phone in without opening the cluster to the world
Atlas only accepts connections from addresses in the project’s IP Access List. Phones move
between Wi-Fi networks and carrier IPs, which tempts people to add 0.0.0.0/0. Better options:
- Temporary entries. Atlas lets you add an IP access entry that expires automatically (within a week at most). When you need to connect, add your phone’s current public IP with a short expiry and forget about cleanup.
- A VPN with a fixed exit IP. Route the phone through a VPN whose exit address never changes, such as a small server you control or a dedicated IP from a VPN provider, and allow only that address. One stable entry, no exposure.
- Private networking. If your cluster is only reachable through peering or a private endpoint, the phone needs a VPN into that network anyway; the same fixed-exit setup applies.
Whatever you choose, keep TLS on (it’s mandatory on Atlas) and verify that a connection from an unlisted network actually fails.
3. Read from a secondary when you can
Most phone checks don’t need the very latest write. Sending them to a secondary keeps load off the primary that serves your application. Add a read preference to the connection string:
mongodb+srv://phone-readonly:<password>@cluster0.example.mongodb.net/?readPreference=secondaryPreferred
secondaryPreferred reads from a secondary and falls back to the primary if none is available.
Secondaries can lag slightly behind, so for “did this write just land?” questions, switch back to
the default primary read.
If your Atlas cluster has analytics nodes, you can isolate ad-hoc reads completely by targeting them with a tag:
?readPreference=secondary&readPreferenceTags=nodeType:ANALYTICS
4. Bound every query
A phone is the worst place to discover that a filter isn’t indexed. A few habits keep queries cheap:
- Filter on indexed fields such as
_id, foreign keys, status plus date, whatever your indexes cover. A filter on an unindexed field over a big collection is a collection scan. - Always use a limit and a projection. You can’t read a thousand documents on a phone anyway.
- Set
maxTimeMSso the server aborts anything that runs too long instead of letting it compete with production traffic. - Prefer estimated counts on large collections.
estimatedDocumentCountreads collection metadata;countDocumentswith a filter has to examine matching documents. - Check the plan of any query you’ll run regularly:
explain()showingCOLLSCANinstead ofIXSCANmeans it needs an index before it belongs on a phone.
5. Make the client part of the safety net
The app you use matters as much as the database settings. Look for a client that:
- stores connection strings in the iOS Keychain, bound to the device and not synced;
- lets you label environments so production looks different from staging;
- has a read-only mode that hides write actions entirely, rather than relying on you to be careful;
- saves only the fields you changed and detects conflicts when you do write, instead of replacing whole documents;
- applies timeouts to every operation, so a weak signal can’t leave a request hanging.
Bussola was designed around this list: production connections open in read-only mode by
default, edits are saved as targeted $set and $unset operations with a conflict check against
the original values, and connection strings never leave the Keychain.
6. Protect the device
Your phone now holds a database credential, so treat it like a laptop with production access:
- a strong passcode and Face ID or Touch ID;
- automatic OS updates;
- Find My enabled, so you can erase it remotely;
- if the phone is lost, rotate the password of the phone user in Atlas or with
db.changeUserPassword(). A dedicated user makes this a two-minute job that doesn’t affect your applications.
7. Keep a trail
Separate users also give you separate trails. On self-hosted MongoDB Enterprise and on dedicated
Atlas tiers you can enable database auditing to record authentication and operations per user;
even without it, logs and Atlas metrics make it easy to see what the phone-readonly user did.
A setup you can copy
| Layer | Setting |
|---|---|
| Database user | Dedicated phone-readonly user with read on specific databases |
| Network | Temporary IP access entries, or a fixed-IP VPN allowed explicitly |
| Connection string | readPreference=secondaryPreferred (or analytics nodes) |
| Queries | Indexed filters, limits, projections, maxTimeMS |
| Client | Keychain storage, read-only mode for production, timeouts |
| Device | Passcode and biometrics, Find My, rotate password if lost |
None of this takes more than half an hour, and it turns “I’ll check when I’m back at my desk” into a safe two-minute look from wherever you are.
Bussola is a free MongoDB client for iPhone: query, edit and aggregate over a direct connection, with no backend.
Coming soon to the App Store