Skip to content
CertScore logoCertScore

Engineering

The 7 seconds we missed

·By Rajat Ravinder Varuni, Founder

A follow-up. Five days ago we published From 17 minutes to 2 minutes, a writeup of seven backend patterns we shipped at CertScore to make bulk credential imports six times faster. Yesterday it hit the front page of Hacker News. Twenty-four hours after that, our first organic signup from the post arrived. Call him User C. He pasted his Credly profile URL at 15:56 UTC and waited.

His full signup-to-first-verified-credential time was three minutes and fifty-one seconds, well inside the “good” band the previous post described. But one event-pair stood out in his audit log:

Time (UTC)Event
16:00:28add_cert.submitted
16:00:38import.credly.complete

A 9.9-second gap between submit and the server confirming the import was complete. The previous post had implied a one-badge Credly import should take one to two seconds. So why 9.9?

The cold-start tax

Supabase Edge Functions run on a Deno runtime. Workers persist for a short window (typically five to fifteen minutes) after the last invocation. After that, the worker shuts down. When the next request arrives, the runtime has to:

  1. Cold-start a fresh worker process
  2. Load and parse all the function’s modules
  3. Warm up the JIT for the hot path

That total is roughly one to three seconds of pure setup overhead, on top of the actual function work (fetching the Credly profile, computing SHA-256 ownership hashes, writing to Postgres).

When we ran the benchmarks for the previous post, our test users were hitting warm workers, because we were testing actively. The previous post’s sub-second one-badge-import claim was true, but only on the warm path. On the cold path it was closer to seven to ten seconds.

The post measured. The post was honest. The post was also missing this entire failure mode, because we’d never watched a real user land at an off-peak hour from a different region than ours.

The fix, in four lines

Two parts. First, a short-circuit at the top of each user-facing edge function’s serve() handler:

ts
serve(async (req) => {
  // Keep-warm ping from pg_cron. Short-circuit before any real work.
  if (new URL(req.url).searchParams.get("warmup") === "1") {
    return new Response("ok", { status: 200 });
  }
  // ... rest of the function
});

The warmup branch fires before any auth check, body parsing, DB connection, or external API call. It runs the worker’s serve() loop just long enough to keep the process alive, which is the whole point.

Second, a pg_cron job that hits each function every five minutes:

sql
SELECT cron.schedule(
  'keep-warm-user-facing',
  '*/5 * * * *',
  $$
  SELECT net.http_get(url := 'https://<project>.supabase.co/functions/v1/import-credly-profile?warmup=1');
  SELECT net.http_get(url := 'https://<project>.supabase.co/functions/v1/import-credential-net-profile?warmup=1');
  SELECT net.http_get(url := 'https://<project>.supabase.co/functions/v1/verify-credly?warmup=1');
  SELECT net.http_get(url := 'https://<project>.supabase.co/functions/v1/verify-accredible?warmup=1');
  SELECT net.http_get(url := 'https://<project>.supabase.co/functions/v1/process-credential?warmup=1');
  SELECT net.http_get(url := 'https://<project>.supabase.co/functions/v1/certscore-ai?warmup=1');
  $$
);

That is the whole infrastructure change.

The before-and-after

We tested by deleting our own Credly-imported credential and re-adding it via Credly profile URL. The function being measured is import-credly-profile. The wall-clock gap between add_cert.submitted and import.credly.complete:

PathScenarioWall time
Cold (User C, 1 badge)New user, off-peak hour, cold worker9.9 sec
Warm (our dogfood, 10 badges)Worker pre-pinged by cron, multi-badge profile2.73 sec

Ten times the workload completed in roughly a quarter of the wall time. That is per-cert latency dropping from 9.9 seconds to 0.27 seconds, a 36x improvement over what User C experienced.

The compute work in both cases is identical: fetch the profile, fetch each badge’s OBI assertion, compute SHA-256 ownership hash, write to the database. The optimizations from the previous post (Promise.all, INSERT ON CONFLICT, statement-level triggers) handle the load scaling. Keep-warm removes the cold-start tax that the previous post never measured.

Cost

Six functions, pinged every five minutes, thirty days a month: 51,840 invocations per month. Supabase’s PRO plan includes two million edge function invocations per month. The keep-warm budget is 2.6 percent of the included tier. The marginal dollar cost of this fix is zero.

When to use this

Keep-warm helps only for functions where a user is synchronously waiting on the response. For CertScore that means profile import, single-badge verification, AI extraction from PDFs, and the LLM chat. We did not keep-warm:

  • Cron-driven internal functions (already warm from their own schedules)
  • Rarely-called functions (account deletion, content moderation triggers, rare report submissions)
  • Async pipeline tasks (audit-to-Slack, notification sends, daily metrics aggregations)

Keep-warming a function that never blocks a user is duplicative noise. The math only works if you save user-perceived seconds.

The bigger lesson

Synthetic benchmarks miss cold-start corner cases. Internal teams test warm paths because they’re testing actively. Real users land on cold paths because they’re new, in a different time zone, at a different hour of the day.

The only way to know what hurts is to watch real users. We have an audit_log table that records every significant action with a timestamp. Five days after publishing a blog post that promised sub-second one-badge imports, we ran one SQL query on User C’s timeline, saw a 9.9-second gap that contradicted the claim, and had a fix shipped within an hour.

If you are running a similar platform: add a last_seen_at column. Trigger it on every audit event insert. Pull one real user’s timeline a day. You will find the next thing your synthetic benchmarks did not.


The four-line warmup short-circuit plus the pg_cron job is the entire intervention. It shipped on 2026-05-13 at roughly 22:15 UTC. We tested it against our own credential at 22:11 UTC and confirmed the new wall time. The workers are now kept warm twenty-four hours a day at zero marginal cost, so the next User C from a different time zone does not have to wait 9.9 seconds to find out our platform exists.

CertScore is the platform behind these numbers. Your IT certifications, verified at the issuer, ranked globally.

Try it free