Skip to main content
All Docs
FeaturesBlockManOSUpdated March 26, 2026

Engineering: Capping Unbounded Sub-list Queries (PERF-15)

Engineering: Capping Unbounded Sub-list Queries (PERF-15)

Release: v1.0.84
Audit finding: PERF-15

Background

A performance audit identified 14 database sub-queries across the property, owner, maintenance, and compliance routers that returned unlimited rows. In a production environment serving multi-unit residential developments, certain data sets — ownership histories, service charge demands, compliance certificates, maintenance activity notes — grow continuously over the lifetime of a development. Returning every row on every request is unsustainable at scale.

This release applies targeted row limits to all affected queries and upgrades listBuildings to proper cursor pagination.

What Was Fixed

listBuildings — Cursor Pagination

Previously listBuildings returned all buildings for a development with no limit. It now uses the shared paginationInput / paginatedResult helpers, providing cursor-based pagination with a default page size of 20.

// Input now accepts cursor pagination params alongside developmentId
listBuildings.useQuery({ developmentId, limit: 20, cursor: undefined })

Callers that pass only { developmentId } continue to work — paginationInput defaults are applied automatically.

Detail-view Sub-lists — Hard Caps

Sub-lists embedded in detail-view responses (ownerships, demands, notes, certificates) are now capped. These views are intended for at-a-glance information; full paginated histories are available through dedicated list endpoints.

EndpointSub-listCap
property.getUnitOwnership history20
property.getOwnerOwned units20
property.getDevelopmentBuildings100
owner.getByIdOwnerships20
owner.getByIdService charge demands20
owner.getByIdPortal tokens10
owner.getPortalDataDemands20
owner.getPortalDataPayments20
owner.getPortalDataOwned units50
maintenance.getRequestActivity notes50
compliance.getObligationCertificates20
compliance.getObligationEvent history20

getUnitOwnershipHistory — Configurable Limit

This dedicated history endpoint previously returned all records. It now accepts a limit parameter (integer, 1–200, default 50).

// Fetch up to 100 ownership records for a unit
ownerRouter.getUnitOwnershipHistory.useQuery({ unitId, limit: 100 })

Callers that do not pass limit receive the first 50 records.

UI Guidance

Where a detail view previously displayed a complete unbounded list, consider adding a "View all" affordance that links to the appropriate paginated list endpoint:

  • Ownership history → owner.getUnitOwnershipHistory
  • Full owner list for a unit → property.listOwners / owner.getById
  • Buildings in a development → property.listBuildings (now paginated)

For maintenance.getRequest, if a request has accumulated more than 50 activity notes, surface a "View all notes" link; the cap is documented in the API comment.

No Breaking Changes

All existing callers are compatible with the new defaults:

  • Sub-list caps match or exceed the row counts typical of production data at the time of the audit.
  • listBuildings defaults apply transparently to callers that do not supply pagination parameters.
  • getUnitOwnershipHistory default of 50 matches prior typical result sizes.