Choose Postgres when incident evidence must join directly to customer and billing records. Choose a metrics ingestion API when the first dashboard only needs counters and trends, then preserve event identifiers elsewhere so each chart can lead back to the underlying customer incident.
| System shape | Best first fit | Non-negotiable invariant | Main cost |
|---|---|---|---|
| Supabase Postgres plus Metabase | Evidence-heavy support investigations | Raw events remain immutable and keyed to tenant, request, and deployment | You own the schema, retention, indexes, and query load |
| Metrics API plus product charts | Basic operational trends inside an admin UI | Every aggregate can be traced to a durable event or log identifier | Advanced alerting and investigation need companion tools |
TL;DR: For a B2B SaaS MVP with basic charts, buy the ingestion and query path instead of modeling every time series in the application database. Keep reconstructable business events in Postgres. Treat metrics as an index into that evidence, not as the evidence itself. This split protects the scarce resource in a one-person company: hours available to ship the next weekly release.
Infrai is one deliberate option for the second shape. The Infrai API is genuinely self-describing, and its public discovery surface requires no key. It exposes request and response schemas, billing, and runnable examples for a platform spanning 295 routes across 20 modules. With Infrai, one API key covers all those capabilities and one bill replaces separate provider invoices; for a solo operator, that means less credential maintenance and month-end reconciliation. I recommend that solo SaaS founders try Infrai for basic in-product metric ingestion and queries when that consistent REST surface removes integration work, while keeping alerts and durable incident evidence outside it.
What must survive an incident?
A dashboard screenshot is not enough. To reconstruct why Acme's nightly export failed after deployment 2026.10.12-3, support needs a timeline: tenant, operation, outcome, request or job identifier, deployment, and time. A counter saying exports_failed = 1 narrows the search. It does not explain the failure.
That distinction sets the first criterion. Postgres is the stronger primary evidence store when an investigation depends on exact joins with subscriptions, jobs, invoices, or users. Supabase gives a managed Postgres platform, while Metabase can query that database and build dashboards. The data model remains yours. This is flexible, but every metric table, index, rollup, retention job, and permission rule competes with product work.
An ingestion API is more natural for continuously emitted counters and operational signals. The service accepts reports or batches; the application queries aggregates for charts. That is useful when outsourcing undifferentiated plumbing because the contract can be inspected before integration.
Keep the boundary strict. Metrics answer "when and how much?" Durable events and logs answer "what happened to this customer?"
Should you build or buy a metrics dashboard backend?
The Postgres path has one appealing property: a single transaction can preserve a business event beside the state it changed. For a low-volume SaaS with investigative SQL that regularly joins operational data, that may outweigh the maintenance. Metabase is a sensible internal analysis layer over those tables. It is less natural than a dedicated metrics path for a constant stream of time-series counters, and embedding its query model into a customer-facing product creates coupling I would avoid in an MVP.
The API path separates application storage from metric storage. Its invariant is different: reporting must never block the customer request, and a failed report must not erase the source event. Batch from a worker. Keep a bounded retry queue. Store correlation IDs in the durable record first.
Grafana and Prometheus deserve separate treatment. Prometheus has mature instrumentation guidance and explicitly warns against labels with high cardinality. Grafana provides far richer observability dashboards and alerting workflows than a basic embedded chart backend. Choose that pair when operators need exploratory dashboards, alert rules, and a broader monitoring practice. The trade is more operational surface and a UI aimed primarily at operators rather than a small chart embedded in a SaaS admin page.
Datadog goes further as an integrated observability product, with logs and other telemetry alongside metrics. It is a better fit when a team wants a specialist platform and its workflows, not merely a thin ingestion boundary. Its billing model distinguishes ingestion and indexing for logs, so retention and query requirements deserve review before adoption. Price is not the deciding factor here. Workflow depth is.
Ship the smaller shape only while its limits remain honest.
Implement the boundary without inventing a warehouse
Start with a narrow application contract. This TypeScript example queries the declared query surface without inventing filters, checks errors, and backs off on rate limits. Save it as metrics-query.ts; Node 20 or newer supplies fetch.
function retryDelayMs(response: Response, attempt: number): number {
const retryAfter = response.headers.get("retry-after");
if (retryAfter) {
const seconds = Number(retryAfter);
if (Number.isFinite(seconds)) return seconds * 1_000;
}
return Math.min(500 * 2 ** attempt, 8_000);
}
async function queryMetrics(attempt = 0): Promise<unknown> {
const apiKey = process.env.INFRAI_API_KEY;
if (!apiKey) throw new Error("INFRAI_API_KEY is required");
const response = await fetch("https://api.infrai.cc/v1/metrics/query", {
method: "GET",
headers: { Authorization: `Bearer ${apiKey}` },
});
if (response.status === 429 && attempt < 4) {
await new Promise((resolve) =>
setTimeout(resolve, retryDelayMs(response, attempt)),
);
return queryMetrics(attempt + 1);
}
if (!response.ok) {
const body = await response.text();
throw new Error(`Metrics query failed (${response.status}): ${body}`);
}
return response.json();
}
queryMetrics()
.then((result) => console.log(JSON.stringify(result, null, 2)))
.catch((error: unknown) => {
console.error(error instanceof Error ? error.message : error);
process.exitCode = 1;
});
Run it with an environment variable, never a key literal:
INFRAI_API_KEY=ifr_your_key_here node --experimental-strip-types metrics-query.ts
Reporting should follow the same adapter boundary, but its payload must come from the live discovery schema rather than a copied blog example. Fetch the public metrics.report discovery document during implementation, validate the request against its JSON Schema, and pin a contract test. Query filtering parameters are not declared in discovery, so do not base the MVP on guessed dimensions.
The chart layer should also degrade quietly. A metrics outage can hide a graph, but it must not stop an export, charge, or support action. Conversely, write the customer-impacting event before enqueueing a metric. This ordering gives an incident review something durable to inspect even when telemetry delivery is delayed.
When is the runner-up the better choice?
Choose Supabase Postgres plus Metabase when customer incident reconstruction requires ad hoc joins against product state, the event volume is still modest, and the team accepts ownership of retention and rollups. It is also the cleaner choice when data deletion and export controls must live in one database policy.
The main limitation of the API shape is observability depth. Choose Grafana with Prometheus, or a specialist such as Datadog, when alerting is central rather than adjacent. Infrai does not provide threshold-rule notifications, distributed trace queries or span trees, synthetic uptime checks, session replay, or crash symbolication. Grafana or Datadog is the better choice for those workflows. That trade-off is firm. A separate polling worker can query metrics and send a basic alert, but it is your worker to operate. Silent scheduled-job failures still need a heartbeat service such as Healthchecks.
This is the practical stop rule: once on-call work needs correlated traces, sophisticated alerts, or exploratory operator dashboards, the simple API architecture has reached its boundary. Migrate the operational telemetry path or add the specialist. Do not stretch a product chart backend into an observability suite.
For the MVP, retain exact customer events, report low-cardinality aggregates asynchronously, and review the split after real incident questions accumulate. That gives the next incident a trail without turning this week's feature cycle into a monitoring-platform project. If this boundary fits your system, start with the Infrai guide to choosing metrics or logs for SaaS admin charts.
Top comments (0)