I’m Ujjwal Rupakheti, a full-stack developer in Itahari offering database design and optimization in Nepal. I design PostgreSQL and MySQL schemas for new apps, find and fix slow queries in existing ones, add the right indexes, and set up migrations and backups you can actually restore.
Most products on my work page run on schemas I designed
Measured before and after, on a copy first
Every query parameterised, never joined from strings
Database design is deciding how your data is stored: the tables, relationships, keys and rules that stop bad data getting in. Optimization is making queries on that data fast and cheap as it grows, mostly through better indexes, better queries and fewer round trips between your app and the database.
Design for New Apps
A schema built from how the business works: clear tables, foreign keys, unique rules, money stored as whole numbers and dates stored with their time zone. Designed together with the screens and reports, so nothing needs a workaround later.
Slow pages traced back to the queries behind them, then fixed with the right index, a rewritten query or a small change to the data model. Measured before and after, so you can see the difference for yourself.
Most database problems announce themselves slowly. Pages that were fast at launch get slower every month, reports time out at month-end, and totals stop matching between screens. If two or more of these sound familiar, a review usually pays for itself.
Pages that loaded in under a second at launch now take several seconds.
Reports or exports time out, especially at month-end.
The database server hits full CPU at busy times of day.
Totals differ by a few paisa between screens, a sign of money stored as decimals that round.
Duplicate customers, orders or payments keep appearing.
Nobody has ever restored a backup to check that it works.
Schema changes are made by hand on the live server.
03Slow queries
How I Fix Slow Queries in PostgreSQL and MySQL
By measuring first. I find the few queries that take most of the time, read their plans with EXPLAIN ANALYZE, and change the index, the query or the data model, in that order of preference. Then I measure again and keep a check so the problem doesn’t return.
01
Measure
A day of real traffic with pg_stat_statements or MySQL’s slow query log, ranked by total time.
02
Read the Plan
EXPLAIN ANALYZE shows full scans, bad row estimates, sorts spilling to disk and joins in the wrong order.
03
Index
Composite indexes in the order the query filters, partial indexes for common filters, unused ones removed.
04
Rewrite
N+1 queries from ORMs fixed, only the needed columns selected, OFFSET paging swapped for keyset paging.
05
Change the Model
When a query can’t be fixed, a counter or summary table updated as data changes.
06
Verify
Timings compared on the same data, and a check added so the slow version can’t return.
Before Example plan
Seq Scan on payments
Filter: (provider_txn_id = $1)
Rows Removed by Filter: every other row
After Same query, one index
Index Scan using payments_provider_txn_id_key
Index Cond: (provider_txn_id = $1)
Indexes: Usually the Cheapest Fix
The right index can turn a query that takes seconds into one that takes milliseconds. The wrong ones slow down every insert and update and waste memory, so I add indexes only for queries the logs show are slow, and remove the ones nothing uses.
On a live database I create indexes without locking the table where the database allows it, take a fresh backup first, and run every change as a versioned migration at a quiet time, with a written rollback plan.
04Choosing
PostgreSQL, MySQL or SQLite: Which One?
I default to PostgreSQL for new apps because of its strict constraints, JSON support, full-text search and extensions. I work in MySQL when an app or host already uses it. For a small app on one server, SQLite in WAL mode is often enough, and much simpler to run and back up.
I reach the database through Prisma or Drizzle in TypeScript projects, and through prepared statements in a DAO layer in Java, as in CivicSathy. Every query is parameterised, never built by joining strings.
05Patterns
Database Design Patterns from My Projects
Good database design is mostly small decisions that stop expensive problems later. Each of these solved a specific problem a business would otherwise discover the hard way.
amount_paisa BIGINT
Money as Whole Numbers
HeliGo Nepal stores every amount in paisa. Prices, commissions, refunds and settlements split without rounding errors, so the books always balance.
idempotency_key UNIQUE
Idempotency Keys Stored with Results
In Eknas, each bill carries a key. A retried request finds the stored result and returns it, instead of adding loyalty points twice.
revision INT
Revision Numbers for Safe Sync
In Jhino, every saved item carries a revision number. When two people save at once, the older write is refused and the changes are merged, not overwritten.
draft ≠ published
Drafts Kept Apart from What’s Live
Nimtto autosaves drafts every 0.7 seconds with optimistic versioning, and keeps them separate from the published snapshot guests see.
BS → AD, 1970–2100
Calendar Data with No Room for Error
Pustau converts Bikram Sambat to AD using published month lengths, verified for every day from 1970 to 2100.
haversine(…) < 200 m
Location Queries
CivicSathy warns citizens about similar complaints within about 200 metres, using a Haversine distance query in MySQL.
06Data safety
Backups, Migrations and Data Safety
A backup only counts if you’ve restored it. I set up automatic daily backups with a retention window, test a restore, and run every schema change as a versioned migration so each environment matches.
Backups
Daily, with 14 copies kept (Nimtto, Jhino)
Stored away from the main server
A test restore before launch
Migrations
Versioned and kept in the repository
Run at start-up, applying only what’s new (Jhino)
A rollback plan for every risky change
Privacy
Phones masked to the last three digits (Eknas)
Cashiers see no birthdays (Eknas)
Formulas escaped in CSV exports (Nimtto)
Access
Separate database users for the app and admins
No database port open to the internet
Parameterised queries everywhere
07Process
How a Database Review Works
Four steps, with every change tested on a copy before it touches production. You get a short written report with before-and-after timings at the end.
Collect
Slow-query logs, the schema and table sizes from a normal busy day.
Read-only access
Diagnose
Query plans read and problems ranked by the time they cost.
Worst first
Fix
Indexes, query rewrites and model changes, tested on a copy first.
Versioned migrations
Report
Before-and-after timings, what changed and what to watch next.
In writing
08Pricing
How Much Does Database Optimization Cost in Nepal?
Database design is included in every app I build. A review of an existing database is quoted after I’ve seen the schema and a day of slow-query logs, because the work depends on how many queries need fixing and whether the data model has to change.
How database work is priced, updated November 2026
Project
Price
Timeline
Database review and fixesSlow queries, indexes, a written report
Quoted after a review
Agreed in writing
Migration between databasesFor example MySQL to PostgreSQL, with checks
Quoted per project
Short freeze on writes
SaaS product with its databaseSchema, migrations and backups included
NPR70,000
6–12 weeks
Hosting and backup storage are billed to you directly. Clients abroad are quoted in USD. All prices are on my services page, and the API side is on my API development page.
Keep reading
Related Services and Case Studies
FAQ: Database Design & Optimization in Nepal
Speed, safety, backups and cost, answered before you ask.
Turn on slow query logging, pg_stat_statements in PostgreSQL or the slow query log in MySQL, and let it run through a busy day. In most apps a handful of queries cause most of the load. EXPLAIN ANALYZE on those queries shows whether they scan whole tables, miss an index or return far more rows than the page needs.
How Much Does Database Optimization Cost in Nepal?
Database design is included in every app I build; a SaaS product’s first version starts from NPR 70,000. Optimization of an existing database is quoted after I’ve seen the schema and a day of slow-query logs, because the work depends on how many queries need fixing and whether the data model has to change.
Should I Use PostgreSQL or MySQL?
For a new app I usually choose PostgreSQL, because of its strict constraints, JSON support, full-text search and extensions. MySQL is a sound choice when your app, framework or hosting already uses it. For a small app on one server, SQLite in WAL mode is often enough and much simpler to back up.
Will Adding Indexes Make My App Faster?
The right index can turn a query that takes seconds into one that takes milliseconds. The wrong ones slow down every insert and update and waste memory. I add indexes only for queries the logs show are slow, check the query plan before and after, and remove indexes nothing uses.
Can You Work on a Live Production Database Safely?
Yes. I work on a copy first, take a fresh backup before any change, create indexes without locking tables where the database allows it, and run schema changes as versioned migrations at a quiet time, with a written rollback plan.
What Backups Should My Database Have?
Automatic daily backups, kept for at least two weeks, stored away from the main server, and restored as a test at least once. My own products keep 14 daily copies. A backup that has never been restored shouldn’t be trusted, so the restore test is part of every launch.
How Should I Store Money in a Database?
As whole numbers of the smallest unit, such as paisa, in an integer column, or as a fixed-precision NUMERIC, never as a floating-point number. HeliGo Nepal keeps its whole ledger in paisa, so commissions, refunds and settlements always add up to exactly what the customer paid.
How Much Normalisation Does a Database Need?
Enough that each fact is stored once, so a customer’s phone or a product’s price never disagrees between tables. For most business apps that means a well-normalised core, plus deliberate copies such as counters or summary tables for reports, each with a clear rule for how it stays up to date.
Can You Move My Data from MySQL to PostgreSQL?
Yes, when there’s a clear reason to. I map the types and constraints, move the data with a script that can be re-run, compare row counts and totals, and switch over with a short freeze on writes. Often fixing the slow queries in MySQL is the cheaper answer, and I’ll tell you if it is.
Can You Help with Supabase or a Hosted Database?
Yes. RecruitFlow runs on Supabase for its database, sign-in, file storage and real-time chat, with an admin client used only inside server routes. The same rules apply to any hosted Postgres: careful access policies, indexes driven by real queries, and backups you’ve tested.
Tell Me Where Your Database Hurts. I’ll Measure First.
Send a short note about your app, the database you use and what has become slow. I reply within one working day with questions or a first estimate.