You finally have real users and real transactions, and now someone — a co-founder, an investor, the ops lead who lives in spreadsheets — wants a dashboard. Not the traffic charts in Base44's Analytics tab, but the actual business picture: revenue by plan this month, signups by week, which plan is converting, where money is leaking. You open the dashboard expecting a reporting tab and find visits, pages and Stripe payment totals, but nothing that reads your own entities. That gap is the moment this guide is written for.
Building a reporting dashboard in Base44 means computing your own business metrics, because the platform's analytics cover traffic and Stripe payments, not the data in your entities. The reliable pattern is server-side math with the SDK's count() and aggregate(), KPI cards and charts that read those results, an optional scheduled summary entity for heavy or historical metrics, and a server-side function for Excel and PDF export. Simple team dashboards are DIY-friendly; stakeholder-grade reporting with drill-downs is a build.
What "Reporting" Means Beyond Base44's Built-Ins
There is a recurring confusion worth clearing up first, because it sends people down the wrong path. Base44 does have analytics, and the founders who tell me "I thought it had reporting" are not wrong — they found the traffic report, not the business report. The Analytics tab shows "how many people visit, which pages they view, where they come from, and how often they complete key actions like sign-ups or button clicks", and its Sales Overview shows payments processed through Stripe (Base44 analytics docs, read 17 Oct 2026). That is genuinely useful. It tells you nothing about the records in your own entities: which plan converts, which rep closes, which cohort churns. It also keeps 60 days of history, so year-over-year reporting needs your own data. Traffic analytics and business reporting are two different products that happen to live behind a similar-looking chart.
So when a stakeholder asks for "the numbers," they mean your domain data — orders, subscriptions, leads, sessions, whatever your entities model. Surfacing that is an application feature you build, not a setting you toggle. And it is squarely the kind of thing Base44 does well, because a reporting dashboard is an internal tool by nature: the viewers are trusted, traffic is low, and nobody is trying to rank it in Google. The hard part is never the platform fit. It is the data plumbing underneath, which is where the database design choices we cover separately start to matter a great deal.
Two facts shape every decision here. First, the math belongs on the server, and the SDK now does it there. count() "Counts the records that match a query" without fetching them, and aggregate() "Computes counts, sums, averages, minimums, maximums or distinct counts, grouped by fields": up to four group-by fields or a date bucket, and up to 1,000 result rows (SDK reference, read 17 Oct 2026). So "what was total revenue per rep this month" is one query, not a nightly job. Second, there is still no SQL and no JOIN, and list reads are capped at 5,000 records per request as of November 2025, so anything that crosses entities or needs raw rows is work you do in code. Ignoring either fact is what makes a DIY dashboard crawl or break the moment real data lands.
KPI Cards, Charts, and Drill-Downs That Work
The pattern we apply on every dashboard we ship comes down to one principle: never compute metrics in the browser. Let the server count and sum, store only what is worth storing, and keep every read the dashboard makes small. I call the layers below the four reporting tiers, and a healthy Base44 dashboard uses all four in order.
The first tier is the metrics layer: the queries that turn raw records into numbers. For most dashboards that is a handful of aggregate() calls, in the shape of Base44's own examples:
import { base44 } from "@/api/base44Client";
// Sales per agent this month, biggest first
const { rows } = await base44.entities.Sale.aggregate({
query: { sale_date: { $gte: "2026-09-01" } },
groupBy: "agent_id",
sum: "amount",
sort: "-sum_amount",
});
// rows: [
// { agent_id: "a1", count: 42, sum_amount: 18250 },
// { agent_id: "a2", count: 37, sum_amount: 15400 },
// ...
// ]
// Orders per day, for a trend line
const { rows: perDay } = await base44.entities.Order.aggregate({
dateBucket: { field: "created_date", unit: "day" },
});
// perDay: [{ created_date: "2026-09-01", count: 8 }, ...]
The server "groups the records you can read", so the same call respects each viewer's access rules. Add a summary entity only where it pays: an entity — call it DailyMetrics — with one row per day (or per week, per cohort, whatever your reporting grain is), written nightly by a backend function on a scheduled automation that runs the same aggregate() calls. It earns its place for metrics every page load reads, for groupings past the 1,000-row cap, and for numbers you want frozen as they stood on each day.
The second tier is KPI cards — the big-number tiles at the top (total revenue, MRR, active users, conversion rate). Each card is one count() or aggregate() result, or one field from the latest summary row, shown with a delta versus the prior period. Because the server does the math, cards stay fast as the data grows. This is the part founders can absolutely build themselves.
The third tier is charts. Add a charting library as an npm dependency — Recharts and Chart.js both work well inside Base44's React environment — and feed it grouped rows, not raw records. A revenue line chart is thirty grouped rows, not thirty thousand orders. This is the core of building base44 custom analytics charts: the chart library is the easy part; the server-side aggregation that keeps reads fast is the load-bearing part.
The fourth tier is drill-downs, and this is where DIY usually stops and a developer starts. A drill-down lets a stakeholder click "March revenue" and see the underlying transactions, then filter by plan, region, or rep. That requires querying raw records on demand, paginating around the 5,000-record cap, joining across entities in application code (because the database won't), and keeping it fast. Drill-downs are real engineering, not a chart-library config.
| Reporting tier | What it shows | Data source | DIY difficulty |
|---|---|---|---|
| Metrics layer | Server-side totals and grouped KPIs | count() and aggregate(), plus an optional scheduled summary entity | Medium — short queries; the summary job needs a backend function + schedule |
| KPI cards | Big-number tiles with deltas | count() / aggregate() results or the latest summary row | Low — founder-friendly |
| Charts | Trends over time | Grouped rows (date buckets) | Medium — library + clean data |
| Drill-downs | Click-through to underlying records | Live paginated raw queries | Very high — usually hired out |
Where Base44 Reporting Still Hits Limits
Even with the right architecture, there are four walls a Base44 reporting project meets. Naming them up front saves weeks, because each one has a known workaround and trying to brute-force past them with raw queries is exactly what produces a slow, broken dashboard.
The first wall is the 1,000-group ceiling. aggregate() returns "one row per group, up to 1,000 rows", and its result sets truncated to true when more groups exist (SDK reference, read 17 Oct 2026). A report grouped by customer across a large customer base needs narrower queries or a stored summary, and a dashboard should check truncated rather than show a silently partial table. The second wall is the 5,000-record list cap. Any report that needs to touch more than 5,000 rows — a full-year transaction export, a cohort analysis across your whole user base — must paginate in a backend function and assemble results server-side. Do that in the browser and you will hit the cap, time out, or quietly show wrong totals. We dig into the mechanics of this in the Base44 performance optimization guide.
The third issue is freshness. A stored summary is yesterday's truth, so compute live cards such as "revenue so far today" on demand with aggregate(), or keep a rollup current with an entity event automation that runs when an order is created. Base44's automations docs warn that "Entity automations only fire for single-record create, update, and delete calls", so a rollup fed that way needs a recount after any bulkUpdate() or updateMany() write. The fourth wall is cross-entity reporting. Joining orders to customers to plans for a single report means listing each entity and merging in code, because there are no JOINs. For two entities that is manageable; for a five-way join feeding a finance report, it is the kind of work that takes an engineer a day to get right and fast.
None of these walls means Base44 is the wrong tool. They mean reporting on Base44 is a build, not a feature you enable — and a build with a well-known shape, which is exactly why our team can quote it confidently.
Exporting Reports to Excel and PDF
Export is the request that turns a "nice internal dashboard" into something stakeholders treat as official, and it is where homemade dashboards fall short. When founders ask how to do base44 export reports excel pdf the right way, the rule that matters is this: real export runs server-side in a backend function, not in the browser. The browser can fake it, but the output is fragile.
For Excel, the temptation is to dump a CSV from a client-side button. CSV is fine for handing raw data to an analyst, but it loses number formatting, multiple tabs, formulas, and column widths — everything that makes a report look like a report. For anything a stakeholder will file or forward, generate a true .xlsx server-side with a library like exceljs: one tab of summary KPIs, one tab of detail rows, formatted and ready. The backend function paginates around the 5,000-record cap, builds the workbook, and returns it as a download.
For PDF, client-side print-to-PDF (the browser's own print dialog) is acceptable for a quick "screenshot the dashboard" share, but it breaks across page boundaries, can't paginate a long table cleanly, and looks different on every machine. A board-ready PDF is rendered from an HTML report template and converted server-side with a headless-Chrome service or a library like Puppeteer or pdfmake. That gives you consistent branding, page numbers, a cover summary, and tables that actually fit. This is the same export discipline we apply when we build internal tools on Base44, where "send the monthly report to the board" is a hard requirement, not a nice-to-have.
| Export need | Quick DIY approach | Stakeholder-grade approach |
|---|---|---|
| Raw data dump | Client-side CSV button | Server-side .xlsx with formatted tabs (exceljs) |
| Formatted spreadsheet | Not reliably possible client-side | Backend function builds multi-tab workbook |
| One-off PDF share | Browser print-to-PDF | HTML template + Puppeteer/pdfmake server-side |
| Scheduled report email | Not possible client-side | Backend function generates + emails on a schedule |
The last row is the easy one to miss: a scheduled export — "email the board a PDF every Monday at 8am" — is impossible from the browser entirely. It needs a backend function run by a scheduled automation, the same scheduling muscle that refreshes a summary entity. Build one well and the other comes nearly for free.
DIY Dashboard vs Hiring It Out
Here is the honest decision framework, because plenty of reporting dashboards on Base44 should be built by the founder, not bought. The dividing line is consequences: does a wrong number on this dashboard cost real money or credibility? A dashboard your own team eyeballs to spot-check the week can be wrong by a row and nobody is harmed. A board deck or an investor update built on the same numbers cannot.
KPI cards and a couple of charts over one or two entities, read by your internal team, are firmly in DIY territory — Base44's AI builder will get you most of the way, and the count() and aggregate() pattern above is learnable in an afternoon. You cross into hire-it-out territory when you need multi-entity drill-downs, the 5,000-record cap starts truncating your reports, you need role-gated financial views (an investor sees revenue, an ops lead sees fulfillment, and never the reverse), or stakeholders depend on scheduled exports that simply cannot fail.
| Dashboard scope | Audience | Recommendation | Typical cost |
|---|---|---|---|
| KPI cards + 2-3 charts, one entity | Internal team | DIY with count() and aggregate() | Your time |
| Multi-entity charts, basic export | Internal + occasional sharing | DIY core, hire for export plumbing | Fix sprint from $1,500 |
| Drill-downs, role-gated views, Excel/PDF | Stakeholders / board | Standard build | Around $9,000 |
| Real-time financial reporting at scale | Finance / regulated | Premium build | From $15,000 |
If you have a half-working dashboard that's slow or showing wrong totals, that is a bug-fix problem, not a rebuild — our fixed-price fix sprints from $1,500 cover exactly the "my charts time out" and "my export is missing rows" class of issue. If you're starting from a blank reporting tab and the audience is stakeholders, it's a build. As the lead engineer at Base44Devs, the call I make on a discovery call comes down to that consequences test, not to how technical the founder is.
Have Us Build a Stakeholder-Ready Dashboard
If the numbers on this dashboard are going in front of a board, an investor, or a buyer, this is the work we do. A board-ready base44 kpi dashboard for stakeholders is exactly what a standard build from our team at around $9,000 delivers, with the full reporting stack: the scheduled summary-entity pipeline so your dashboard stays fast at scale, KPI cards and charts wired to clean pre-computed data, the multi-entity drill-downs that the database won't give you for free, role-gated views so each stakeholder sees only their numbers, and server-side Excel and PDF export — including the scheduled "email the board every Monday" report. Leaner, single-team scopes can start from an MVP build at $4,500; real-time financial reporting at scale moves into premium territory from $15,000.
If you already have a dashboard and just need to know whether it's trustworthy, start with a $497 production audit. We pressure-test the numbers, check whether your queries are quietly hitting the 5,000-record cap, and hand you a written verdict on what's safe and what's lying to you. If we find a critical issue, the audit fee credits against any build engagement, and it's backed by our money-back guarantee. The fastest way to get a straight answer is to tell us what your stakeholders need to see — we'll tell you exactly which row of the tables above you're in.
Related reading
- Base44 database best practices — the entity and query patterns that make server-side reporting possible at scale.
- Base44 performance optimization guide — why adding up records in the browser slows a dashboard down and how to keep reads fast.
- Base44 for internal tools — why dashboards and admin panels are exactly where Base44 shines.
- Standard and premium builds — what our team ships at each tier and what a stakeholder-grade dashboard costs.
- Fixed-price fix sprints — for when a dashboard already exists but the charts time out or the export drops rows.
- Finish my half-built Base44 app — for the half-working reporting tab that stalled before the data plumbing was done.