shilpiworksprismaoutagevercelincident-responseinfrastructure

Your Database Is Fine — The Proxy Isn't: A Prisma Data Platform Outage Story

Arun Batchu & Claude (AI)·April 4, 2026·5 min read

The Verdict: If the middleman between your app and your database goes down, your database being healthy doesn't matter. We spent more time confirming "it's not our code" than the outage itself lasted.

We had just deployed a community engagement feature set to Shilpiworks — share buttons, anonymous hearts, a trending strip, and a fresh-from-the-studio feed. The deploy succeeded. The build passed. The migration applied cleanly. Then the products API started returning 500s.

The error: P1001 — Can't reach database server at db.prisma.io:5432.

The Timeline

The sequence matters because it shaped the debugging path:

  1. Deploy completes. Vercel build runs prisma migrate deploy, applies our new product_reactions table. No errors.
  2. Homepage loads fine. Products, collections, images — all there. ISR cache serving the static build.
  3. Products API returns 500. GET /api/products fails consistently. The catch block returns "Failed to fetch products".
  4. First instinct: did we break something? We'd just added a new Prisma model. Maybe a schema issue?
  5. Diff check. git diff on the schema confirms: only an additive CREATE TABLE for product_reactions. No changes to the datasource block, no env var changes, no Product model changes.
  6. Cross-API check. The reactions API — which uses the same prisma client import, same database URL — works fine. Tags API works. Only queries touching the Product table fail.
  7. The actual error. Vercel function logs show P1001: can't reach db.prisma.io:5432. Not a query error. Not a schema error. A network-level connection failure to the Prisma Data Platform proxy.
  8. External confirmation. Prisma had run scheduled maintenance on db.prisma.io two days prior (April 2). The proxy was intermittently dropping connections post-maintenance.
  9. Recovery. The proxy recovered on its own roughly an hour later. No action on our side.

Why the Debugging Was Harder Than It Needed to Be

The confusing part was that some Prisma queries worked and others didn't. The reactions API returned {} (empty, correct). The tags API returned full tag lists. Only product.findMany() — which returns 600+ rows with large JSON features fields — failed consistently.

Key point: An intermittent proxy failure doesn't affect all queries equally. Lightweight queries may succeed while heavier queries time out or get dropped. This makes it look like a code problem when it's an infrastructure problem.

The second confusing signal: the homepage still showed products. That's ISR doing its job — the page was pre-rendered at build time and served from Vercel's edge cache. The live API route was broken, but cached pages were fine. For visitors, the site never went visually down.

The Architectural Debt

Here's the deeper issue. Every connection string in our frontend — DATABASE_URL, POSTGRES_URL, RESTORED_DATABASE_URL — routes through db.prisma.io. This is Prisma's Data Platform proxy, a deprecated product that Prisma replaced with Accelerate (a paid service).

The proxy sits between every serverless function and the actual database. When it's healthy, the overhead is minimal. When it's not, the entire application goes dark for any non-cached request — even though the database itself is fine.

This is the same db.prisma.io proxy that was involved in the February 2026 database wipe. That incident taught us never to run raw SQL through the proxy. This incident taught us something more fundamental: we shouldn't be routing production traffic through a deprecated third-party proxy at all.

What Saved Us

  • ISR caching with revalidate = 60. The homepage, product pages, collections, and /fresh feed all served from Vercel's edge cache. Visitors saw a working site throughout the outage.
  • Silent failure patterns. Tracking endpoints (/api/track/view, /api/track/share) use fire-and-forget fetch calls that swallow errors. Hearts and share buttons degraded gracefully — they just didn't register.
  • The trending strip handled it. getTrendingProducts() wraps both queries in try-catch and returns an empty array on failure. The homepage rendered without a trending section instead of crashing.

What We're Doing About It

The fix is architectural, not tactical. We need to remove db.prisma.io from the connection path and connect directly to the Vercel-hosted Postgres instance with its native connection pooler.

| Current | Target | |---------|--------| | postgres://...@db.prisma.io:5432 | postgres://...@[vercel-pooler] | | Deprecated Prisma proxy | Vercel-native PgBouncer | | Single point of failure | Same uptime as the database |

This is now tracked in our tech debt register. The migration is low-risk — the Prisma schema just needs a different url value — but it requires verifying the direct connection string from Vercel's dashboard and testing against the full query surface.

Key Lesson: A proxy in front of your database is a convenience until it becomes a liability. If the proxy vendor is deprecating the product, that liability is growing, not shrinking. Remove the middleman before the next outage makes the decision for you.