KrexelBlogHome

2026-07-14

What changed at Krexel this week

Slower product = no product. Here's everything we shipped over the last four days to make Krexel faster to use, easier to share, and ready for B2B buyers.

This week was an audit week. We rewrote the dashboard cache layer, got hit by a subtle regression, fixed it, and shipped four other audit items in the same deploy cycle.

Here's what landed, with the honest numbers.

The dashboard is 30 % faster

We started the week measuring 1011 ms for the warm /dashboard load. After four days of cache-layer work (and one self-inflicted regression that we caught before it shipped to anyone but ourselves), it's at 708 ms for the same flow.

RouteBeforeAfterΔ
/dashboard1011 ms708 ms−30 %
/keys753 ms636 ms−13 %
/settings/webhooks1523 ms450 ms−70 %
/deploys1526 ms815 ms−47 %

The biggest single win was /settings/webhooks. The honest read is that listWebhooks() was doing its own worker round-trip outside the dashboard's bootstrap cache, which meant every page nav re-fetched the full list even when the data hadn't changed. The fix is the same unstable_cache + revalidateTag pattern we use for the rest of the dashboard — and tag-busting on the create / delete / rotate-secret server actions keeps it fresh when mutations happen.

We shipped a cacheKey regression we want to call out

Around the middle of the week we shipped a cache-key change to /keys and /settings/webhooks that regressed /dashboard from 587 ms to 914 ms in one build. The mistake: the new key triggered a dbGetCustomer per-render that the old key had implicitly short-circuited. We caught it in the end-to-end timing check before any user hit it (CI is good). The fix was wrapping resolveCustomerId in unstable_cache(5min) + React.cache().

We've added it to our internal notes: always re-measure every page that touches a cache layer, not just the one the change was intended for.

Real status feed — for both humans and machines

There's a /status page that has been correctly flagging an outage in our Cloudflare Pages API integration all week. The badge was red; the underlying cause was a Cloudflare token that doesn't have Workers Scripts:Edit on the right account (more on that below).

What's new is /status.json — a machine-readable mirror of the same data. Always returns HTTP 200; the body carries the truth. Aggregate it in UptimeRobot / BetterStack / BetterUptime — you get the full per-check status on every poll.

$ curl https://krexel.com/status.json
{ "ok": false, "checks": { ... }, "version": "...", "ts": "..." }

Every shared link now looks right

Sharing /blog/krexel-vs-vercel on Twitter used to fetch the generic "Krexel" preview. We added proper OpenGraph + Twitter card metadata to every public route — /blog/*, /docs/*, /pricing, /legal/*, /faq, /chatgpt-gpt. Implementation: a lib/marketing-md.ts helper that reads the same frontmatter the body renderer reads, so editing one .md updates title, description, canonical, and the social preview in a single pass.

Two new pages for B2B buyers

Anyone who has ever been mid-procurement and Googled "what's your security page" will recognize why these matter:

  • /legal/security — concrete list of controls (TLS + HSTS preload + bcrypt + KV scoping), sub-processors, vulnerability disclosure channel.
  • /legal/dpa — public summary of the data-processing addendum: SCC modules, retention windows, breach commitment. Enterprise procurement can request a countersigned copy from legal@krexel.com.

We also shipped /docs/api-quickstart — the five-minute, no-dashboard walkthrough of how to get an API key and ship a site. The exact gap was that, until this post, there was no public README for the API for users who came in from a Twitter link rather than from a friend.

Honest caveats

  • /status.json reports ok: false because our stored cloudflare_api_token doesn't have Workers Scripts:Edit on the right Cloudflare account (saadr234@gmail.comb77dbe91…). We don't have a working token with the right scope on hand. Once one is dropped into ~/.cloudflare/credentials, the /readyz upstream check, and therefore /status.json's ok, will flip to green — no code change from us required.
  • The /templates and /usage dashboard pages are stub pages today. They'll stay that way until we know whether to ship them — we'd rather not build them twice.

— Saad