Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 5 additions & 20 deletions packages/app/src/components/submissions/SubmissionsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,7 @@ function DetailItem({
);
}

type SortKey =
| 'hardware'
| 'model'
| 'precision'
| 'framework'
| 'latest_date'
| 'total_datapoints';
type SortKey = 'hardware' | 'model' | 'precision' | 'framework' | 'date' | 'total_datapoints';
type SortDir = 'asc' | 'desc';

interface SubmissionsTableProps {
Expand All @@ -62,7 +56,7 @@ function getModelDisplayName(dbModel: string): string {
}

export default function SubmissionsTable({ data }: SubmissionsTableProps) {
const [sortKey, setSortKey] = useState<SortKey>('latest_date');
const [sortKey, setSortKey] = useState<SortKey>('date');
const [sortDir, setSortDir] = useState<SortDir>('desc');
const [search, setSearch] = useState('');
const [expandedRows, setExpandedRows] = useState<Set<string>>(new Set());
Expand Down Expand Up @@ -119,7 +113,7 @@ export default function SubmissionsTable({ data }: SubmissionsTableProps) {
}, []);

const rowKey = (row: SubmissionSummaryRow) =>
`${row.model}_${row.hardware}_${row.framework}_${row.precision}_${row.spec_method}_${row.disagg}_${row.is_multinode}_${row.num_prefill_gpu}_${row.num_decode_gpu}_${row.prefill_tp}_${row.prefill_ep}_${row.decode_tp}_${row.decode_ep}`;
`${row.model}_${row.hardware}_${row.framework}_${row.precision}_${row.spec_method}_${row.disagg}_${row.is_multinode}_${row.num_prefill_gpu}_${row.num_decode_gpu}_${row.prefill_tp}_${row.prefill_ep}_${row.decode_tp}_${row.decode_ep}_${row.date}`;

const SortHeader = ({ label, field }: { label: string; field: SortKey }) => (
<th
Expand Down Expand Up @@ -156,7 +150,7 @@ export default function SubmissionsTable({ data }: SubmissionsTableProps) {
<SortHeader label="Model" field="model" />
<SortHeader label="Precision" field="precision" />
<SortHeader label="Framework" field="framework" />
<SortHeader label="Latest Run" field="latest_date" />
<SortHeader label="Date" field="date" />
<SortHeader label="Datapoints" field="total_datapoints" />
</tr>
</thead>
Expand Down Expand Up @@ -219,7 +213,7 @@ function SubmissionRow({
<td className="px-3 py-2">{getModelDisplayName(row.model)}</td>
<td className="px-3 py-2 uppercase">{row.precision}</td>
<td className="px-3 py-2">{getFrameworkLabel(row.framework)}</td>
<td className="px-3 py-2 tabular-nums">{row.latest_date}</td>
<td className="px-3 py-2 tabular-nums">{row.date}</td>
<td className="px-3 py-2 tabular-nums">{row.total_datapoints.toLocaleString()}</td>
</tr>
{isExpanded && (
Expand All @@ -231,15 +225,6 @@ function SubmissionRow({
<DetailItem label="Vendor:" tip="GPU manufacturer">
{vendor}
</DetailItem>
<DetailItem label="First Run:" tip="Date of the earliest benchmark for this config">
<span className="tabular-nums">{row.first_date}</span>
</DetailItem>
<DetailItem
label="Run Days:"
tip="Number of distinct days this config was benchmarked"
>
<span className="tabular-nums">{row.run_days}</span>
</DetailItem>
<DetailItem
label="Spec Method:"
tip="Speculative decoding method (e.g. MTP, Eagle)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,7 @@ describe('computeTotalStats', () => {
prefill_ep: 1,
decode_tp: 4,
decode_ep: 1,
first_date: '2026-01-01',
latest_date: '2026-01-10',
run_days: 10,
date: '2026-01-10',
total_datapoints: 100,
distinct_sequences: 3,
distinct_concurrencies: 10,
Expand All @@ -117,9 +115,7 @@ describe('computeTotalStats', () => {
prefill_ep: 1,
decode_tp: 8,
decode_ep: 1,
first_date: '2026-01-05',
latest_date: '2026-01-10',
run_days: 5,
date: '2026-01-05',
total_datapoints: 50,
distinct_sequences: 2,
distinct_concurrencies: 5,
Expand Down
6 changes: 5 additions & 1 deletion packages/app/src/components/submissions/submissions-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,18 +93,22 @@ export function computeCumulative(volume: SubmissionVolumeRow[]): CumulativePoin
/** Compute total stats from summary rows. */
export function computeTotalStats(summary: SubmissionSummaryRow[]) {
let totalDatapoints = 0;
const configs = new Set<string>();
const models = new Set<string>();
const gpus = new Set<string>();

for (const row of summary) {
totalDatapoints += row.total_datapoints;
configs.add(
`${row.model}_${row.hardware}_${row.framework}_${row.precision}_${row.spec_method}_${row.disagg}_${row.num_prefill_gpu}_${row.num_decode_gpu}`,
);
models.add(row.model);
gpus.add(row.hardware);
}

return {
totalDatapoints,
totalConfigs: summary.length,
totalConfigs: configs.size,
uniqueModels: models.size,
uniqueGpus: gpus.size,
};
Expand Down
4 changes: 2 additions & 2 deletions packages/app/src/lib/api-cache.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,9 @@ describe('purgeAll', () => {
});

describe('cachedJson', () => {
it('sets Cache-Control with max-age=0 and 1 year s-maxage', () => {
it('sets Cache-Control with max-age=0 and 1 day s-maxage', () => {
const res = cachedJson({ ok: true });
expect(res.headers.get('Cache-Control')).toBe('public, max-age=0, s-maxage=31536000');
expect(res.headers.get('Cache-Control')).toBe('public, max-age=0, s-maxage=86400');
});

it('sets Vercel-Cache-Tag to db', () => {
Expand Down
4 changes: 2 additions & 2 deletions packages/app/src/lib/api-cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ export async function purgeAll(): Promise<number> {
return deleted;
}

/** 1 year — Vercel max. Purged on demand via revalidateTag('db'), no TTL needed. */
/** 1 day. Purged on demand via revalidateTag('db'). */
const CDN_HEADERS = {
'Cache-Control': 'public, max-age=0, s-maxage=31536000',
'Cache-Control': 'public, max-age=0, s-maxage=86400',
'Vercel-Cache-Tag': 'db',
};

Expand Down
4 changes: 1 addition & 3 deletions packages/app/src/lib/submissions-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ export interface SubmissionSummaryRow {
prefill_ep: number;
decode_tp: number;
decode_ep: number;
first_date: string;
latest_date: string;
run_days: number;
date: string;
total_datapoints: number;
distinct_sequences: number;
distinct_concurrencies: number;
Expand Down
49 changes: 30 additions & 19 deletions packages/db/src/queries/submissions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ export interface SubmissionSummaryRow {
precision: string;
spec_method: string;
disagg: boolean;
is_multinode: boolean;
num_prefill_gpu: number;
num_decode_gpu: number;
prefill_tp: number;
prefill_ep: number;
decode_tp: number;
decode_ep: number;
date: string;
total_datapoints: number;
distinct_sequences: number;
distinct_concurrencies: number;
max_concurrency: number;
Expand All @@ -19,8 +28,8 @@ export interface SubmissionVolumeRow {
datapoints: number;
}

/** Get unique config submissions with first/latest date and datapoint counts.
* Uses latest_benchmarks (deduplicated: newest per config+conc+isl+osl, no errors). */
/** Get per-run config submissions (one row per config × date).
* Uses benchmark_results with error/workflow filters to include full history. */
export async function getSubmissionSummary(sql: DbClient): Promise<SubmissionSummaryRow[]> {
const rows = await sql`
SELECT
Expand All @@ -37,34 +46,36 @@ export async function getSubmissionSummary(sql: DbClient): Promise<SubmissionSum
c.prefill_ep,
c.decode_tp,
c.decode_ep,
MIN(lb.date)::text AS first_date,
MAX(lb.date)::text AS latest_date,
COUNT(DISTINCT lb.date)::int AS run_days,
br.date::text,
COUNT(*)::int AS total_datapoints,
COUNT(DISTINCT (lb.isl, lb.osl))::int AS distinct_sequences,
COUNT(DISTINCT lb.conc)::int AS distinct_concurrencies,
MAX(lb.conc)::int AS max_concurrency,
(ARRAY_AGG(lb.image ORDER BY lb.date DESC) FILTER (WHERE lb.image IS NOT NULL))[1] AS image
FROM latest_benchmarks lb
JOIN configs c ON c.id = lb.config_id
GROUP BY c.model, c.hardware, c.framework, c.precision, c.spec_method, c.disagg, c.is_multinode, c.num_prefill_gpu, c.num_decode_gpu, c.prefill_tp, c.prefill_ep, c.decode_tp, c.decode_ep
ORDER BY MAX(lb.date) DESC, COUNT(*) DESC
COUNT(DISTINCT (br.isl, br.osl))::int AS distinct_sequences,
COUNT(DISTINCT br.conc)::int AS distinct_concurrencies,
MAX(br.conc)::int AS max_concurrency,
(ARRAY_AGG(br.image) FILTER (WHERE br.image IS NOT NULL))[1] AS image
FROM benchmark_results br
JOIN configs c ON c.id = br.config_id
JOIN latest_workflow_runs wr ON wr.id = br.workflow_run_id
WHERE br.error IS NULL
GROUP BY c.model, c.hardware, c.framework, c.precision, c.spec_method, c.disagg, c.is_multinode, c.num_prefill_gpu, c.num_decode_gpu, c.prefill_tp, c.prefill_ep, c.decode_tp, c.decode_ep, br.date
ORDER BY br.date DESC, COUNT(*) DESC
`;
return rows as unknown as SubmissionSummaryRow[];
}

/** Get daily datapoint counts by hardware for volume charts.
* Uses latest_benchmarks (deduplicated: newest per config+conc+isl+osl, no errors). */
* Uses benchmark_results with error/workflow filters to include full history. */
export async function getSubmissionVolume(sql: DbClient): Promise<SubmissionVolumeRow[]> {
const rows = await sql`
SELECT
lb.date::text,
br.date::text,
c.hardware,
COUNT(*)::int AS datapoints
FROM latest_benchmarks lb
JOIN configs c ON c.id = lb.config_id
GROUP BY lb.date, c.hardware
ORDER BY lb.date ASC
FROM benchmark_results br
JOIN configs c ON c.id = br.config_id
JOIN latest_workflow_runs wr ON wr.id = br.workflow_run_id
WHERE br.error IS NULL
GROUP BY br.date, c.hardware
ORDER BY br.date ASC
`;
return rows as unknown as SubmissionVolumeRow[];
}
Loading