Your app writes a row to the chain on every user action. Profile edits. View counts. A comment. Each one is a signed transaction, a gas estimate, a confirmation wait, and a permanent public record. Your users wait four seconds to save a setting. Your monthly gas bill reads like a payroll line. And somewhere in that ledger is a customer's email address, written in plaintext, immutable, indexed by every block explorer on earth.
This happened because someone decided the product was "on-chain," and on-chain became a religion instead of a tool. Everything went on the chain because going on the chain was the point. Nobody asked which data actually needed the chain's guarantees and which data was just paying chain prices for database problems.
The chain is extraordinary at exactly four things and terrible at almost everything else. Build like you know the difference.
What the chain is actually for
Strip away the marketing and a blockchain gives you a small, expensive, specific set of properties: shared settlement nobody can reverse, ownership that doesn't depend on trusting a server, and verifiability anyone can check without asking you. That's the product. You're renting a global, adversarial, append-only ledger where every write is broadcast, replayed by thousands of machines, and stored forever.
That set of properties is worth paying for when — and only when — your problem is trust between parties who don't trust each other. Settlement of value. Proof of ownership. A record an auditor or a counterparty can verify independently. If two parties need to agree on a fact and neither will accept "because our server says so," the chain earns its cost.
Everything else — speed, privacy, cheap storage, rich queries, flexible logic — the chain is actively bad at. Not mediocre. Bad. A Postgres instance does all of it for a thousandth of the price and a hundredth of the latency.
The four things that genuinely belong on-chain
Settlement. The moment value changes hands and the change must be final. Token transfers, escrow release, payment finality between parties who don't share a backend. This is the chain's home turf. The whole point is that no one — not you, not a hacked admin, not a court order against your server — can quietly reverse it.
Ownership. Who holds what, expressed as state nobody can forge. A token balance, an NFT representing a real asset, a credential bound to an address. The user controls it through their key, not through your permission. Take this off-chain and you've rebuilt a database with extra steps and worse uptime.
Verifiability. Facts a third party must be able to check without trusting you. A commitment hash that proves a document existed at a point in time. A merkle root anchoring a dataset. A public rule — "rewards distribute on this formula" — that anyone can audit by reading the contract. The value is that the proof outlives your company.
Authorization that must be trustless. Rules about who can do what, where "trust the server's auth check" is unacceptable. A multisig that gates a treasury. A contract that only lets the verified owner withdraw. When the access decision itself has to be tamper-proof, it goes on-chain.
That's the list. Settlement, ownership, verifiability, trustless authorization. Notice what's not on it.
What belongs off-chain, every time
Compute. Anything heavier than arithmetic. Matching engines, scoring, search ranking, image processing, anything iterative. The EVM charges you per operation and runs single-threaded across the whole network. A loop that's free on a server can cost dollars on-chain and still time out. Compute off-chain, settle the result on-chain if the result needs settling.
Private data. Emails, names, KYC documents, anything regulated, anything a user would object to seeing on a block explorer. The chain is a global broadcast. "Immutable and public" is the opposite of what GDPR, HIPAA, or basic decency require. Personal data on-chain isn't a feature — it's a breach you can't undo and can't delete.
UX and application state. Drafts, preferences, session data, the half-filled form, the unread count, the thing the user might undo in three seconds. This is high-churn, low-stakes, latency-sensitive state. It belongs in a database where a write is a millisecond and a delete is a delete.
Rich queries and history for display. "Show me this user's last 50 transactions, filtered, sorted, paginated." The chain can't do this — it's a ledger, not a query engine. You index chain events into a normal database off-chain and query that. Reading your own UI from raw chain calls is slow, expensive, and brittle.
The hybrid pattern that actually ships
Real production systems are hybrids. The chain holds the small set of facts that need its guarantees; everything else lives in conventional infrastructure, and the two are stitched together at deliberate seams.
The canonical shape:
./chain
├─ on-chain → the settled fact, the ownership record, the proof commitment
├─ indexer → watches chain events, writes them into your database
├─ database → fast reads, rich queries, private data, application state
└─ app → reads from DB for speed, writes to chain only when it must
The user interacts with a fast app backed by a normal database. The instant something needs to be settled — a purchase finalizes, ownership transfers, a proof is recorded — the app writes that one fact to the chain. An indexer watches for the confirmed event and reflects it back into the database, so your UI stays fast and your source of truth for settled facts stays the chain.
We built our /work/image-provenance system (Sigil, on Polygon) on exactly this line. The image, the metadata, the rich gallery, the user accounts — all off-chain, in a database, fast and private. What went on-chain was the one thing that needed to be unforgeable and independently verifiable: a cryptographic commitment proving a specific image existed at a specific time, anchored where anyone could check it without trusting Sigil's servers. One fact on the chain. Everything else where it's cheap. That's the pattern.
Both failure modes
You can get this wrong in two directions, and both are common.
Too much on-chain. The failure you probably have now. Slow, expensive, and leaking private data into a public, permanent ledger. Every user action is a transaction. The app can't move faster than block time. Personal data is exposed forever. You're paying settlement prices for database work and getting database guarantees nowhere. The fix is subtraction: identify the handful of facts that truly need the chain, move the rest off, and connect them with an indexer.
Too much off-chain. The quieter failure, and sometimes the worse one. The team, burned by gas and latency, retreats — and starts putting settlement in the database too. Now the "on-chain" product has a centralized backend silently deciding who owns what, with a token contract that's mostly decorative. You've kept the costs of crypto and thrown away the guarantees. The moment your server is compromised or your company is gone, the "ownership" your users thought they had evaporates. If the thing that must be trustless depends on your server, it isn't trustless.
The discipline is drawing the line on purpose and defending it. Each piece of state gets one question: does this need the chain's guarantees, or does it just need to work fast and stay private? The answer is usually the database. When it's genuinely the chain, you know exactly why, and you put nothing else up there with it.
What fixed looks like
A fixed system has a written boundary. There's a short, explicit list of what lives on-chain and why each item earns its place — settlement, ownership, a verifiable proof. Everything else is in conventional infrastructure: compute on servers, private data in a database, application state where writes are cheap and deletes are real. An indexer bridges the two, watching confirmed chain events and reflecting them into a queryable store, so the UI reads fast and the chain stays the source of truth for the facts that need it.
The user gets an app that feels like an app — instant, private, responsive — that happens to settle the things that matter on a ledger nobody can forge. Gas costs drop to the handful of writes that justify them. Private data is private because it was never broadcast. And the on-chain facts are clean, minimal, and verifiable, the way a ledger should be.
This is for you if
You're a funded US founder building a real-money on-chain system and the architecture has drifted to one extreme — either everything's on-chain and it's grinding, or settlement quietly slid into a database and the decentralization is theater. You want an engineer to draw the boundary deliberately, design the hybrid, and build the indexer that holds it together. Architecture engagements that redraw an on-chain/off-chain boundary start at $50k+; designing and building the full hybrid system runs $100k+.
This is not for you if you're shipping a memecoin or an NFT art drop where the contract is the whole product and there is no off-chain system to speak of. We build production systems that hold real value and serve real users, where getting the line wrong costs you money, speed, and your users' trust. If your project is the token and nothing behind it, there's no boundary to draw.