Aggregate

Efficiently manage denormalized sums and counts in Convex databases without performance bottlenecks or data consistency issues.

Installation

npm install @convex-dev/aggregate

About Aggregate

This Convex component calculates count and sums of values for efficient aggregation.

Suppose you have a leaderboard of game scores. These are some operations that the Aggregate component makes easy and efficient:

Count the total number of scores: aggregate.count(ctx)
Count the number of scores greater than 65: aggregate.count(ctx, { bounds: { lower: { key: 65, inclusive: false } } })
Find the p95 score: aggregate.at(ctx, Math.floor(aggregate.count(ctx) * 0.95))
Find the overall average score: aggregate.sum(ctx) / aggregate.count(ctx)
Find the ranking for a score of 65 in the leaderboard: aggregate.indexOf(ctx, 65)
Find the average score for an individual user. You can define another aggregate grouped by user and aggregate within each:

Benefits

Use cases

how to track post like counts in Convex database

The @convex-dev/aggregate component lets you maintain denormalized like counts that update automatically when users like or unlike posts. Instead of counting likes on every page load, you store the aggregate count and update it efficiently when the underlying data changes.

maintain running totals in Convex without performance issues

Use @convex-dev/aggregate to keep running totals like order amounts, inventory counts, or user points without recalculating from scratch. The component handles the denormalization strategy and ensures your totals stay accurate as individual records change.

scalable vote counting system Convex

The aggregate component provides a scalable approach to vote counting by maintaining denormalized vote totals that update incrementally. This avoids the performance penalty of counting votes in real-time while ensuring vote totals remain consistent.

Frequently asked questions

How does the aggregate component handle data consistency?

The @convex-dev/aggregate component uses Convex's transactional guarantees to ensure aggregate values stay consistent with underlying data. When source records change, the component automatically updates the corresponding aggregate fields within the same transaction, preventing inconsistencies.

When should I use denormalized aggregates instead of real-time queries?

Use @convex-dev/aggregate when you need to display aggregate values frequently or when the underlying dataset is large enough that real-time aggregation impacts performance. It's particularly valuable for public-facing metrics like like counts, view counts, or summary statistics that many users access simultaneously.

Can I use this component for complex aggregations beyond sums and counts?

The @convex-dev/aggregate component focuses on sums and counts, which cover most denormalization use cases. For more complex aggregations like averages or percentiles, you would need to track multiple aggregate fields (like sum and count) and calculate the derived values in your application logic.

How does this handle high-frequency updates to aggregate values?

The @convex-dev/aggregate component is designed for scalable updates by avoiding expensive recalculation operations. It uses incremental updates that only modify the aggregate value by the delta, making it suitable for high-frequency scenarios like real-time voting or activity tracking.

Links